Monday, January 4, 2010

How to use Java Persistence API (JPA)?

The Java Persistence API, sometimes referred to as JPA, is a Java programming language framework that allows developers to manage relational data in applications. A persistence entity is a lightweight Java class whose state is typically persisted to a table in a relational database. Instances of such an entity correspond to individual rows in the table. Entities typically have relationships with other entities, and these relationships are expressed through object/relational metadata. Object/relational metadata can be specified directly in the entity class file by using annotations, or in a separate XML descriptor file distributed with the application.

Let's start with Simple Java Code.

Consider following table in any rational database.


Table Structure:

CREATE TABLE `persistencemsg` (
`messageCode` INT(10) NOT NULL,
`sessionId` VARCHAR(500) NULL,
`message` BLOB(4294967295),
PRIMARY KEY (`messageCode`),
INDEX `messageCode` (`messageCode`)
)
ENGINE = INNODB;


Now, we will write corresponding entity class (JPIPersistenceMessage.java) for the same. @Table annotation represents table name of the table, in our case it is 'PERSISTENCEMSG'. This entity class is always implements Serializable to write thread safe code. It contains getter and setter method for each column in the table. @Column annotation represents column name corresponding to the each column in the table. Go through below Java code.


Class: JPIPersistenceMessage.java

import java.io.Serializable;
import java.nio.ByteBuffer;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

/**
*
* @author naman
*/
@Entity
@Table(name = "PERSISTENCEMSG")
public class JPIPersistenceMessage implements Serializable {

private byte [] message;
private int messageCode;
private String sessionId;

/**
* @return the message
*/
@Column(name = "MESSAGE")
public byte[] getMessage() {
return message;
}

/**
* @param message the message to set
*/
public void setMessage(byte[] message) {
this.message = message;
}

/**
* @return the messageCode
*/
@Column(name = "MESSAGECODE")
public int getMessageCode() {
return messageCode;
}

/**
* @param messageCode the messageCode to set
*/
public void setMessageCode(int messageCode) {
this.messageCode = messageCode;
}

/**
* @return the sessionId
*/
@Column(name = "SESSIONID")
public String getSessionId() {
return sessionId;
}

/**
* @param sessionId the sessionId to set
*/
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
}


Now, how do we use this class for add/edit/update/find operation? First, we need to connect to the database so we have to write one XML file called 'persistence.xml' which is part of META-INF folder in your application. It contains properties to connect to the database. Please change as per your requirement.


XML File: persistence.xml

<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_1_0.xsd"
version="1.0">
<persistence-unit name="persist_name">
<class>JPIPersistenceMessage</class>
<properties>
<property name="toplink.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="toplink.jdbc.password" value="password"/>
<property name="toplink.jdbc.url" value="jdbc:mysql://localhost:3306/databasename"/>
<property name="toplink.jdbc.user" value="username"/>
<property name="toplink.jdbc.read-connections.max" value="3"/>
<property name="toplink.jdbc.read-connections.min" value="1"/>
<property name="toplink.jdbc.read-connections.shared" value="true"/>
<property name="toplink.jdbc.write-connections.max" value="5"/>
<property name="toplink.jdbc.write-connections.min" value="2"/>
<property name="toplink.cache.type.default" value="Full"/>
<property name="toplink.target-database" value="MySQL4"/>
</properties>
</persistence-unit>
</persistence>


Let's write manager class (JPIPersistenceManager.java) for database operations. We need to load EntityManagerFactory using persistence-unit name given in persistence.xml file, in this case it is 'persist_name'. Now load EntityManager based on EntityManagerFactory. Now you can call all database operations like add/delete/find on this EntityManager object. User must have to start and close the transaction during each operation. Please go through below code.


Class: JPIPersistenceManager.java

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

/**
*
* @author naman
*/
public class JPIPersistenceManager {

private static EntityManagerFactory emf;
private static EntityManager em;

public void createEntityManagerFactory(String persistenceUnitName) {
emf = Persistence.createEntityManagerFactory(persistenceUnitName);
}

private static void createEntityManager() {
em = emf.createEntityManager();
}

private static void closeEntityManager() {
em.close();
}

private static void createTransactionalEntityManager() {
createEntityManager();
em.getTransaction().begin();
}

private static void closeTransactionalEntityManager() {
em.getTransaction().commit();
closeEntityManager();
}

public void storeMessage(JPIPersistenceMessage persistenceMessage) {

createTransactionalEntityManager();
em.persist(persistenceMessage);
closeTransactionalEntityManager();
}

public void deleteMessage(long messageCode) {

JPIPersistenceMessage persistenceMessageDelete = findMessage(messageCode);
createTransactionalEntityManager();
em.remove(em.merge(persistenceMessageDelete));
closeTransactionalEntityManager();
}

public JPIPersistenceMessage findMessage(long messageCode) {

createTransactionalEntityManager();
JPIPersistenceMessage jpipm = em.find(JPIPersistenceMessage.class, Long.toString(messageCode));
closeTransactionalEntityManager();
return jpipm;

}

public JPIPersistenceMessage updateMessage(byte[] message, long messageCode) {

createTransactionalEntityManager();
Query query = em.createQuery(
"UPDATE JPIPersistenceMessage p SET p.message = :message where p.messageCode = :messageCode");
query.setParameter("message", message);
query.executeUpdate();
closeTransactionalEntityManager();
return findMessage(new Long(messageCode));
}

public static void main(String args[]) {
JPIPersistenceManager persistenceManager = new JPIPersistenceManager();
persistenceManager.createEntityManagerFactory("persist_name");

// Now call storeMessage,deleteMessage, updateMessage and findMessage on persistenceManager object.
}
}


Hope it should be useful to you. Please let me know any comment on this...

1 comment:

  1. Hi Naman,
    Thanks. It is useful.

    ReplyDelete