Pages

Wednesday, June 19, 2013

JPA basics tutorial

JPA (Java Persistence API) is an API that allows to store Java objects in the database.
There are several implementations of this interface and one of the most popular uses Hibernate.

Let's create a simple application and look at how JPA works.

This post is available in Russian.

We will use next technologies:
  • Hibernate 4.2.2
  • MySQL 5.6.12
  • Maven 3.0.5

Create jpa_basics_tutorial database and artist table with id, name and genre columns.
This table will store information about music artists:
CREATE DATABASE jpa_basics_tutorial;
USE jpa_basics_tutorial;

CREATE TABLE artist (
id INT PRIMARY KEY,
name VARCHAR(30),
genre VARCHAR(20)
);

Add needed dependencies into pom.xml file:
<?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>jpa_basics_tutorial</groupId>
    <artifactId>jpa_basics_tutorial</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.2.2.Final</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.25</version>
        </dependency>
    </dependencies>
    
</project>

Create Artist class with id, name and genre properties.
Class that could be used by JPA is called an entity.
We should add @Entity annotation to turn Artist class into an entity.
Entities of Artist type will be stored in the table of the same name. e.g. artist.
Entity properties values will be stored in the columns of the same name.
Entity should have a persistence identity, or an identifier. It is a key that uniquely identifies an entity instance and distinguishes it from all other instances of the same entity type. Identifier has @Id annotation. id property can be used as an identifier in Artist class, because it corresponds to the primary key column in artist table:
package package com.jpa.basics.tutorial.domain;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Artist {

    @Id
    private int id;

    private String name;
    private String genre;

    public Artist() {

    }

    public Artist(int id, String name, String genre) {
        this.id = id;
        this.name = name;
        this.genre = genre;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGenre() {
        return genre;
    }

    public void setGenre(String genre) {
        this.genre = genre;
    }

    @Override
    public String toString() {
        return "Artist{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", genre='" + genre + '\'' +
                '}';
    }
}

Create ArtistService class that has:
  • em property of EntityManager type. EntityManager implements API for working with entities. persist() method stores a new entity, find() performs entity search, remove() deletes entity and createQuery() allows to execute JPQL-queries. You don't have to invoke special EntityManager method to update entity property, just change its value (e.g. with setGenre() method)
  • CRUD methods (Create, Read, Update, Delete) that use EntityManager to create, read, update and delete entities
package com.jpa.basics.tutorial.service;

import com.jpa.basics.tutorial.domain.Artist;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.util.List;

public class ArtistService {
    
    private EntityManager em;

    public ArtistService(EntityManager em) {
        this.em = em;
    }

    public Artist createArtist(int id, String name, String genre) {
        Artist artist = new Artist(id, name, genre);
        em.persist(artist);

        return artist;
    }

    public void removeArtist(int id) {
        Artist artist = em.find(Artist.class, id);

        if (artist != null) {
            em.remove(artist);
        }
    }

    public Artist changeArtistGenre(int id, String genre) {
        Artist artist = em.find(Artist.class, id);

        if (artist != null) {
            artist.setGenre(genre);
        }

        return artist;
    }

    public Artist findArtist(int id) {
        return em.find(Artist.class, id);
    }

    public List<Artist> findAllArtists() {
        TypedQuery<Artist> query = em.createQuery("SELECT a FROM Artist a", Artist.class);
        return query.getResultList();
    }
}

EntityManager is obtained from EntityManagerFactory object.
EntityManagerFactory settings (e.g. for database connection) and classes that are used by EntityManager are set in corresponding persistence unit. Persistence unit name is used when EntityManagerFactory object is created.
Persistence unit is described in persistence.xml file, which must be located in resources/META-INF directory.
Create that file:
<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="JpaBasicsTutorial" transaction-type="RESOURCE_LOCAL">
        <class>com.jpa.basics.tutorial.domain.Artist</class>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" 
                      value="jdbc:mysql://localhost:3306/jpa_basics_tutorial"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="root"/>           
        </properties>
    </persistence-unit>

</persistence>

Create JpaBasicsTutorial class to check that application works.
EntityManagerFactory, EntityManager and ArtistService objects are created and after that CRUD methods are invoked in main() method.
Methods that are used to create, update and delete entities must be invoked in transactions to store these changes in the database. begin() and commit() methods of EntityTransaction object are used to open and close transactions:
package com.jpa.basics.tutorial;

import com.jpa.basics.tutorial.domain.Artist;
import com.jpa.basics.tutorial.service.ArtistService;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import java.util.List;

public class JpaBasicsTutorial {

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("JpaBasicsTutorial");
        EntityManager em = emf.createEntityManager();
        ArtistService service = new ArtistService(em);

        System.out.println("--- Create and persist artist ---");
        EntityTransaction transaction = em.getTransaction();
        transaction.begin();
        Artist artist = service.createArtist(1, "Franz Ferdinand", "Rock");
        transaction.commit();
        System.out.println(String.format("Persisted: %s\n", artist));

        System.out.println("--- Find artist ---");
        artist = service.findArtist(1);
        System.out.println(String.format("Found: %s\n", artist));

        System.out.println("--- Find all artists ---");
        List<Artist> artists = service.findAllArtists();
        for (Artist foundArtist : artists) {
            System.out.println(String.format("Found: %s\n", foundArtist));
        }

        System.out.println("--- Update artist ---");
        transaction.begin();
        artist = service.changeArtistGenre(1, "Indie Rock");
        transaction.commit();
        System.out.println(String.format("Updated: %s\n", artist));

        System.out.println("--- Remove artist ---");
        transaction.begin();
        service.removeArtist(1);
        transaction.commit();
        artist = service.findArtist(1);
        System.out.println(String.format("Found: %s\n", artist));
    }
}

Execute main() method:

















All CRUD methods were executed correctly, which means we have successfully used JPA during application development.

Folder structure:




Application source code is available at https://code.google.com/p/jpa-basics-tutorial/.

Recommended posts:

10 comments:

  1. Thanks for the tutorial.
    Very simple but all a begineer needs.

    ReplyDelete
  2. Thanks for the tutorial.
    Alex, which provider is being used here? since we do not have any thing specified in the persistence.xml?

    ReplyDelete
    Replies
    1. Thanks. you meant this "org.hibernate.ejb.HibernatePersistence" and is this the default one?

      Delete
    2. Yes for both questions! But if you are going to use newer version of Hibernate (4.3+) then your provider should be org.hibernate.jpa.HibernatePersistenceProvider

      Delete