This is a tutorial to set up JPA with
Hibernate, using Maven 2. There are probably
other/better tutorials out there, but I couldn't find one that explained everything that I needed to
know, all in one place. This may be due to lack of Googling skills. Nevertheless, I'm writing this
in case others find it useful. There isn't anything particularly difficult here, but I'm probably
going to need to refer back to this, so I may as well post it.
You can download the source code for this example here.
First, I'm assuming that you have Maven 2 installed. I'm using Maven 2.0.9
at the time of this writing.
Next, create a directory for your project. When you're done, you'll have a directory and file
structure as follows:
+- pom.xml
+- src
| +- main
| | +- java
| | | +- example
| | | | +- Person.java
| | +- resources
| | | +- META-INF
| | | | +- persistence.xml
| +- test
| | +- java
| | | +- example
| | | | +- BasicPersistenceTest.java
Now, create a pom.xml file inside your project directory, similar to this one:
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>your.groupid</groupId>
<artifactId>yourArtifactId</artifactId>
<packaging>jar</packaging> <!-- or war, or ... -->
<name>your-project</name>
<version>1.0-SNAPSHOT</version>
<description>Sample project</description>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.6.ga</version>
<exclusions>
<exclusion>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.4.0.GA</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.5</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Basically it's JPA, Hibernate without JTA, and the Hibernate EntityManager. Now, that last needs
SLF4J, but make sure to use the matching version. To do that, run
mvn dependency:tree
In my example, I see, among other things:
[INFO] +- org.hibernate:hibernate-entitymanager:jar:3.4.0.GA:compile
[INFO] | +- org.hibernate:ejb3-persistence:jar:1.0.2.GA:compile
[INFO] | +- org.hibernate:hibernate-commons-annotations:jar:3.1.0.GA:compile
[INFO] | +- org.hibernate:hibernate-annotations:jar:3.4.0.GA:compile
[INFO] | +- org.hibernate:hibernate-core:jar:3.3.0.SP1:compile
[INFO] | +- org.slf4j:slf4j-api:jar:1.4.2:compile
That last line reveals SLF4J version 1.4.2. So, even though a newer version is available, it is
recommended to use the matching version, and that's what we have in the above pom.xml file.
Finally, I'm using C3P0 for DataSource
connection pooling, HSQLDB as a database, and JUnit to
run a simple test that confirms everything is set up properly.
If you want to use log4j, you'll want this in pom.xml instead
of slf4j-simple:
slf4j_log4j.xml
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.4.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
Of course, you can use another database instead of HSQLDB. For example,
MySQL:
mysql.xml
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
Now, create the persistence.xml file (see above for directory structure):
persistence.xml
<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_1_0.xsd"
version="1.0">
<persistence-unit name="yourunitname" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:yourdb"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.c3p0.min_size" value="5"/>
<property name="hibernate.c3p0.max_size" value="20"/>
<property name="hibernate.c3p0.timeout" value="300"/>
<property name="hibernate.c3p0.max_statements" value="50"/>
<property name="hibernate.c3p0.idle_test_period" value="3000"/>
</properties>
</persistence-unit>
</persistence>
The important thing here is the name= attribute of the persistence-unit tag; replace
yourunitname by what you want to use. Also, you'll need to adapt the connection settings to your
database, URL, username, and password. Finally, you can change the C3P0 settings, or change the
configuration if you're using an altogether different DataSource provider.
Next, let's try a simple entity class:
Person.java
package example;
import java.io.Serializable;
import javax.persistence.*;
@Entity
public class Person implements Serializable {
private Integer personId;
private String firstName;
private String lastName;
@Id
@GeneratedValue
public Integer getPersonId() {
return personId;
}
public void setPersonId(Integer personId) {
this.personId = personId;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Besides having the @Entity annotation, you don't have to do anything else for this class to be
discovered as being an entity class.
We're now ready to make sure everything works:
BasicPersistenceTest.java
package example;
import org.junit.Assert;
import org.junit.Test;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class BasicPersistenceTest {
@Test
public void testBasicPersistence() throws Exception {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("yourunitname");
EntityManager manager = factory.createEntityManager();
String firstName = "Freddy";
String lastName = "Daoud";
Person person = new Person();
person.setFirstName(firstName);
person.setLastName(lastName);
manager.getTransaction().begin();
manager.persist(person);
manager.getTransaction().commit();
Person result = (Person) manager
.createQuery("SELECT p FROM Person p WHERE p.firstName = :firstName")
.setParameter("firstName", firstName)
.getSingleResult();
Assert.assertEquals(firstName, result.getFirstName());
Assert.assertEquals(lastName, result.getLastName());
manager.close();
factory.close();
}
}
Run mvn test.
If the test passes, you're on your way!
You can download the source code for this example here.