I am using OpenCMIS 1.1.0 to execute CRUD operations on an Alfresco Content Repository. Using the examples provided here I am able to execute all CRUD operations on both folders and documents.
Now I want to execute these operations (esp. create and update) asynchronously. Using this excellent SO post I can create documents asynchronously. However, OpenCMIS AsyncSession class does not provide an updateContentStream method.
Is there some way I can use OpenCMIS API to update document content asynchronously.
All operations that require a change token are not available in AsyncSession because the outcome would not be predicable if two operations on the same object would be scheduled.
But you can add your own Callable. Cast your AsyncSession object to AbstractExecutorServiceAsyncSession and call submit with your own Callable object. Here you can do whatever you want.
Such a Callable class could look like this:
public class SetContentStreamCallable extends SessionCallable<ObjectId> {
private Document doc;
private ContentStream contentStream;
private boolean overwrite;
public SetContentStreamCallable(Session session, Document doc, ContentStream contentStream, boolean overwrite) {
super(session);
this.doc = doc;
this.contentStream = contentStream;
this.overwrite = overwrite;
}
#Override
public ObjectId call() throws Exception {
return doc.setContentStream(contentStream, overwrite, false);
}
}
But keep in mind not to run two tasks on the same document!
Related
I have a requirement to persist huge payload to database. So I decided to use asynchronous call to persist a batch of records. I enabled Asynchronous processing by using #EnableAsync annotation. I also used #Async on a method on my service layer as below
#Async
#Transactional
public CompletableFuture<Boolean> insertRecords(List<Record> records) {
recordRepository.saveAll(records);
recordRepository.flush();
LOGGER.debug(Thread.currentThread().getName()+" -> inserting);
return CompletableFuture.completedFuture(Boolean.TRUE);
}
Above method is called from another service method
#Transactional
public void performSomeDB(InputStream is){
//perform another CRUD operation
processStream(is);
}
private void processStream(InputStream is){
//Read stream using JsonReader and load into a list
// record by record. Once the desired batch is met, pass the
// list to insertRecords
List<Record> records = new ArrayList<>();
List<CompletableFuture<Boolean>> statuses = new ArrayList<>();
while(stream has data){
records.add(record);
statuses.add(insertRecords(records);
}
System.out.println(statuses.size()); // It returns >1 based on the iterations.
Some of the code added above is more symbolic, than actual code.
When I looked into logs, I see that statuses.size() are returning value >1, which means more threads are spawned. But only one thread is used to persist and that is running in sequence for each iteration.
http-nio-9090-exec-10 -> insert records
http-nio-9090-exec-10 -> insert records.
......................................
In logs, I see only one thread is running and persisting a batch of records in sequential order.
Why only one thread is taking the load to persist all records.
Is my approach incorrect?
As for #Async annotation , self-invocation – calling the async method from within the same class – won’t work.
You should make the method in a separate class and reference it using the bean object of this class.
#Component
public class DbInserter {
#Async
#Transactional
public CompletableFuture<Boolean> insertRecords(List<Record> records) {
recordRepository.saveAll(records);
recordRepository.flush();
LOGGER.debug(Thread.currentThread().getName()+" -> inserting);
return CompletableFuture.completedFuture(Boolean.TRUE);
}
}
That's the magic and general idea of Async. It's sharing the full load without generating several threads.
If you are using Spring's Java-configuration, your config class needs to implements AsyncConfigurer:
#Configuration
#EnableAsync
public class AppConfig implements AsyncConfigurer {
#Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(50);
executor.setThreadNamePrefix("MyPool");
executor.initialize();
return executor;
}
}
You can refer below document for more details : http://docs.spring.io/spring/docs/3.1.x/javadoc-api/org/springframework/scheduling/annotation/EnableAsync.html
I have the following code which takes in a object of type employee based on it's model, I want to convert this to a DocumentDB Document then post to the database.
How would I do the conversion?
[HttpPost]
public async Task Post([FromBody]Employee employee)
{
using (_logger.BeginScope("Post employee"))
{
try
{
// convert employee to Document??
await _documentDbRepository.CreateItemsAsync(document);
}
catch (Exception e)
{
_logger.LogError(e.Message);
throw;
}
}
}
It seems that you're using a custom layer over top of the regular Cosmos libraries which is hard coded to only accept a Document. The libraries supplied by Microsoft are capable of inserting any generic object and will use default JSON serialization to turn it into a Document for you at insert time. Changing the signature on your custom repository to accept Object instead of Document should get you unblocked.
I was looking around but couldn't find anything specific for this one. So, I have an async repository, which used to look like:
public object get()
{
var db = new entity(); //i am using EF6
var listOfObjects = db.Object.ToList();
db.Dispose();
return listOfObjects;
}
but now that I'm using async I can't have the dispose there because it hits it before the previous call is being resolved. So my previous method now looks like:
public async Task<Object> GetAsync()
{
var db = new entity();
return await db.Object.ToListAsync();
}
So my question is, when or how should I dispose now?
As we talked about in our discussion and more detail can be foudn on this on the stack link below;
Entity Framework and Connection Pooling
Christopher Harrison also talks about this briefly in the Entity Framework MVA videos at the microsoft virtual academy.
Basically, Entity Framework will create a single entity per context. To quote the link,
Any subsequent query which requires entity with the same key returns
this stored instance. If values in the data store changed you still
receive the entity with values from the initial query. This is called
Identity map pattern. You can force the object context to reload the
entity but it will reload a single shared instance.
I'm new to Flex and BlazeDS and I'm trying to implement a simple application which uses Flex on the front end and a Spring/Hibernate application on the back end, with communication between the two going over a BlazeDS channel.
I'm seeking direction as to the best and/or simplest way to approach this. I have the UI set up in such a way that the user is presented with a file chooser in which they pick the image file they want to upload. When this is chosen and submitted (as a form submission) then the server side should receive the image file data as well as some related metadata such as a description and date, then populate a Hibernate entity/POJO with the image file data and related metadata, and then persist the entity/POJO into the database.
I have found some examples of how you would do a file upload and download using servlets here and the FileReference class (here and here) but these don't appear to address the problem in a way which leverages BlazeDS and/or Spring/Hibernate. I want to put the image file data and related metadata (description, capture date, etc.) into a value object within the Flex application and then send this over BlazeDS to a service provided by my Spring/Hibernate application running on Tomcat. In this service I want to extract the image data (both the actual JPG/PNG/GIF data and the related metadata such as description, etc.) from the value object sent from the Flex app into an entity/POJO which is then persisted via Hibernate in my database.
Can this be done, and if so what's the best way to go about it? Am I mistaken in assuming that if I use BlazeDS then I am somehow bypassing the need to provide HTTP-based services such as servlets on the server side and instead I can use my Java services as "RemoteObjects"? Is there necessarily a one-to-one mapping between Java POJO/entity class and the Flex value object class when making this sort of transfer? If so is there a tool which creates corresponding Flex value objects from Java POJOs or vice versa.
Thanks in advance for your help, comments, suggestions, etc.
--James
Update: Some code to make this more clear:
I have this as my value object in Flex:
package valueobjects
{
import flash.utils.ByteArray;
[Bindable]
[RemoteClass(alias="com.abc.example.persistence.entity.Image")]
public class Image
{
public var id:Number;
public var captureDate:Date;
public var description:String;
public var imageData:ByteArray;
public function Image() {}
}
I am assuming that this can be used as a one-to-one mapping to the POJO class used by my service and DAO classes on the server-side, which looks like this:
package com.abc.example.persistence.entity;
import java.sql.Blob;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
#Entity(name = "IMAGE")
public class Image
extends AbstractBaseEntity<Long>
{
private String description;
private Date captureDate;
private Blob imageData;
#Column(name = "CAPTURE_DATE", nullable = true)
public Date getCaptureDate()
{
return captureDate;
}
#Column(name = "DESCRIPTION", nullable = true)
public String getDescription()
{
return description;
}
#Column(name = "IMAGE_DATA", nullable = true)
public Blob getImageData()
{
return imageData;
}
public void setCaptureDate(final Date captureDate)
{
this.captureDate = captureDate;
}
public void setDescription(final String description)
{
this.description = description;
}
public void setImageData(final Blob imageData)
{
this.imageData = imageData;
}
}
In my Flex application I populate the fields of an Image object with a description string, date, and image file data (based on the user's file selection and text input for the description) and then call a method on the RemoteObject which is mapped to the service running on Tomcat. I make the RemoteObject service call within my Flex code using the Image value object as the argument, but the service method running on the servier side actually expects an argument of the POJO/entity type, and it's here that I am thinking that some sort of conversion/transformation between the Flex value object and the Java POJO will occur (by virtue of the RemoteClass alias setting on the value object's class declaration), but it doesn't seem to be happening that way because when I debug the application the Java service is only getting null values when the service call is made.
In my Flex application I have a FileReference and Image value object as public, bindable variables:
[Bindable]
public var imageToBeArchivedFileReference:FileReference = new FileReference();
[Bindable]
public var imageToBeArchivedValueObject:valueobjects.Image = new valueobjects.Image();
There is also an event handler to browse for a file when the user clicks on a file select button:
protected function imageFileSelectButton_clickHandler(event:MouseEvent):void
{
var imageFileFilter:FileFilter = new FileFilter("Images (*.jpg, *.jpeg, *.gif, *.png)", "*.jpg;*.jpeg;*.gif;*.png");
var fileTypes:Array = new Array();
fileTypes.push(imageFileFilter);
imageToBeArchivedFileReference.addEventListener(Event.SELECT, imageToBeArchived_fileSelectHandler);
imageToBeArchivedFileReference.browse(fileTypes);
}
There is an event handler which builds the value object when the image file has been selected:
private function imageToBeArchived_fileSelectHandler(event:Event):void
{
imageToBeArchivedFileReference.load();
imageToBeArchivedValueObject = new valueobjects.Image()
imageToBeArchivedValueObject.imageData = imageToBeArchivedFileReference.data;
imageToBeArchivedValueObject.description = imageToBeArchivedDescription.text;
imageToBeArchivedValueObject.captureDate = imageToBeArchivedFileReference.creationDate;
}
and there's an event handler which is invoked when the user clicks on the submit button to perform the image save/upload:
protected function archiveImageButton_clickHandler(event:MouseEvent):void
{
imageArchivalService.archiveImage(imageToBeArchived);
}
On the server side my Java class is doing a simple save of the POJO:
public void archiveImage(final Image image)
{
imageDao.saveOrUpdate(image);
}
When I set a breakpoint in the method above and look at the image variable it looks to be empty, so I'm assuming that the transformation from the Flex value object to the Java POJO did not go as expected and that there's more to it than just adding a RemoteClass alias in the Flex value object class.
Check out this example, it is all there.
http://biemond.blogspot.com/2008/08/flex-upload-and-download-with-blazeds.html
Don't use the loader class, use the readBytes call.
Make sure you go to the comments, there are valuable info there.
Cheers
I'm trying to work out how to complete my implementation of the Repository pattern in an ASP.NET web application.
At the moment, I have a repository interface per domain class defining methods for e.g. loading and saving instances of that class.
Each repository interface is implemented by a class which does the NHibernate stuff. Castle Windsor sorts out the DI of the class into the interface according to web.config. An example of an implemented class is provided below:
public class StoredWillRepository : IStoredWillRepository
{
public StoredWill Load(int id)
{
StoredWill storedWill;
using (ISession session = NHibernateSessionFactory.OpenSession())
{
storedWill = session.Load<StoredWill>(id);
NHibernateUtil.Initialize(storedWill);
}
return storedWill;
}
public void Save(StoredWill storedWill)
{
using (ISession session = NHibernateSessionFactory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
session.SaveOrUpdate(storedWill);
transaction.Commit();
}
}
}
}
As pointed out in a previous thread, the repository class needs to accept an unit of work container (i.e. ISession) rather than instantiating it in every method.
I anticipate that the unit of work container will be created by each aspx page when needed (for example, in a property).
How do I then specify that this unit of work container instance is to be passed into the constructor of StoredWillRepository when Windsor is creating it for me?
Or is this pattern completely wrong?
Thanks again for your advice.
David
I have a persistence framework built on top of NHibernate that is used in a few Web apps. It hides the NH implementation behind an IRepository and IRepository<T> interface, with the concrete instances provided by Unity (thus I could in theory swap out NHibernate for, say, Entity Framework fairly easily).
Since Unity doesn't (or at least the version I'm using doesn't) support the passing in of constructor parameters other than those that are dependency injections themselves, passing in an extant NH ISession isn't possible; but I do want all objects in the UOW to share the same ISession.
I solve this by having a controlling repository class that manages access to the ISession on a per-thread basis:
public static ISession Session
{
get
{
lock (_lockObject)
{
// if a cached session exists, we'll use it
if (PersistenceFrameworkContext.Current.Items.ContainsKey(SESSION_KEY))
{
return (ISession)PersistenceFrameworkContext.Current.Items[NHibernateRepository.SESSION_KEY];
}
else
{
// must create a new session - note we're not caching the new session here... that's the job of
// BeginUnitOfWork().
return _factory.OpenSession(new NHibernateInterceptor());
}
}
}
}
In this example, PersistenceFrameworkContext.Current.Items accesses an IList<object> that is stored either ThreadStatic if not in a Web context, or within HttpContext.Current.Items if it is in a Web context (to avoid thread-pool problems). The first call to the property instantiates the ISession from the stored factory instance, subsequent calls just retrieve it from storage. The locking will slow things down slightly but not as much as just locking an appdomain-scoped static ISession instance.
I then have BeginUnitOfWork and EndUnitOfWork methods to take care of the UOW - I have specifically disallowed nested UOWs because frankly they were a pain to manage.
public void BeginUnitOfWork()
{
lock (_lockObject)
{
if (PersistenceFrameworkContext.Current.Items.ContainsKey(SESSION_KEY))
EndUnitOfWork();
ISession session = Session;
PersistenceFrameworkContext.Current.Items.Add(SESSION_KEY, session);
}
}
public void EndUnitOfWork()
{
lock (_lockObject)
{
if (PersistenceFrameworkContext.Current.Items.ContainsKey(SESSION_KEY))
{
ISession session = (ISession)PersistenceFrameworkContext.Current.Items[SESSION_KEY];
PersistenceFrameworkContext.Current.Items.Remove(SESSION_KEY);
session.Flush();
session.Dispose();
}
}
}
Finally, a pair of methods provide access to the domain-type-specific repositories:
public IRepository<T> For<T>()
where T : PersistentObject<T>
{
return Container.Resolve<IRepository<T>>();
}
public TRepository For<T, TRepository>()
where T : PersistentObject<T>
where TRepository : IRepository<T>
{
return Container.Resolve<TRepository>();
}
(Here, PersistentObject<T> is a base class providing ID and Equals support.)
Access to a given repository is thus in the pattern
NHibernateRepository.For<MyDomainType>().Save();
This is then facaded over such that you can use
MyDomainType.Repository.Save();
Where a given type has a specialised repository (ie needs more than it can get from IRepository<T>) then I create an interface deriving from IRepository<T>, an extending implementation inheriting from my IRepository<T> implementation, and in the domain type itself I override the static Repository property using new
new public static IUserRepository Repository
{
get
{
return MyApplication.Repository.For<User, IUserRepository>();
}
}
(MyApplication [which is called something less noddy in the real product] is a facade class which takes care of supplying the Repository instance via Unity so you have no dependency on the specific NHibernate repository implementation within your domain classes.)
This gives me full pluggability via Unity for the repository implementation, easy access to the repository in code without jumping through hoops, and transparent, per-thread ISession management.
There's lots more code than just what's above (and I've simplified the example code a great deal), but you get the general idea.
MyApplication.Repository.BeginUnitOfWork();
User user = User.Repository.FindByEmail("wibble#wobble.com");
user.FirstName = "Joe"; // change something
user.LastName = "Bloggs";
// you *can* call User.Repository.Save(user), but you don't need to, because...
MyApplication.Repository.EndUnitOfWork();
// ...causes session flush which saves the changes automatically
In my Web app, I have session-per-request, so BeginUnitOfWork and EndUnitOfWork get called in BeginRequest and EndRequest respectively.
I have a pretty similar structure to yours, and here's how I solve your question:
1) To specify my container on each method, I have a separate class ("SessionManager") which I then invoke via a static property. By doing so, here's an example using my Save implementation:
private static ISession NHibernateSession
{
get { return SessionManager.Instance.GetSession(); }
}
public T Save(T entity)
{
using (var transaction = NHibernateSession.BeginTransaction())
{
ValidateEntityValues(entity);
NHibernateSession.Save(entity);
transaction.Commit();
}
return entity;
}
2) My container is not created on each ASPX page. I instantiate all of my NHibernate goodness on the global.asax page.
** A few more things spring up **
3) You don't need to have a helper to instantiate the Load. You might as well use Get instead of Load. More information # Difference between Load and Get.
4) Using your current code, you would have to repeat pretty much the same code for each domain object you need (StoredWillRepository, PersonRepository, CategoryRepository, etc..?), which seems like a drag. You could very well use a generic class to operate over NHibernate, like:
public class Dao<T> : IDao<T>
{
public T SaveOrUpdate(T entity)
{
using (var transaction = NHibernateSession.BeginTransaction())
{
NHibernateSession.SaveOrUpdate(entity);
transaction.Commit();
}
return entity;
}
}
In my implementation, I could then use something like:
Service<StoredWill>.Instance.SaveOrUpdate(will);
Technically, the answer to my question is to use the overload of container.Resolve which allows you to specify the constructor argument as an anonymous type:
IUnitOfWork unitOfWork = [Code to get unit of work];
_storedWillRepository = container.Resolve<IStoredWillRepository>(new { unitOfWork = unitOfWork });
But let's face it, the answers provided by everyone else have been much more informative.