Injection EntityManager Vs. EntityManagerFactory

Long question, please carry me.

We use Spring + JPA for web application. My team is discussing EntityManagerFactory injection in GenericDAO (Generics-based DAO has something in the strings provided by APPFUSE, for some reason we are not using JpaDaosupport ) for EntityManager injection. We use "managed management."

The argument against injecting a EntityManagerFactory that it is too heavy and therefore not required; EntityManager does what we need. In addition, since Spring will create a new DAO instance for each web request (I doubt it), there will be no concurrency problems, since there is a common thread in one EntityManager instance in two ways.

The argument for injecting EFM is that its good practice throughout it is always good to have a handle to the factory.

I'm not sure which is the best approach, can someone please enlighten me?

+63
java spring jpa entitymanager
Aug 21 '09 at 4:28
source share
4 answers

The advantages and disadvantages of an EntityManagerFactory vs EntityManager injection are described in Spring docs here , I'm not sure if I can improve this.

Having said that there are some points in your question that need to be clarified.

... Spring will create a new DAO instance for each web request ...

This is not true. If your DAO is a Spring bean, then it is single, unless you configure it differently using the scope attribute in the bean definition. Creating a DAO instance for each request will be insane.

The argument for EMF injection is that its good practice over all its always good to have a handle for the factory.

This argument does not really contain water. The generally accepted practice suggests that minimal collaborators should be introduced to the object, by which it must carry out its work.

+49
Aug 21 '09 at 7:10
source share

I suppress what I finally put together. From the " Deploying DAO Based on a Simple JPA " section of the Spring reference:

Although EntityManagerFactory instances are thread safe, there are no instances of EntityManager. The JPA entered by EntityManager behaves like an EntityManager extracted from the application JNDI server environment as defined by the JPA specification. It delegates all calls to the current transactional EntityManager, if any; otherwise, it backs out for the newly created EntityManager per operation, effectively creating thread-safe usage.

This means that, according to JPA specifications, EntityManager instances are not thread safe, but if Spring processes them, they become thread safe.

If you are using Spring, it is best to add an EntityManager instead of an EntityManagerFactory.

+22
Aug 21 '09 at 11:39
source share

I think this has already been well lit, but only in order to reinforce a few points.

  • DAO, if Spring is entered , is singleton by default . You must explicitly specify the scope of the prototype to create a new instance each time.

  • The entity organizer introduced by @PersistenceContext is thread safe .

However, I had some problems with the single point DAO in my multi-threaded application. I turned the DAO into an instanced bean and this solved the problem. So, although the documentation may say one thing, you probably want to test your application thoroughly.

Follow-up:

I think part of my problem is to use

 @PersistenceContext(unitName = "unit", type = PersistenceContextType.EXTENDED) 

If you are using PersistenceContextType.EXTENDED, keep in mind that you must, if I understand correctly, manually close the transaction. See this for more details.

Another observation:

Using an instanced DAO is a very bad idea. Each DAO instance will have its own persistent memory cache, and changes in one cache will not be recognized by other DAO beans. Sorry for the bad advice.

+9
Aug 21 '09 at 11:43
source share

I found that setting @Repository Spring annotation on our DAOs and having EntityManager running Spring and introduced by @PersistenceContext annotation is the most convenient way to make everything work freely. You get the security benefits of shared EntityManager threads and exception throwing. By default, a generic EntityManager will manage transactions if you combine multiple DAOs from the dispatcher. As a result, you will find that your DAOs become anemic.

+6
Aug 21 '09 at 6:44
source share



All Articles