Question

Say that I have this code in a @Stateless Enterprise JavaBean:

@PersistenceUnit
EntityManagerFactory emf;

Will the Java EE container automatically close my EntityManagerFactory sooner or later?

What the specs say

The Java Persistence specification, version 2.1 says the following on page 338:

When the application has finished using the entity manager factory, and/or at application shutdown, the application should close the entity manager factory.

Okay, so that is pretty straight forward. I have to close the factory.

However, since I injected the factory in the first place, I'm a bit nervous calling the close() method all by myself. What if the container is no smarter than trying to reuse a closed factory in the next bean that wants a factory? Also, I don't like to add a lot of plumbing to hook my own logic into what happens or not at application shutdown. Moreover, it just smells bad that I didn't open/create the factory, yet my code is responsible for closing it. Surely the massive pile of Java EE specifications has something more to tell me about this issue?

Well.. no. The examples I've seen in the JPA 2.1 and EJB 3.2 specification that inject a factory do not close it explicitly. The examples do close it only if they explicitly create a factory by means of Persistence.createEntityManagerFactory() (see JPA 2.1 specification, pages 345 and 355).

The only talk about the container's responsibility that I've seen comes from the JPA 2.1 specification page 356:

[..] the container is required to support third-party persistence providers, and in this case the container must use the PersistenceProvider.createContainerEntityManagerFactory method to create the entity manager factory and the EntityManagerFactory.close method to destroy the entity manager factory prior to shutdown (if it has not been previously closed by the application).

Here it says that the container do have the responsibility to close the factory. But what makes me hardly believe in this last quote is that the example/quote clearly talked about a very particular use case when the container uses a "third-party persistence provider".

For me, the topic becomes even more confusing if I read the chapter on Persistence Unit References in the EJB 3.2 specification that begins on page 286. In here, there is not a word on who bears the responsibility of closing the entity manager factory - me or the container.

My conclusion is that I should, or rather must be, safe by copying the examples used in the specifications. Meaning that I don't have to close the factory explicitly. What is mainly confusing to me though is the first quote I used from the JPA specification that clearly says I have to close the factory!

What is your opinion? Have I missed anything?

Was it helpful?

Solution

Since the EntityManagerFactory is created by your container, it is responsible for its lifecycle (and thus closing it). There is only one EMF, so closing it would make no sense except on the end of your applications lifecycle. From the JPA 2.1 spec section 9.1:

[...]

The EntityManagerFactory instance obtained as a result will be used by the container to create container-managed entity managers. Only one EntityManagerFactory is permitted to be created for each deployed persistence unit configuration. Any number of EntityManager instances may be created from a given factory.

You are, however, responsible for closing your EntityManager if you decide to manage it by yourself via the injected EMF.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top