Injecting EntityManager Vs. EntityManagerFactory - java

A long question, please bear with me.
We are using Spring+JPA for a web application. My team is debating over injecting EntityManagerFactory in the GenericDAO (a DAO based on Generics something on the lines provided by APPFUSE, we do not use JpaDaosupport for some reason) over injecting an EntityManager. We are using "application managed persistence".
The arguments against injecting a EntityManagerFactory is that its too heavy and so is not required, the EntityManager does what we need. Also, as Spring would create a new instance of a DAO for every web request(I doubt this) there are not going to be any concurrency issues as in the same EntityManager instance is shared by two threads.
The argument for injecting EFM is that its a good practice over all its always good to have a handle to a factory.
I am not sure which is the best approach, can someone please enlighten me?

The pros and cons of injecting EntityManagerFactory vs EntityManager are all spelled out in the Spring docs here, I'm not sure if I can improve on that.
Saying that, there are some points in your question that should be cleared up.
...Spring would create a new instance of
a DAO for every web request...
This is not correct. If your DAO is a Spring bean, then it's a singleton, unless you configure it otherwise via the scope attribute in the bean definition. Instantiating a DAO for every request would be crazy.
The argument for injecting EMF is that
its a good practice over all its
always good to have a handle to a
factory.
This argument doesn't really hold water. General good practice says that an object should be injected with the minimum collaborators it needs to do its job.

I am putting down what I have finally gathered. From the section "Implementing DAOs based on plain JPA" in the Spring Reference:
Although EntityManagerFactory instances are thread-safe, EntityManager
instances are not. The injected JPA EntityManager behaves like an
EntityManager fetched from an application server's JNDI environment,
as defined by the JPA specification. It delegates all calls to the
current transactional EntityManager, if any; otherwise, it falls back
to a newly created EntityManager per operation, in effect making its
usage thread-safe.
This means as per JPA specifications EntityManager instances are not thread safe, but if Spring handles them, they are made thread safe.
If you are using Spring, it is better to inject EntityManagers instead of EntityManagerFactory.

I think this has already been well covered, but just to reinforce a few points.
The DAO, if injected by Spring, is a
singleton by default. You have to
explicitly set the scope to prototype
to create a new instance every time.
The entity manger injected by
#PersistenceContext is thread safe.
That being said, I did have some issues on with a singleton DAO in my multi-threaded application. I ended up making the DAO a instanced bean and that solved the problem. So while the documentation may say one thing, you probably want to test your application thoroughly.
Follow-up:
I think part of my problem is I am using
#PersistenceContext(unitName = "unit",
type = PersistenceContextType.EXTENDED)
If you use PersistenceContextType.EXTENDED, keep in mind you have to, if I understand correctly, manually close the transaction. See this thread for more information.
Another Follow-up:
Using an instanced DAO is an extremely bad idea. Each instance of the DAO will have its own persistence cache and changes to one cache will not be recognized by other DAO beans. Sorry for the bad advice.

I found that setting the #Repository Spring annotation on our DAOs and having EntityManager managed by Spring and injected by #PersistenceContext annotation is the most convenient way to get everything working fluently. You benefit from the thread safety of the shared EntityManager and exception translation. By default, the shared EntityManager will manage transactions if you combine several DAOs from a manager for instance. In the end you'll find that your DAOs will become anemic.

Related

Combining MDB, JPA and JTA

I'm developing a system to process messages and update the database accordingly, but I need to keep some degree of isolation between layers. I have in mind something like the following.
MyDao.java: a #Stateless bean that provides database access. MyDao accesses the database using JPA, with an EntityManager injected by #PersistenceContext.
MyMdb.java: an MDB that listens on a queue. MyMdb uses MyDao by injection with #EJB.
One single execution of MyMdb.onMessage() needs to perform several accesses to the database, both read and write.
On the one hand, this makes me think that a #Stateless bean is not the right choice for MyDao: the EntityManager instance in MyDao could be randomly accessed by different executions of MyMdb.onMessage(), leading threads to interfere with each other.
On the other hand, JPA documentation says that the injected EntityManager is just a proxy: the actual persistence context on which it operates is the one bound to the JTA transaction. This way everything should be ok because, even though EntityManagers are "shared", each MDB will have a different transaction ongoing and thus work in safe isolation.
What is the right scenario? Am I missing something?
Entity managers injected in a stateless EJB in the way that you described are exactly what you should do.
This type of injection provides a 'Container-Managed Entity Manager' which is 'transaction scoped'.
So in the scenario that you describe.
the onMessage MDB call will create a transaction
the call to the stateless bean will happen to the same transaction context, creating an Entity Manager which will live until the transaction finishes usually when the MDB method returns.
The specific type of injected entity manager for the same EJB instance doesn't survive and is not re-used across different transactions.

Understanding Spring and "No EntityManager with actual transaction available"

I have a Spring Boot application with Hibernate, with a bunch of DAOs annotated with #Repository and Spring's #Transactional. Everything works fine. Then I decide to move common methods (persist, find, merge) to an AbstractDao. Writing operations (persist, merge) start throwing that No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call exception. I try adding #Transactional to AbstractDao, and contrary to my expectations, it fixes it.
Why is that so? I thought that since, unlike CGLIB, Spring uses interfaces instead of extending classes, it wouldn't work, and I would need to define an interface to declare instead of my DAOs. But I also guess that I'm mixing concepts of how Spring deals with dependency management and with transactions.
Can somebody provide an explanation of why does it work? Is there a better way of dealing with this problem?

JTA & MySQL - How to Retrieve records from database

I am new to JTA and I need a method to retrieve some some elements from the database. I can do this through EntityManager but that works only for ResourceLocal.
I want to know how can I do this:
Query q = em.createNamedQuery("AnyQuery");
q.getResultList();
without the use of EntityManager.
Any ideas?
The question itself shows that you don't understand any of the technologies you try to work with. You probably need to study some more general stuff before you do any actual development.
you are probably confusing JTA and JPA,
your statement about RESOURCE_LOCAL is not true (and irrelevant) - there are JTA and RESOURCE_LOCAL transactions and in Java EE you usually use the former,
your thought of using Named JPA queries without EntityManager is plain absurd and probably stems from misunderstanding of some kind (what would be the point of using named queries without an entity manager?),
saying "some elements from database" shows that you can't really tell the difference between records and mapped objects, in which case you probably should not use JPA at all.
I am not really expecting that you accept this answer. That's just my frustration taking over.
EDIT
OK, now that you mentioned JSF I understand more of your problem.
I assume you want to use JPA. In such case you have a choice of:
creating your own EntityManager (in such case you cannot have it injected; instead you have yo use an EntityManagerFactory and build your own). This is an "application managed EntityManager". You don't really want to do this.
using an injected EntityManaged ("conatiner managed EntityManager"). This is the standard choice.
Now you need a transaction. Since you should be using a JTA EntityManager, you will need a transaction object that is responsible for coordinating the whole thing. Again, you have two choices:
in a JSF bean, inject a UserTransaction (using #Resource annotation). This is messy, error-prone and takes a lot of boilerplate, but you will find all the necessary methods. You can create your own (application managed) EntityManager, call its joinTransaction method and then call begin-commit on UserTransaction. This is would be an "application managed transaction"
move your EntityManager code to EJB. It only takes a couple of lines of code and a single annotation (#Statless). All the code inside an EJB is - magically - wrapped inside a transaction that the container manages for you. This is the "container managed transaction" - the default and common choice.
Each of the things above could (and should) be expanded with some additional information. But the short path for you is:
create an EJB (a simple class with #Stateless annotation),
move the method that uses EntityManager to the EJB,
inject the EJB into your managed bean (using #EJB annotation) and call the relevant method.
The JTA transaction will happen around each call to any EJB method. This should get you started :-)

How many EntityManagers are injected for a given PersistenceContext?

I am injecting EntityManager objects in stateless EJB3 beans (which act as DAO objects and each provide access to a different database table). Deployment is in JBoss AS 7.
I then added code using System.identityHashCode in the EJB3 beans methods to see the various instances of the EntityManagers injecting (hoping to see the same instance in all DAOs). E.g. like:
#Stateless
public class AFacade {
#PersistenceContext(unitName="foo")
EntityManager em;
public List<A> findAll() {
l.info("entity manager is: "+System.identityHashCode(em)+" class is: "+em.getClass().getSimpleName());
...
}
However, what I noticed is that each DAO (e.g. AFacade, BFacade and so on) was injected with a different EntityManager (as reported by identityHashCode) although the PersistenceContext was the same. The implementing class was TransactionScopedEntityManager in all cases.
It is not clear to me why this different EntityManager objects are injected, whether this is something that should concern me or not. Also, I understand that the EJB3 container may actually inject proxies to the real EntityManager so these different instances may actually be proxies to a single EntityManager.
Yes, they are proxies (in fact, I think they are thread safe decorators, rather than proxies) on the real entity managers.
I'm not sure if you know that the EntityManager is a wrapper around a connection. If you wouldn't have this decorator (or proxy), all invocations to that stateless bean would share the same connection (and potentially transaction), which is not what you want.
The injected EntityManagers are proxy generated by the EJB Containers.
For Transaction scoped Entity Managers, each transaction uses a single separate instance of Provider's Entity Manager.
When a method call is made to this proxy , container checks javax.transaction.TransactionSynchronizationRegistry ( this is implemented by EJB Container) to see if there is a provider EntityManager already created for this transaction. If not, it will create the provider Entity Manager and register it in TransactionSynchronizationRegistry and then delegate the method call to it. If already present, it will simply retrieve the provider Entity Manager an delegate the method call to it.
Transaction scoped EntityManagers are stateless according to the book "Pro JPA2 Mastering the Java Persistence API" by Mike Keith and Merrick Schincariol (See Chapter 6).
The proxy objects inserted in each EJB instance object is different, though a single proxy object could have been used because of the stateless nature of Transaction scoped Entity Manager.
Also take a look at : http://piotrnowicki.com/2011/11/am-i-in-the-same-transaction-am-i-using-the-same-persistencecontext/

EntityManager initialization best practices

When using EntityManager, is it better to get one instance with PersistenceContext and pass it around in my program, or should I use dependency injection more than once?
In my application each client will communicate with a stateful session bean, and each bean needs to use EntityManager at some point.
I guess that bean methods are invocated concurrently (but I'm not even sure).
How do I guarantee that I use EntityManager in a thread-safe manner? With transactions? With a separate instance in each bean?
Sorry if this is confusing, I'm new to EJB/JPA and I couldn't find any material which addresses my questions.
Yes, you should inject the EntityManager instances (which will be different for each thread/client request) into your stateful session beans (which are not invoked concurrently, at least not from different clients).
There is no point in creating DAO classes, though. JPA already is a high-level persistence API that gives you RDBMS independence and portability between different JPA implementations. So, DAOs would only add clutter to the codebase.
For transactions, you don't really need to do anything. Business methods in session beans have a "Required" transaction attribute by default, so they will always run inside a client-specific transaction.
Use #PersistenceContext to inject your EntityManager in your DAO class(es). These are the classes that will handle the database operations. Then in all other (service) classes inject your DAO class(es). Your DAO should be a stateless bean (no need of a remote interface, only local)

Categories