We’ll be using maven for dependency management and H2 database. Let’s start by adding all the dependencies to the pom.xml.


Here, We’ll be using hibernate as a JPA provider. By convention JPA looks for the configuration file in META-INF/ in the root of the classpath with name persitence.xml. let’s add one for our application.

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
   <persistence-unit name="helloworld">
           <!-- auto detection strategy -->
           <property name="hibernate.archive.autodetection" value="class, hbm"/>
           <property name="hibernate.show_sql" value="true" />
           <property name="hibernate.format_sql" value="true" />

           <!--Datasource configuration-->
           <property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
           <property name="hibernate.connection.url" value="jdbc:h2:file:~/db/SampleJPA;AUTO_SERVER=TRUE"/>
           <property name="hibernate.connection.username" value="sa"/>
           <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>

           <!--connection pool -->
           <property name="hibernate.c3p0.min_size" value="5"/>
           <property name="hibernate.c3p0.max_size" value="10"/>
           <property name="hibernate.c3p0.max_statements" value="50"/>
           <property name="hibernate.c3p0.idle_test_period" value="30000"/>

           <!--export schema-->
           <property name="hibernate.hbm2ddl.auto" value="create-drop"/>


Here we are configuring a persitence unit with Hibernate as a JPA provider along with the datasource and connection pool settings. We have also added configuration for exporting the schema to the database at the start of the application. Let’s add the entity class that has been annotated with the annotation provided in the standard javax.persistence package.

@Table(name = "MESSAGES")
public class Message {

    @Column(name = "MESSAGE_ID")
    private Long id;

    @Column(name = "MESSAGE_TEXT")
    private String text;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "MESSAGE_NEXT_ID")
    private Message nextMessage;

    public Message(){}

    public Message(String text){

    public Long getId() {
        return id;

    public void setId(Long id) {
        this.id = id;

    public String getText() {
        return text;

    public void setText(String text) {
        this.text = text;

    public Message getNextMessage() {
        return nextMessage;

    public void setNextMessage(Message nextMessage) {
        this.nextMessage = nextMessage;

That’s all we need for a simple JPA application. Let’s put all our code into action with a main class.

public class Main {

    public static void main(String... args){
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("helloworld");

        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        Message message = new Message("hello JPA world!");
        message.setNextMessage(new Message("this is the next message"));


That’s all to the application.