Having seen numerous examples of how to use a JNDI DataSource from a Java Servlet, I've yet to find a sample of how to use JNDI in conjunction with JPA in a Servlet context.
The basic outline of my scenario is:
- a Java Servlet
- an external project containing JPA entities and a persistence.xml
- I'd like to use JPA in a ServLet
Lots of googeling have resulted in the following scheme.
In the web.xml I've registered a ServletContextListener
together with a database definition:
<web-app>
...blah blah blah...
<listener>
<listener-class>my.company.MyContextListener</listener-class>
</listener>
... blah blah blah
<resource-ref>
<res-ref-name>jdbc/MyDB</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
...blah blah blah...
</web-app>
Where the details for the resource-ref jdbc/MyDB is properly defined in a context.xml.
The MyContextListener
just instantiates a globally accessible EntityBroker
:
public class MyContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent event) {
Map<String, String> props = new HashMap<String, String>();
props.put(PersistenceUnitProperties.JTA_DATASOURCE, "java:/comp/env/jdbc/MyDB");
EntityManagerFactory factory = Persistence.createEntityManagerFactory("my-jpa", props);
event.getServletContext().setAttribute("RatingController", new EntityBroker(factory));
}
}
Where an EntityBroker
is an invention of mine. Basically it's just a wrapper for an EntityManagerFactory
allowing clients to get an EntityManager
:
public class EntityBroker {
private final EntityManagerFactory factory;
public EntityBroker(EntityManagerFactory factory) {
this.factory = factory;
}
public EntityManager getManager() {
return factory.createEntityManager();
}
}
In this way I think I'm able to accommodate all future needs for client database access using JPA, but being a newbie to Servlet's I'd like to be more certain.
Is this scheme of mine totally bizarre or have I overcomplicated matters in any way?