The project I'm working on is deployed under Tomcat and isn't using EJBs. The codebase is using JDBC for database access and I'm looking into using some O/R mapping. Hibernate is great, but Java Persistence is more desirable, as it's more of a standard. Getting it to work with EJB3 is dead simple. Getting it to work without EJB was a bit more problematic. The entire application is being deployed as a WAR file. As such, the JPA configuration artifacts weren't getting picked up. Setting aside how absolutely horrendous Java Enterprise configuration is, here's what ended up working for me:
  • Create a persistence.xml file as per standard documentation leaving out the jta-data-source stanza (I could not figure out how to get Hibernate/JPA to find my configured data source)
  • Create your hibernate.cfg.xml, being sure to include JDBC conncetion info. This will result in hibernate managing connections for you, which is fine
  • Create a persistence jar containing:
    • Hibernate config at root
    • persistence.xml in META-INF
    • All classes with JPA annotations in root (obviously in their java package/directory structure)
  • This goes into WEB-INF/lib of the war file (being careful to omit the JPA-annotated classes from WEB-INF/classes
The first two steps took a while to get to and aren't super clear from the documentation. To use JPA, this (non-production quality) code works:
EntityManagerFactory emf = 
    Persistence.createEntityManagerFactory("name used in persistence.xml");
EntityManager em = emf.createEntityManager(); 

Query query = em.createQuery("from Account where name = :name");
query.setParameter("name",itsAccountName);
List results = query.getResultList();

// do stuff with your results

em.close();
emf.close();
The EntityManagerFactory is supposed to survive the life of application and not be created/destroyed on every request. I also believe there might be some transaction issues with this, but I can't figure out from the documentation what they are and if they are a big deal for a single-database application. Update: Turns out, it's not quite this simple. Since this configuration is running outside an EJB container, and given Bug $2382, you can query all day long, but you cannot persist. To solve this, you must work in a transaction, as so:
EntityManagerFactory emf = 
    Persistence.createEntityManagerFactory("name used in persistence.xml");
EntityManager em = emf.createEntityManager(); 
EntityTransaction tx = em.getTransaction();

tx.begin();
Query query = em.createQuery("from Account where name = :name");
query.setParameter("name",itsAccountName);
List results = query.getResultList();

// modify your results somehow via persist() 
// or merge()

tx.commit();
em.close();
emf.close();
Again, this is not production code as no error handling has been done at all, but you get the point.