Thursday, 24 March 2011

JPA Architecture

Java Persistence API or JPA for short is a lightweight, POJO-based Java framework to persist the Java Objects to the relational database. JPA is uses metadata to map the persistence objects with the database table. JPA supports SQL like query language to ease the process of querying the database. JPA Query language can be used to execute both static and dynamic queries.

JPA supports many ORM frameworks available these days. You can use either free or commercial ORM framework in your JPA based applications. It's also very easy to switch to different ORM frameworks.

List of ORM frameworks:

  1. Hibernate
  2. Toplink from oracle
  3. iBatis
  4. Open JPA

You can easily plug any persistence provider into your JPA application.

JPA Concepts

JPA concept includes the three components Entity, EntityManager and EntityManagerFactory. Following diagram shows the primary components of JPA architecture.

Entity

Entity is the persistence (POJO) objects that represent one record in the table. The Entity is simple annoted POJO class, which is easy to develop. Here are the characteristics of an Entity:

  1. Entity can be persisted to the relational database
  2. Entity is identified by persistence identity (the primary key of the table)
  3. Entity supports transactions
  4. Entity supports inheritance

Example consider this class:

class MobileEntity{

private String model;
private String manufacturer;
private Double price;
private String imeiNo;

…..
// Getters and Setters go here.
}


Now to make it an entity, we mark the class with @Entity annotation:


@Entity
class MobileEntity{

private String model;
private String manufacturer;
private Double price;
private String imeiNo;

…..
// Getters and Setters go here.
}


EntityManager

The EntityManager interface is providing the API for interacting with the Entity. Some of the functions provided by EntityManager API are:


  1. persist – this method is used to save a new entity
  2. merge – this method is used to update the sate of entity into database
  3. remove – this method is used to remove the entity instance

You will learn about all these functions in next sections. We have developed many JPA examples to help you in learning JPA.

EntityManagerFactory

The EntityManagerFactory is used to create an instance of EntityManager. In your application when there is no use of EntityManagerFactory or application shuts down then it is necessary to close the instance of EntityManagerFactory . Once the EntityManagerFactory is closed, all its EntityManagers are also closed.

JDBC vs ORM

Since entities form the heart of the JPA, they have some unique characteristics like persistability, identity and transactionability. The property of persistability deals with the storing and retrieving of entity from and to a persistent medium like database. Identity property is usually used to identity one unique entity among multiple entities (or multiple entity instances) in a database. All the CRUD operations (Create, Update and Delete) for entity objects will occur within a transactional context and it is one of the major characteristic for an entity object as the real state of an entity depends whether a transaction completes (commits/fails) or not.

Example

import  java.sql.*;

public class AllTableName{
public static void main(String[] args) {
System.out.println( "Listing all table name in Database!" );
Connection con = null ;
String url = "jdbc:mysql://localhost:3306/" ;
String db = "jdbctutorial" ;
String driver = "com.mysql.jdbc.Driver" ;
String user = "root" ;
String pass = "root" ;
try {
Class.forName(driver);
con = DriverManager.getConnection(url+db, user, pass);
try {
DatabaseMetaData dbm = con.getMetaData();
String[] types = { "TABLE" };
ResultSet rs = dbm.getTables(null,null, "%" ,types);
System.out.println( "Table name:" );
while (rs.next()){
String table = rs.getString( "TABLE_NAME" );
System.out.println(table);
con.close();
}
}
catch (SQLException s){
System.out.println( "No any table in the database" );
}
}
catch (Exception e){
e.printStackTrace();
}
}
}


Above program retrieves the names of all tables present in the database and then displays on the console.

Advantages of JDBC


  • Clean and easily for small programs
  • JDBC provides good performance with large amount of data
  • Small JDBC programs can be developed very easily
  • Very good for small applications

Disadvantages of JDBC


  • JDBC is not easily if it is used in large projects. There is a big programming overhead.
  • Programmer must hardcode the Transactions and concurrency code in the application.
  • Handling the JDBC connections and properly closing the connection is also a big issue. Properly closing the connection is must.
  • JDBC is not good for big applications

ORM


ORM stands for Object Relational Mapping, is another technology to access the data databases. Here business object is directly mapped to the database tables with the help of ORM framework.

ere are the benefits of ORM technology


  • No need to deal with the SQL Queries to save and retrieve the data
  • Simple configuration
  • Standardized API to persist the business objects
  • Fast development of application
  • Concurrency support
  • Excellent cashing support for better performance of the application
  • Injected transaction management
  • Configurable logging
  • Easy to learn and use

Disadvantages of ORM


  • Slow performance in case of large batch updates
  • Little slower than JDBC 

JPA : Overview

The Java Persistence API or JPA is one to the specification of JEE5, which allows the programmer to develop the persistence layer for their desktop and web applications. JPA is developed to ease the development of persistence layer and it has also standardized the Java ORM or Object Relational Mapping technologies.

It provides POJO (Plain Old Java Object) standard and object relational mapping (OR mapping) for data persistence among applications. Persistence, which deals with storing and retrieving of application data, can now be programmed with Java Persistence API starting from EJB 3.0 as a result of JSR 220. This API has borrowed many of the concepts and standards from leading persistence frameworks like Toplink (from Oracle) and Hibernate (from JBoss). One of the great benefits of JPA is that it is an independent API and can nicely integrate with J2EE as well as J2SE applications.

Persistence Entities

Persistent Data normally refers to permanent data in an application. The state of these data is made permanent by storing them in a persistent medium like database, files or a disk tape. In JPA terms, these persistent data are referred as entities. An entity refers to a logical collection of data that can be stored or retrieved as a whole. For example, in a banking application, Customer and BankAccount can be treated as entities. Customer name, customer address etc can be logically grouped together for representing a Customer entity. Similarly account number, total balance etc may be logically grouped under BankAccount entity.

Since entities form the heart of the JPA, they have some unique characteristics like persistability, identity and transactionability. The property of persistability deals with the storing and retrieving of entity from and to a persistent medium like database. Identity property is usually used to identity one unique entity among multiple entities (or multiple entity instances) in a database. All the CRUD operations (Create, Update and Delete) for entity objects will occur within a transactional context and it is one of the major characteristic for an entity object as the real state of an entity depends whether a transaction completes (commits/fails) or not.

Initialling to zero rather than null

Some classes like BigDecimal,String have empty element into it. So we should use them nicely. Initialize these to zero, rather than null.

public void someFunc(BigDecimal p_number)
{
BigDecimal m_number;
m_number = p_number==null?BigDecimal.Zero : p_number;
}

Equivalent of function pointers of C in java

Function pointers were omitted from the Java programming language because object references can be used to provide the same functionality. Invoking a method on an object typically performs some operation on that object. However, it is possible to define an object whose methods perform operations on other objects, passed explicitly to the methods.
An instance of a class that exports exactly one such method is effectively a pointer to that method. Such instances are known as function objects. For example, consider the following class:

class StringLengthComparator {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}


This class exports a single method that takes two strings and returns a negative integer if the first string is shorter than the second, zero if the two strings are of equal length, and a positive integer if the first string is longer. This method is a comparator that orders strings based on their length instead of the more typical lexicographic ordering. A reference to a StringLengthComparator object serves as a “function pointer” to this comparator,
allowing it to be invoked on arbitrary pairs of strings. In other words, a StringLengthComparator instance is a concrete strategy for string comparison.
As is typical for concrete strategy classes, the StringLengthComparator class is stateless: It has no fields, hence all instances of the class are functionally equivalent to one another. Thus it could just as well be a singleton to save on unnecessary object creation costs :
class StringLengthComparator {
private StringLengthComparator() { }
public static final StringLengthComparator
INSTANCE = new StringLengthComparator();
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}

To pass a StringLengthComparator instance to a method, we need an appropriate type for the parameter. It would do no good to use StringLengthComparator because clients would be unable to pass any other comparison strategy. Instead, we need to define a Comparator interface and modify StringLengthComparator to implement this interface. In other words, we need to define a strategy interface to go with the concrete strategy class. Here it is:
// Strategy interface
public interface Comparator {
public int compare(Object o1, Object o2);
}

Get file size in java

How to check the file size:
public static long getFileSize(String filename) {

File file = new File(filename);

if (!file.exists() || !file.isFile()) {
System.out.println("File doesn\'t exist");
return -1;
}

//Here we get the actual size
return file.length();
}

To get the file size in KB, just divide file.length() by 1024. i.e.


public static long getFileSizeInKB(String filename) {
File file = new File(filename);
if (!file.exists() || !file.isFile()) {
System.out.println("File doesn\'t exist");
return -1;
}
//Here we get the size in KB
return file.length()/1024;
}

Monday, 21 March 2011

More on XML serialization with JAXB

I posted some days ago an article explaining how to “XML-serialize” objects with JAXB in Eclipse. The downside of using XSD for XML serialization is the dependency on the XML schema that will generate java classes; this is because I wanted to extend the classes to have extra-functionality, more constructors and so on. So I started looking for a way to serialize objects to XML without creating XSD definitions… but I found a problem: every time java classes are generated, an additional class, called ObjectFactory.java is also created. It is also needed for XML marshalling/unmarshalling. The only viable solution I found was to write my one ObjectFactory.java class, to be used by JAXB when serializing objects.

But I creating ObjectFactory is not necessary. We can simply serialize from simple xml files(see here).

But if we want we can create our own ObjectFactory Class. Example:

Step 1: Create the java classes that you need. In my case, I had two main entities, Node and Line, and two additional collections, Lines and Nodes. I also created a Graph entity, holding a list with nodes and a list with lines. Below are presented Line.java, Lines.java and Graph.java files

Line.java

package com.vaani.jaxb.objects;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Line", propOrder = { "startNode", "endNode" })
public class Line {

@XmlAttribute(name = "StartNode")
protected int startNode;
@XmlAttribute(name = "EndNode")
protected int endNode;

public Line(int start, int end) {
this.setStartNode(start);
this.setEndNode(end);
}

public Line() {
this(0, 0);
}

public int getStartNode() {
return startNode;
}

public void setStartNode(int value) {
this.startNode = value;
}

public int getEndNode() {
return endNode;
}

public void setEndNode(int value) {
this.endNode = value;
}

}


Lines.java

package com.vaani.jaxb.objects;

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "lines", propOrder = { "lines" })
public class Lines {

@XmlElement(name = "Line")
protected List<Line> lines;

public List<Line> getLines() {
if (lines == null) {
lines = new ArrayList<Line>();
}
return this.lines;
}
}



Graph.java

package com.vaani.jaxb.objects;

import java.io.*;
import java.util.*;
import javax.xml.bind.*;
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Graph")
public class Graph {

@XmlElement(name = "Nodes", required = true)
protected Nodes nodes = new Nodes();
@XmlElement(name = "Lines", required = true)
protected Lines lines = new Lines();
@XmlAttribute(name = "StartNode")
protected int startNode;
@XmlAttribute(name = "EndNode")
protected int endNode;

public void addNode(int x, int y) {
getNodes().add(new Node(x, y, getNodes().size() + 1));
}

public void addLine(int start, int end) {
getLines().add(new Line(start, end));
}

public List<Node> getNodes() {
return nodes.getNodes();
}

public void setNodes(Nodes value) {
this.nodes = value;
}

public List<Line> getLines() {
return lines.getLines();
}

public void setLines(Lines value) {
this.lines = value;
}

public int getStartNode() {
return startNode;
}

public void setStartNode(int value) {
this.startNode = value;
}

public int getEndNode() {
return endNode;
}

public void setEndNode(int value) {
this.endNode = value;
}

public void marshalToFile(String fileName) {
try {
JAXBContext jc = JAXBContext.newInstance(this.getClass().getPackage().getName());
Marshaller m = jc.createMarshaller();
m.marshal( this, new FileOutputStream(fileName) );
} catch(Exception e) {
e.printStackTrace();
}
}

public static Graph unmarshalFromFile(String fileName) {
try {
JAXBContext jc = JAXBContext.newInstance((new Graph()).getClass().getPackage().getName());
Unmarshaller um = jc.createUnmarshaller();
return (Graph) um.unmarshal(new File(fileName));
} catch (Exception e) {
return new Graph();
}
}


}


In order to be able to serialize the above classes, we must use the XML annotations like @XmlRootElement, @XmlElement, @XmlAttribute, @XmlType. For the serialization, we use the same JAXBContext, Marshaller and Unmarshaller classes.

Step 2: Implement the ObjectFactory.java class

package com.vaani.jaxb.objects;

import javax.xml.bind.annotation.XmlRegistry;

@XmlRegistry
public class ObjectFactory {

public ObjectFactory() {
}

public Graph createGraph() {
return new Graph();
}

public Node createNode() {
return new Node();
}

public Line createLine() {
return new Line();
}

}


As you can see, the class must be preceded by @XmlRegistry annotation.

Step 3: Test the serialization

package com.vaani.jaxb.objects;

import org.junit.*;
import static org.junit.Assert.*;

public class GraphTest {

Graph graph;

@Test
public void test_graph()
{
createGraph();
graph.marshalToFile("newGraphOutput.xml");
Graph secondGraph = Graph.unmarshalFromFile("newGraphOutput.xml");
assertTrue(secondGraph.getLines().size() == 2);
assertTrue(secondGraph.getNodes().size() == 3);
}

private void createGraph()
{
graph = new Graph();
graph.addNode(60, 60);
graph.addNode(110, 110);
graph.addNode(60, 110);
graph.addLine(1, 3);
graph.addLine(2, 3);
}
}


Step 4: Check the result

image