26

Ok, I read bunch of articles/examples how to write Entity Manager Factory in singleton.

One of them easiest for me to understand a bit:

http://javanotepad.blogspot.com/2007/05/jpa-entitymanagerfactory-in-web.html

I learned that EntityManagerFactory (EMF) should only be created once preferably in application scope.

And also make sure to close the EMF once it's used (?)

So I wrote EMF helper class for business methods to use:

public class EmProvider {

    private static final String DB_PU = "KogaAlphaPU";

    public static final boolean DEBUG = true;

    private static final EmProvider singleton = new EmProvider();

    private EntityManagerFactory emf;

    private EmProvider() {}

    public static EmProvider getInstance() {
        return singleton;
    }


    public EntityManagerFactory getEntityManagerFactory() {
        if(emf == null) {
            emf = Persistence.createEntityManagerFactory(DB_PU);
        }
        if(DEBUG) {
            System.out.println("factory created on: " + new Date());
        }
        return emf;
    }

    public void closeEmf() {
        if(emf.isOpen() || emf != null) {
            emf.close();
        }
        emf = null;
        if(DEBUG) {
            System.out.println("EMF closed at: " + new Date());
        }
    }

}//end class

And my method using EmProvider:

public String foo() {
    EntityManager em = null;
    List<Object[]> out = null;
    try {

        em = EmProvider.getInstance().getEntityManagerFactory().createEntityManager();
        Query query = em.createNativeQuery(JPQL_JOIN); //just some random query 
        out = query.getResultList();
    }
    catch(Exception e) {
        //handle error....
    }
    finally {
        if(em != null) {
             em.close(); //make sure to close EntityManager
        }
        //should I not close the EMF itself here?????
        EmProvider.getInstance().closeEmf();
    }

I made sure to close EntityManager (em) within method level as suggested. But when should EntityManagerFactory be closed then? And why EMF has to be singleton so bad??? I read about concurrency issues but as I am not experienced multi-thread-grammer, I can't really be clear on this idea.

Meow
  • 16,125
  • 50
  • 122
  • 176
  • 1
    "And why EMF has to be singleton so bad???" this statement i should probably open another question.... – Meow Dec 28 '10 at 05:48

1 Answers1

61
  • EntityManagerFactory instances are heavyweight objects. Each factory might maintain a metadata cache, object state cache, EntityManager pool, connection pool, and more. If your application no longer needs an EntityManagerFactory, you should close it to free these resources.

  • When an EntityManagerFactory closes, all EntityManagers from that factory, and by extension all entities managed by those EntityManagers, become invalid.

  • It is much better to keep a factory open for a long period of time than to repeatedly create and close new factories. Thus, most applications will never close the factory, or only close it when the application is exiting.

  • Only applications that require multiple factories with different configurations have an obvious reason to create and close multiple EntityManagerFactory instances.

  • 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.

  • More than one entity manager factory instance may be available simultaneously in the JVM. Methods of the EntityManagerFactory interface are threadsafe.
Nayan Wadekar
  • 10,772
  • 4
  • 41
  • 69
  • 3
    I think 'EntityManagerFactory' should not be closed for an online web application. – abbas Oct 09 '13 at 18:19
  • 1
    It should be closed but only when the web application stops (user stops it or undeploys it). Example: Implementing contextDestroyed method from ServletContextListener interface when using JSF – GabrielBB Mar 03 '14 at 15:26
  • 1
    @pvm14 Yes, definitely. If have to go by your way & if its there everything in the documentation & everybody understands, stackoverlow wouldn't have came into the picture. People haven't voted unnecessarily. If you don't like, leave it, refrain from posting irrelevant comments, instead try adding more information, details, mistakes etc. if you can, which would help everyone. – Nayan Wadekar Mar 29 '14 at 18:16
  • the only problem I have with the answer is that, in my admittedly limited experience, it's actually required to open/close the EMF -- at least from clients, otherwise the client will just hang without even logging an error. Perhaps the performance is different when JPA runs from the server. – Thufir Sep 25 '14 at 02:57
  • @Thufir Already mentioned EntityManagerFactory instance is a heavyweight object & should be created only once at the application initialization & closed when undelpoyed/terminated. If there are numerous clients, opening/closing factory instance is not preferable. – Nayan Wadekar Sep 25 '14 at 09:42