Friday, 25 January 2013

Hibernate JPA sample project

Here's a simple example of a project that uses JPA with Hibernate as default implementation.

Let's start with the required dependencies:

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.1.9.Final</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.9.1.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
We're going to use the embedded Derby database.

We will also need the persistence.xml placed in META-INF directory on our classpath :

<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="test">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>pl.mjedynak.model.Person</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:derby:test;create=true"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
</persistence>
view raw persistence.xml hosted with ❤ by GitHub
We're setting Hibernate as our persistence provider and Derby as JDBC driver.
Entity class Person is also specified as belonging to this persistent unit.

It's defined as:

@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
private String name;
private Integer age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public int hashCode() {
return Objects.hash(id, name, age);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Person other = (Person) obj;
return Objects.equals(this.id, other.id) && Objects.equals(this.name, other.name) && Objects.equals(this.age, other.age);
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
view raw Person.java hosted with ❤ by GitHub

In order to manage Person we need some kind of DAO.  Let's define an interface PersonDao:

public interface PersonDao {
List<Person> findAll();
void addPerson(Person person);
}
view raw PersonDao.java hosted with ❤ by GitHub
For simplicity it has only methods for adding person and finding all persons.

The sample implementation could look like:

public class PersonDaoJpa implements PersonDao {
private EntityManager entityManager;
public PersonDaoJpa(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
public List<Person> findAll() {
List<Person> result = new ArrayList<>();
EntityTransaction transaction = entityManager.getTransaction();
try {
transaction.begin();
result = entityManager.createQuery("SELECT p FROM Person p").getResultList();
transaction.commit();
} catch (Exception e) {
transaction.rollback();
}
return result;
}
@Override
public void addPerson(Person person) {
EntityTransaction transaction = entityManager.getTransaction();
try {
transaction.begin();
entityManager.persist(person);
transaction.commit();
} catch (Exception e) {
transaction.rollback();
}
}
}

And the most important - integration test that checks if everything is glued together correctly:

public class PersonDaoJpaIntegrationTest {
private PersonDaoJpa personDaoJpa;
private EntityManagerFactory entityManagerFactory;
private EntityManager entityManager;
@Before
public void setUp() {
entityManagerFactory = Persistence.createEntityManagerFactory("test");
entityManager = entityManagerFactory.createEntityManager();
personDaoJpa = new PersonDaoJpa(entityManager);
}
@After
public void tearDown() {
entityManager.close();
entityManagerFactory.close();
}
@Test
public void shouldFindPreviouslySavedPerson() {
// given
Integer age = 22;
String name = "Charlie";
Person person = aPerson().
withAge(age).
withName(name).build();
personDaoJpa.addPerson(person);
// when
List<Person> result = personDaoJpa.findAll();
// then
assertThat(result, hasSize(1));
Person foundPerson = result.get(0);
assertThat(foundPerson.getAge(), is(age));
assertThat(foundPerson.getName(), is(name));
}
}

The whole project can be found at:  https://github.com/mjedynak/hibernate-jpa-example

To sum up:
it's quite easy to create JPA with Hibernate project, however every entity class needs it's own DAO (unless we use a generic one).
In the next post I'll take a look at Spring Data Jpa project that solves that impediment.