Where to put createEntityManagerFactory() ?

Hello,

Since Apache Tomcat does not support @EJB or @PersistenceContext injection, the recommended way to do access the JPA EntityManager and EntityManagerFactory is via direct calls as follows :

EntityManagerFactory emf = javax.persistence.Persistence.createEntityManagerFactory("MyPersistenceUnit");

I put this call in my Application.init() method and store/cache the reference for later use, and this works as expected. The problem is that the “Application” in Vaadin is actually a “Session” in J2EE , so if i understood this correctly, this means that the above code is run once per user session instead of once per application startup.

Which brought us to the main question as per subject line: where/when do I call the JPA method ? Or am i doing it wrong? :slight_smile:

Thank you very much in advance,
regards,
ts.

Not that I could say anything how this
should
be with JPA and this may be too obvious, but if you add a singleton pattern instead of calling it on app.init() it will be instantiated once per JVM. Everything is shared between all application instances then.

I don’t think you can really do it wrong in this case. As Sami points out, you can create a singleton for it in your application class (I assume as a static variable in the class). Since the factory is thread safe, it’s fine to share it this way. If you did it once per session instead, I don’t think you’re causing much overhead. But it’s a non-zero amount of time, so you might as well avoid it.

(In some basic testing of mine with Tomcat 6 on Mac OS, I see separate objects for each call to createEntityManagerFactory rather than some cached value like Loggers.)

Anyway, sharing it among instances is fine. I think it’s a little cleaner to not create it in the Vaadin Application class however. You could write a simple Servlet that extends Vaadin’s AbstractApplicationServlet, create the entity manager factory there, and pass it into a custom constructor on your Application object. Something like this:


public class MyServlet extends AbstractApplicationServlet {

    EntityManagerFactory emf = //...

    @Override
    protected Class<? extends Application> getApplicationClass() {
        return MyVaadinApp.class;
    }

    @Override
    protected Application getNewApplication(HttpServletRequest request) throws ServletException {
        return new MyVaadinApp(service);
    }
}

It’s a little more work, but if you ever move to another container you could inject all kinds of resources in the servlet to pass into the Vaadin application class. I have some full EE examples where I do this to pass an EJB reference into my application. Just make sure you’re only doing it with thread-safe classes!

Cheers,
Bobby

This is one of those moments where the answer is obvious once it’s pointed out to you. Thank you!