Thursday, May 9, 2013

Eclipse – Hibernate – Application-Managed JPA annotated Entity Beans

Here's a simple step-by-step guide showing how to work with a JPA annotated Entity Bean in Eclipse using Hibernate as the JPA implementer and MySQL as the database backend.  This project is just going to record the title and rating of Wii games.  I used NintendoLife as my source for game review.

Before we start, you'll want to create a VideoGame table in MySQL.

According to the book Java EEDevelopment with Eclipse by Deepak Vohra: “The JPA specification does not mandate the creating of tables and only some JPA persistence providers create tables. If it is not known whether a persistence provider supports table generation it is better to create the tables...”

CREATE TABLE 'my_database'.'VideoGame' (
  'Title' VARCHAR(45) NOT NULL,
  'Rating' FLOAT NULL,
  PRIMARY KEY('Title')
);

Start Eclipse.
Click File > New > JPA Project

  

Title the Project VideoGame


Click Next.  Click Next again.

On the JPA Facet page select MySQL from the connection drop down.


 Right click on the newly created JPA Project and select New > JPA Entity.


Java package: jpa.entity
Class name: VideoGame

Click Next.

Click on the Add... button to add a new Entity Field
Type: String
Name: Title


Repeat the same process to add a Rating field that will be stored as a float.

Since no two Wii games will have the same title, let's make that the primary key.
Make sure the appropriate box has a check mark.


Let's add a main method to test our VideoGame entity.
  public static void main(String[] args) {
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("VideoGame");       
    EntityManager em = emf.createEntityManager();

    VideoGame videoGame = new VideoGame();
    videoGame.setTitle("Mario Kart Wii");
    videoGame.setRating((float)9/10);
    
    EntityTransaction trans = em.getTransaction();
    
    trans.begin();
    em.persist(videoGame);
    trans.commit();
    
    em.close();
    emf.close();    
  }
Note: The above was derived from pages 120 & 121 of Michael Sikora's EJB 3 Developer Guide.

We also need to edit the persistence.xml file:
    <?xml version="1.0" encoding="UTF-8"?>
      <persistence
        version = "2.0"
        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">
      
        <persistence-unit name = "VideoGame" >     
          <class>jpa.entity.VideoGame</class>
          <properties>
      
            <property
              name="hibernate.connection.url" 
              value = "jdbc:mysql://localhost:3306/<DATABASE>" />
      
            <property
              name="hibernate.connection.username"
              value = "<USERNAME>" />
      
            <property
              name="hibernate.connection.password"
              value = "<PASSWORD>" />
      
            <property
              name="hibernate.connection.driver_class"
              value = "com.mysql.jdbc.Driver" />
      
            <property
              name="hibernate.dialect"
              value = "org.hibernate.dialect.MySQLDialect" />
      
            <property
              name="hibernate.show_sql"
              value = "true" />
      
          </properties>
        </persistence-unit>
      </persistence>      
Note: The above was derived by comparing the persistence.xml file posted on roseindia.net with a hibernate.cfg.xml file I already know that works. I just copied the properties that were in both files.  Of course you'll want to replace the placeholders <DATABASE>, <USERNAME>, and <PASSWORD> with whatever database, user, and password that you are using.

If you try to run this as is, you'll get an error message similar to the following:

Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named VideoGame
  • at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:69)
  • at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:47)
  • at jpa.entity.VideoGame.main(VideoGame.java:44)
Basically Java is looking for a class that implements javax.persistence.spi.PersistenceProvider, which is a Java Enterprise Edition class. Since we're using Hibernate we want to use org.hibernate.ejb.HibernatePersistence. Therefore we need to add the hibernate-entitymanager jar to our build path. You also need to add the jar file for MySQL's Connector-J to the build path.

You should be able to run the program now and when you check the database you should see.


If you've worked with Hibernate before you're probably wondering (like I was) what the difference is between hibernate.cfg.xml and persistence.xml since they both seem to do the same thing.

According to Mark Spritzler @ coderanch.com : “If you are using JPA with Hibernate, then you will use a persistence.xml file. If you are not using JPA with Hibernate, then you will use a hibernate.cfg.xml file. You'll also use hibernate.cfg.xml if you are using a version of Hibernate earlier than version 3.x

In general, you won't need both files as you'll either use JPA or Hibernate's proprietary API," says
Pascal Thivent @ stackoverflow.com  "However, if you were using Hibernate Proprietary API and already have a hibernate.cfg.xml (and hbm.xml XML mapping files) but want to start using JPA, you can reuse the existing configuration files by referencing the hibernate.cfg.xml in the persistence.xml in the hibernate.ejb.cfgfile property - and thus have both files. Reusing existing hbm.xml files is, in my opinion, a realistic scenario that could justify keeping both (even if I'd probably migrate to JPA annotations on the long run)."

Note: I did some minor editing of what they said.  The edits are in italics.


No comments:

Post a Comment