Maven and JPA tutorial

This tutorial shows how to create a JPA project using a Maven archetype and how to modify it in order to use Hibernate 4 JPA Provider and MySQL.

 

Maven and JPA tutorial

By using the mvn archetype:generate command you are able to generate a quickstart project from an archetype. Lots of archetypes are available on public repositories and in the next tutorial we will show also how to publish your own archetype.

 

The simplest way to use the Maven Archetype plugin to generate a new Maven project from an archetype is to run the archetype:generate goal in interactive mode.

$ mvn archetype:generate 

------------------------------------------------------------------------

[INFO] Building Maven Default Project

[INFO]task-segment: [archetype:generate] (aggregator-style)

[INFO] [archetype:generate]

[INFO] Generating project in Interactive mode [INFO] No archetype defined. Using maven-archetype-quickstart Choose archetype: 1: internal - appfuse-basic-jsf
. . . . . . .

However, once that you have identified one archetype and you are going to use it often in your projects, you can create it in no interactive mode. Here’s for example how to create a project which uses the standalone-jpa-eclipselink-archetype (A JPA standalone project which uses Eclipselink JPA provider)
 

mvn archetype:generate -DarchetypeGroupId=com.github.lalyos -DarchetypeArtifactId=standalone-jpa-eclipselink-archetype -DgroupId=com.mastertheboss -DartifactId=EclipseJPAExample -Dversion=1.0-SNAPSHOT -Dpackage=com.mastertheboss -DinteractiveMode=false

This will generate a sample JPA project in the folder EclipseJPAExample. The project as it is, can be imported into Eclipse using the command:

mvn eclipse:eclipse

maven jpa hibernate tutorial maven jpa hibernate tutorial
The project is composed of two domain classes (Employee and Department) and a Test class:
hibernate jpa maven tutorial hibernate jpa maven tutorial
Here’s the Department class:

package com.mastertheboss.domain;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;

@Entity
public class Department {

    @Id
    @GeneratedValue
    private Long id;
    private String name;
    
    @OneToMany(mappedBy="department",cascade=CascadeType.PERSIST)
    private List<Employee> employees = new ArrayList<Employee>();
    
    public Department() {
        super();
    }
    public Department(String name) {
        this.name = name;
    }
    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 List<Employee> getEmployees() {
        return employees;
    }
    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }
}

This is the Employee class:

package com.mastertheboss.domain;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;

@Entity
public class Employee {
    @Id
    @GeneratedValue
    private Long id;

    private String name;
    
    @ManyToOne
    private Department department;

    public Employee() {}

    public Employee(String name, Department department) {
        this.name = name;
        this.department = department;
    }
    

    public Employee(String name) {
        this.name = name;
    }

    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 Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + ", department="
                + department.getName() + "]";
    }

}

The project by default uses the EclipseLink JPA provider and the Apache Derby embedded database, as stated in the persistence.xml file:

<?xml version="1.0" encoding="UTF-8" ?>
<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" xmlns="http://java.sun.com/xml/ns/persistence">
    <persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
        <!-- shouldn't be valid for java SE per specification, but it works for EclipseLink ... -->
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
        
            <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:derby:simpleDb;create=true" />
            <property name="javax.persistence.jdbc.user" value="EclipseJPAExample" />
            <property name="javax.persistence.jdbc.password" value="EclipseJPAExample" />

            <!-- EclipseLink should create the database schema automatically -->
            <property name="eclipselink.ddl-generation" value="create-tables" />
            <property name="eclipselink.ddl-generation.output-mode" value="database" />
            <property name="eclipselink.logging.level" value="SEVERE"/>                
        </properties>

    </persistence-unit>
</persistence>

The Test class is named JpaTest, basically insert some sample data in the Employee and Department tables and later on retrieves this data using the listEmployees method.

package com.mastertheboss.jpa;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import com.mastertheboss.domain.Employee;
import com.mastertheboss.domain.Department;

public class JpaTest {

    private EntityManager manager;

    public JpaTest(EntityManager manager) {
        this.manager = manager;
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("persistenceUnit");
        EntityManager manager = factory.createEntityManager();
        JpaTest test = new JpaTest(manager);

        EntityTransaction tx = manager.getTransaction();
        tx.begin();
        try {
            test.createEmployees();
        } catch (Exception e) {
            e.printStackTrace();
        }
        tx.commit();

        test.listEmployees();

        System.out.println(".. done");
    }

    private void createEmployees() {
        int numOfEmployees = manager.createQuery("Select a From Employee a", Employee.class).getResultList().size();
        if (numOfEmployees == 0) {
            Department department = new Department("java");
            manager.persist(department);

            manager.persist(new Employee("Jakab Gipsz",department));
            manager.persist(new Employee("Captain Nemo",department));

        }
    }

    private void listEmployees() {
        List<Employee> resultList = manager.createQuery("Select a From Employee a", Employee.class).getResultList();
        System.out.println("num of employess:" + resultList.size());
        for (Employee next : resultList) {
            System.out.println("next employee: " + next);
        }
    }


}

You can compile/test this class using the following command:

mvn compile exec:java -Dexec.mainClass=com.mastertheboss.jpa.JpaTest
. . . . . . . . . . . . . . . . . . . 
num of employes:2
next employee: Employee [id=3, name=Captain Nemo, department=java]
next employee: Employee [id=2, name=Jakab Gipsz, department=java]
.. done
[INFO] ------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------
[INFO] Total time: 10.497s
[INFO] Finished at: Sun Sep 30 21:56:12 CEST 2012
[INFO] Final Memory: 15M/38M
[INFO] ------------------------------------------------------------

We will now change the default project so that it uses MySQL database (instead of Apache Derby) and Hibernate JPA Provider (instead of EclipseLink). In order to do that, we need to trigger some dependencies into Maven pom.xml file. Here’s the list of dependencies we will use:

http://mvnrepository.com/artifact/mysql/mysql-connector-java

http://mvnrepository.com/artifact/org.hibernate.javax.persistence/hibernate-jpa-2.0-api

http://mvnrepository.com/artifact/org.hibernate/hibernate-entitymanager

Now edit your pom.xml file so that it looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mastertheboss</groupId>
    <artifactId>Hibernate4Example</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.21</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.0-api</artifactId>
            <version>1.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.0.1.Final</version>
        </dependency>
    </dependencies>
</project>

Next thing we need to change is persistence.xml file, which is located into the resources/META-INF folder of your Maven project. (We have set up to use a JDBC URL named “jdbc:mysql://localhost:3306/mysqlDB”)

<?xml version="1.0" encoding="UTF-8" ?>
<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" xmlns="http://java.sun.com/xml/ns/persistence">
    <persistence-unit name="persistenceUnit"
        transaction-type="RESOURCE_LOCAL">

        <class>com.mastertheboss.domain.Employee</class>
        <class>com.mastertheboss.domain.Department</class>
        <properties>

            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/mysqlDB" />
            <property name="javax.persistence.jdbc.user" value="user" />
            <property name="javax.persistence.jdbc.password" value="passwd" />
            <property name="hbm2ddl.auto" value="create" />

            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
        </properties>

    </persistence-unit>
</persistence>

That’s all. Verify that the Test class works using again the following command:

mvn compile exec:java -Dexec.mainClass=com.mastertheboss.jpa.JpaTest

In the next Maven tutorial, we will show how to create your own archetype and publish it on a public repository so that it can be used by the Community of developers.

Found the article helpful? if so please follow us on Socials