views:

50

answers:

2

Can we cache reference to EntityManager.

As for our requirement, instead of injecting EntityManger into other EJBs, we are having utility class which will return the reference to entitymanager. The issue is each time we need to get reference, we are doing JNDI lookup.

in order to avoid JNDI lookup, we want to cache the reference to entity manager in hashmap etc..

It seems to be working but few doubts I have are: 1. If we cache the entityManager, then will it hold the connection as long as the reference is active? 2. Will there be any change in the transaction management?

Thank you in advance.

+1  A: 

EntityManagers are not threadsafe, so at a minimum you'd need to be caching them thread local or in a map by thread identifier or something.

Question 1) That is specific to your underlying provider, but in most cases, yes, open EntityManager means you are holding a database connection.

Question 2) Possibly, but you didn't say what strategy you're currently using for transaction management.

Another big problem is that if you're using the EM properly according to spec, you need to dispose it and get a new one whenever an exception comes out of it. This means you need to be properly managing that cache wherever an exception could come out of it.

It sounds like maybe you're trying to use JPA as just a JDBC wrapper. Getting an new EM for each individual SQL statement then disposing of it. You haven't given any information about the architecture of the system, perhaps a middle ground like the Open EntityManager in View pattern would alleviate your problem without trying to invent a new wheel?

Affe
A: 

As for our requirement, instead of injecting EntityManger into other EJBs, we are having utility class which will return the reference to entitymanager.

There are probably very good reasons but what are the constraints exactly, why can't you use injection? Anyway, is the lookup identified as being a problem? Did you measure something? How much time does the lookup represent compared to the total processing time? Is it non negligible?

In order to avoid JNDI lookup, we want to cache the reference to entity manager in hashmap etc...

To be honest, that fact that you are asking questions here is a strong hint that you shouldn't go this way. What about transaction management? What about exceptions handling (you're supposed to discard the EM after an exception)? What about memory management?

If we cache the entityManager, then will it hold the connection as long as the reference is active?

Resources (as long as they have been acquired) won't be released, so yes. From the Hibernate EM documentation:

5.1. Entity manager and transaction scopes

A EntityManagerFactory is an expensive-to-create, threadsafe object intended to be shared by all application threads. It is created once, usually on application startup.

An EntityManager is an inexpensive, non-threadsafe object that should be used once, for a single business process, a single unit of work, and then discarded. An EntityManager will not obtain a JDBC Connection (or a Datasource) unless it is needed, so you may safely open and close an EntityManager even if you are not sure that data access will be needed to serve a particular request*. (This becomes important as soon as you are implementing some of the following patterns using request interception.)

...

And later:

5.2.1. Non-managed environment

...

A call to close() marks the end of an EntityManager. The main implication of close() is the release of resources - make sure you always close and never outside of guaranteed finally block.

There is no magic. If the EM needs to interact with the database, it will acquire a connection. And this connection won't be released if you don't close the EntityManager. Check the source code of the underlying Hibernate Session if you want.

Will there be any change in the transaction management?

Well, you didn't say anything about what you're currently using (a container-managed entity manager? an application-managed entity manager?) and you didn't explain how transactions are managed (JTA entity manager? resource-local entity manager?). Anyway, the answer is... probably.

Maybe you should explain how things are currently working (before starting to cache entity managers).

And I would personally measure things, I'm not convinced there is a problem. Unless you prove there is a problem, what you're trying to do is not worth the troubles.

Pascal Thivent
Thanks Pascal.we are using CMPI am using jboss, i saw the DataSource connection pool MBeans. Even after getting entity manager the connection pool count (available connections shows 20 - which is the actual count available) that means EM is not holding connection.We need to use separate entity manager because the connection to db is identified at runtime.I read it on ibm.com that lookup takes time.I got an idea from this http://www.ibm.com/developerworks/java/library/j-ejb0924.htmland trying to fine tune my application.Thank you :)
Vineyard
@Vineyard The connection in the EM is lazy loaded. But once acquired, it won't be released until you close it (check the code, there is no magic). And you should not base your choices on something you *read* in an dusty article from 2002 about EJB 2.x. As I said, *measure* things. But if you insist, good luck :)
Pascal Thivent