问题
In my project, I forgot to close the entity manager for each operation. After some time, I got exception due to excessive connections to mysql server. Does this mean that each entity manager establish the connection? What will happen when we forget to close the connection? I have used only one entity manager factory.
回答1:
Assuming that you are using an application-managed entity manager, then you are responsible for initializing and closing the entity manager. One the other hand, if you are relying on the container to inject the entity manager into your session beans (or any managed classes), then the container is responsible for ensuring that the entity manager is closed.
Usually, the entity manager is not responsible for creating connections to the database. It would instead use a connection pool, that is defined in persistence.xml
. This is true of both JTA entity managers and resource-local entity managers; JTA entity managers rely on a JTA datasource provided by the application server environment, while resource-local entity managers create and manage their own pools.
If you do not close entity managers, and if you continue to create new instances of them, then it is possible for you to exhaust connections in the JTA datasource (for JTA entity managers) or hit a server-defined limit on client connections (for both JTA and resource-local entity managers). Each database instance would be configured to accept no more than a certain number of connections. If the number of connections established by all clients, exceeds this limit, the server will simply drop addition connections. If you open entity manager instances that request for additional connections from a pool (for JTA entity managers), or create new pools (for resource-local entity managers), then it is very much likely that the pool itself might be exhausted, or too many connections would have been opened.
Since you cannot close the connections directly, or even resize the connection pools from your application, it is quite obvious that you must close entity manager instances when you no longer need them; this will automatically release the connections that were established for the entity manager.
Also, it would be wise to look at using a well-tuned and adequately sized connection pool for every entity manager instance, in case you are using resource-local entity managers for a reason. If you are using a JTA entity manager, consider using container-injected entity managers and a JTA datasource that is backed by a well-tuned and adequately sized connection pool.
回答2:
In any case - if you explicitely open EntityManager (get it from EMFactory), then you should close it. Whether it takes connection (which seems to be your case) or not depends on settings that is rather JPA provider related. On our project, EM opens connection for every query and returns it back immediately (closes). But there are other options - keep the connection, or connection that follows transaction lifecycle.
As an example, here are settings for OpenJPA. I'd say that if EM opened the connection for query/transaction, than you wouldn't hit the problem. It seems that your EM takes the connection and holds it.
In any case, you should close the EM if you created it. Best practice is to do it in the same method if possible, so it's easy to review the correctness, and to do so in finally block.
来源:https://stackoverflow.com/questions/6815277/does-an-entity-manager-create-a-connection-to-the-database