iBATIS, Hibernate, and JPA: Which is right for you?

Object-relational mapping solutions compared

1 2 3 4 5 6 7 Page 6
Page 6 of 7

Working with JPA

JPA uses many interfaces and annotation types defined in the javax.persistence package available with version 5 of Java EE. JPA uses entity classes that are mapped to tables in the database. These entity classes are defined using JPA annotations. Listing 9 shows the entity class named Employee that corresponds to the EMPLOYEE table in the sample application's database.

Listing 9. Employee entity class

@Entity
@Table(name = "employee")
@NamedQueries({@NamedQuery(name = "Employee.findByEmpId", query = "SELECT e FROM Employee e WHERE e.empId = :empId"), @NamedQuery(name = "Employee.findByEmpFirstname", query = "SELECT e FROM Employee e WHERE e.empFirstname = :empFirstname"), @NamedQuery(name = "Employee.findByEmpLastname", query = "SELECT e FROM Employee e WHERE e.empLastname = :empLastname")})
public class Employee implements Serializable {
        @Id
      @Column(name = "emp_id", nullable = false)
  private Integer empId;
  @Column(name = "emp_firstname", nullable = false)
  private String empFirstname;
  @Column(name = "emp_lastname", nullable = false)
  private String empLastname;

public Employee() {    }
public Employee(Integer empId) {
        this.empId = empId;
}
public Employee(Integer empId, String empFirstname, String empLastname) {
   this.empId = empId;
        this.empFirstname = empFirstname;
        this.empLastname = empLastname;
}
public Integer getEmpId() {
        return empId;
      }
      public void setEmpId(Integer empId) {
        this.empId = empId;
      }
      public String getEmpFirstname() {
        return empFirstname;
}
      public void setEmpFirstname(String empFirstname) {
        this.empFirstname = empFirstname;
}
      public String getEmpLastname() {
        return empLastname;
}
public void setEmpLastname(String empLastname) {
        this.empLastname = empLastname;
}
   /****
*override equals, hashcode and toString methods
*using @Override annotation
******/

The features of an entity class are as follows:

  • The entity class is annotated using the javax.persistence.Entity annotation (@Entity).
  • It must have a public or protected no-argument constructor, and may also contain other constructors.
  • It cannot be declared final.
  • Entity classes can extend from other entities and non-entity classes as well; the converse is also possible.
  • They cannot have public instance variables. The class members should be exposed using only public getter and setter methods, following JavaBean style.
  • Entity classes, being POJOs, generally need not implement any special interfaces. However, if they are to be passed as arguments over the network, then they must implement the Serializable interface.

The javax.persistence.Table annotation specifies the name of the table to which this entity instance is mapped. The class members can be Java primitive types, wrappers of Java primitives, enumerated types, or even other embeddable classes. The mapping to each column of the table is specified using the javax.persistence.Column annotation. This mapping can be used with persistent fields, in which case the entity uses persistent fields as well, or with getter/setter methods, in which case the entity uses persistent properties. However, the same convention must be followed for a particular entity class. Also, fields that are annotated using the javax.persistence.Transient annotation or marked transient will not be persisted into the database.

Each entity has a unique object identifier. This identifier is used to differentiate among different entity instances in the application domain; it corresponds to a primary key that is defined in the corresponding table. A primary key can be simple or composite. A simple primary key is denoted using the javax.persistence.Id annotation. Composite primary keys can be a single persistent property/field or a set of such fields/properties; they must be defined in a primary key class. Composite primary keys are denoted using the javax.persistence.EmbeddedId and javax.persistence.IdClass annotations. Any primary key class should implement the hashcode() and equals() methods.

The life cycle of JPA entities is managed by the entity manager, which is an instance of javax.persistence.EntityManager. Each such entity manager is associated with a persistence context. This context can be either propagated across all application components or managed by the application. The EntityManager can be created in the application using an EntityManagerFactory, as shown in Listing 10.

Listing 10. Creating an EntityManager

public class Main {
  private EntityManagerFactory emf;
  private EntityManager em;
  private String PERSISTENCE_UNIT_NAME = "EmployeePU";
  public static void main(String[] args) {
      try      {
          Main main = new Main();
          main.initEntityManager();
          main.create();
          System.out.println("Employee successfully added");
          main.closeEntityManager();
      }
      catch(Exception ex)      {
          System.out.println("Error in adding employee");
          ex.printStackTrace();
      }
  }
 private void initEntityManager()  {
 emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
         em = emf.createEntityManager();
  }
  private void closeEntityManager()   {
      em.close();    emf.close(); }
 private void create() {
      em.getTransaction().begin();
      Employee employee=new Employee(100);
      employee.setEmpFirstname("bob");
      employee.setEmpLastname("smith");
      em.persist(employee);
      em.getTransaction().commit();
    }
}

The PERSISTENCE_UNIT_NAME represents the name of the persistence unit that is used to create the EntityManagerFactory. The EntityManagerFactory can also be propagated across the application components using the javax.persistence.PersistenceUnit annotation.

In the create() method in Listing 10, a new employee record is being inserted into the EMPLOYEE table. The data represented by the entity instance is persisted into the database once the EntityTransaction associated with persist() is completed. JPA also defines static and dynamic queries to retrieve the data from the database. Static queries are written using the javax.persistence.NamedQuery annotation, as shown in the Employee entity class. Dynamic queries are defined directly in the application using the createQuery() method of the EntityManager.

1 2 3 4 5 6 7 Page 6
Page 6 of 7