Hibernate with JPA Annotations and Guice
In this tutorial, I use the H2 database, which you can utilize by downloading the jar or you can replace with your own DB.
First off, you need to create a persistence.xml in a folder named META-INF at the root of your classpath. For example, if you’re using Maven you can create src/main/java/META-INF/persistence.xml. It lists all the classes you want Hibernate to persist and any other Hibernate properties you might want to specify. I also define Hibernate properties later on in the tutorial when creating the EntityManagerFactory.
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="db-manager">
<class>com.benmccann.db.ExamplePersistedClass</class>
<properties>
<!-- Disable the second-level cache -->
<property name="hibernate.cache.provider_class" value="org.hibernate.cache.NoCacheProvider"/>
<!-- Default is false for backwards compatibility. Should be used on all new projects -->
<property name="hibernate.id.new_generator_mappings" value="true"/>
</properties>
</persistence-unit>
</persistence>
We listed the class com.benmccann.db.ExamplePersistedClass as being the only persisted class, so now we’ll go ahead and create it. Note that you need a no-argument constructor. Fields in your bean will be persisted unless annotated with @Transient. More info about persisted classes is available in the Hibernate documentation.
package com.benmccann.db;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class ExamplePersistedClass {
@Id
@GeneratedValue
private Long id;
private String otherField;
public ExamplePersistedClass() {}
public void setId(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public void setOtherField(String otherField) {
this.otherField = otherField;
}
public String getOtherField() {
return otherField;
}
}
And we’ll create a DAO for it:
package com.benmccann.db;
import javax.persistence.EntityManager;
public class ExamplePersistedClassDao {
protected EntityManager entityManager;
@Inject
public ExamplePersistedClassDao(EntityManager entityManager) {
this.entityManager = entityManager;
}
public void saveInNewTransaction(ExamplePersistedClass object) {
entityManager.getTransaction().begin();
save(object);
entityManager.getTransaction().commit();
}
public void save(ExamplePersistedClass object) {
entityManager.persist(object);
}
public ExamplePersistedClass getByOtherField(String otherField) {
return (ExamplePersistedClass) entityManager
.createQuery("select e from ExamplePersistedClass e where e.otherField=:otherField")
.setParameter("otherField", otherField)
.getSingleResult();
}
}
And finally, we’ll create a Guice module to define the injection. Note that EntityManagerFactory is thread-safe while EntityManager is not. I use ThreadLocal storage here in order to have one entity manager per thread. When creating the EntityManagerFactory notice that I use the same “db-manager” string that is defined in the persistence.xml file. Also, I defined most of my Hibernate properties here rather than in the persistence.xml file to demonstrate how you can alter the values of these properties. For example, when writing tests it could be very helpful to override the connection string to point to a local test database.
package com.benmccann.db;
import java.util.HashMap;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Singleton;
/**
* @author Ben McCann (benmccann.com)
*/
public class DbModule extends AbstractModule {
private static final ThreadLocal<EntityManager> ENTITY_MANAGER_CACHE
= new ThreadLocal<EntityManager>();
public void configure() {
}
@Provides @Singleton
public EntityManagerFactory provideEntityManagerFactory() {
Map<String, String> properties = new HashMap<String, String>();
properties.put("hibernate.connection.driver_class", "org.h2.Driver");
properties.put("hibernate.connection.url", "jdbc:h2:test");
properties.put("hibernate.connection.username", "sa");
properties.put("hibernate.connection.password", "");
properties.put("hibernate.connection.pool_size", "1");
properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
properties.put("hibernate.hbm2ddl.auto", "create");
return Persistence.createEntityManagerFactory("db-manager", properties);
}
@Provides
public EntityManager provideEntityManager(EntityManagerFactory entityManagerFactory) {
EntityManager entityManager = ENTITY_MANAGER_CACHE.get();
if (entityManager == null) {
ENTITY_MANAGER_CACHE.set(entityManager = entityManagerFactory.createEntityManager());
}
return entityManager;
}
}
Now we can run our code:
package com.benmccann.db;
import java.sql.SQLException;
import java.util.Date;
import org.junit.Assert;
import org.junit.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.benmccann.db.DbModule;
import com.benmccann.db.ExamplePersistedClass;
import com.benmccann.db.ExamplePersistedClassDao;
public class H2DBTest {
@Test
public void testDb() throws SQLException {
Injector injector = Guice.createInjector(new DbModule());
ExamplePersistedClassDao examplePersistedClassDao = injector.getInstance(ExamplePersistedClassDao.class);
ExamplePersistedClass example = new ExamplePersistedClass();
example.setOtherField("hello world");
examplePersistedClassDao .saveInNewTransaction(quote);
ExamplePersistedClass retrieved = examplePersistedClassDao.getByOtherField("hello world");
Assert.assertEquals(example.getId(), retrieved.getId());
Assert.assertEquals(example.getOtherField(), retrieved.getOtherField());
}
}
Tags: Guice, Hibernate, JPA, Persistence, Tutorial
steven said,
September 28, 2010 at 8:03 pm
thanks, this was useful for me
Lenik said,
January 29, 2011 at 9:25 pm
This is the best quickstart for JPA i’ve ever seen, which get rids of spring framework.
Lenik said,
January 29, 2011 at 9:41 pm
I hereby add the missing dependencies, it maybe not easy to find them out for Maven users,
javax.persistence
persistence-api
1.0
com.google.inject
guice
3.0-rc2
com.h2database
h2
1.3.149
org.hibernate
hibernate-core
3.3.2.GA
Steven H. said,
February 14, 2011 at 4:17 pm
I’m getting
Error in custom provider, javax.persistence.PersistenceException: No Persistence provider for EntityManager named db-manager
When trying this in intellij Community Edition and using Maven (and the dependencies mentioned by Lenik
I assume its not finding my persistence.xml, but I’m at a loss as to where to put it. (The location you suggest doesn’t seem to work.
Steven H. said,
February 14, 2011 at 5:16 pm
Turns out you need further dependancies
org.hibernate
hibernate-entitymanager
3.3.2.GA
org.slf4j
slf4j-simple
1.6.1
John said,
July 14, 2011 at 5:02 pm
Also a runtime dependency on
javax.transaction:jta:1.1
if you use Java SE
John said,
July 15, 2011 at 1:07 am
This is an excellent summary.
However, you could omit the section of the persistence.xml, in my experience.
Rajesh said,
September 6, 2011 at 5:45 am
Hi All,
I was also getting “No Persistence provider for EntityManager named db-manager” whilst running test.
Please make sure that you have copied persistance.xml in “src/test/resources/META-INF/”.
Cheers,
Rajesh
Christophe said,
December 22, 2011 at 3:17 am
Nice article, thanks a lot.
It is all I need.
But the code is hard to read, please use a syntax highlighting plugin !