The Java persistence API (JPA) allows you to store data from POJO's (Plain old Java Objects) into database tables.
The persistence metadata is specified using Java annotations, XML mapping files or acombination of both. In case both are used then the XML information overwrites the annotations in the Java code. This persistence metadata defines the mapping to the database and the relationship between the objects.
The JPA requires that you identify the classes that you will store in a database. JPA uses the term Entity to define classes / interfaces that it will map to a relational database.
The Java compiler will use the metadata information (from the annotations or the XML file) to perform the correct database operations.
Although this should not be used in a production environment OpenJPA has also the option to create the necessary database tables automatically from the classes.
Both EclipseLink and OpenJPA requires that the JPA library are added to the classpath to use JPA.
My example will be using Derby as a database. Download Derby and add Derby.jar to your classpath.
Download the EclipseLink implementation from http://www.eclipse.org/eclipselink/downloads/ and unpack it to a folder "ecliselink". The download contains several jars. Add the following jars to your project classpath:
-
eclipselink.jar
-
persistence.jar
Alternative to the EclipseLink JPA implementation you could also use the Apache OpenJPA implementation.
Download the Apache OpenJPA implementation from http://openjpa.apache.org and unpack it to a folder "myopenjpa". The download contains several jars. Add these jars to your project classpath.
Tip
Please note that you need the openjpa-*.jar from the folder "myopenjpa" as well as all the library out of the folder "myopenjpa/lib" folder.The following describes the usage of annotations for describing the persistence metadata.
A persistable class must be annotated with javax.persistence.Entity. Entity classes will become a table in a relational database. The instances of the class will be a row in the table. The Java Persistence API implementation will create a table for the entity in your relational database. By default, the table name corresponds to the class name. You can change this with the addition to the annotation @Table(name="NEWTABLENAME")
All entities must have a primary key. Keys can be a single field or a combination of fields.
JPA allows also to auto generate the primary key in the database via the @GeneratedValue annotation.
The Java Persistence API supports that you can either uses your instance variables or your uses your Java Bean conform property getters and setters for reading and saving the elements from and to the database.
If you would to use the instance variables you annotate the variable. If you want to use the getter and setting you annotate them. You are not allowed to mix both methods.
Tip
If you annotate the instance variables then the persistence implementation will directly access them. This is for example useful if you don't want to implement a setter method.All properties or fields that should not be persisted must be explicitly marked with @Transient.
By default the entity field or property name is used for the column name in the table. You can change the default name via @Column(name="newColumnName").
The following annotations can be used for fields and / or getter and setters.
Table 1. Annotations for fields / getter and setter
@Id | Identifies the uniqui ID of the database entry |
@GeneratedValue | Together with ID defines that this value is generated automatically. |
@Transient | Field will not be saved in database |
Relationships between classes can be expressed. Classes can have one to one, one to many, many to one, and many to many relationships with other classes.
A relationship can be bidirectional or unidirectional, e.g. in a bidirectional relationship both classes store a reference to each other while in an unidirectional case only one class has a reference to the other class.
The following shows our example class with the annotations for the persistence metadata. The ID will be automatically be created by the database. The field nonsenseField will not be persisted to the database.
package datamodel;
import java.util.List;
import javax.persistence.ManyToOne;
import datamodel.impl.Family;
import datamodel.impl.Job;
public interface IPerson {
public abstract String getId();
public abstract void setId(String Id);
public abstract String getFirstName();
public abstract void setFirstName(String firstName);
public abstract String getLastName();
public abstract void setLastName(String lastName);
public Family getFamily();
public void setFamily(Family family);
public abstract ListgetJobList();
public abstract void setJobList(Listjobs);
public abstract String getNonsenseField();
public abstract void setNonsenseField(String nonsenseField);
}
package datamodel.impl;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Transient;
import datamodel.IPerson;
@Entity
public class Person implements IPerson {
private String id;
private String firstName;
private String lastName;
private Family family;
private String nonsenseField = "";
private ListjobList = new ArrayList ();
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE)
public String getId() {
return id;
}
public void setId(String Id) {
this.id = Id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
// Leave the standard column name of the table
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@ManyToOne
public Family getFamily() {
return family;
}
public void setFamily(Family family) {
this.family = family;
}
@Transient
public String getNonsenseField() {
return nonsenseField;
}
public void setNonsenseField(String nonsenseField) {
this.nonsenseField = nonsenseField;
}
@OneToMany
public ListgetJobList() {
return this.jobList;
}
public void setJobList(ListnickName) {
this.jobList = nickName;
}
}
package datamodel;
public interface IJob {
public abstract String getId();
public abstract void setId(String id);
public abstract double getSalery();
public abstract void setSalery(double salery);
public abstract String getJobDescr();
public abstract void setJobDescr(String jobDescr);
}
package datamodel.impl;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import datamodel.IJob;
@Entity
public class Job implements IJob {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private String id;
private double salery;
private String jobDescr;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public double getSalery() {
return salery;
}
public void setSalery(double salery) {
this.salery = salery;
}
public String getJobDescr() {
return jobDescr;
}
public void setJobDescr(String jobDescr) {
this.jobDescr = jobDescr;
}
}
Alternative to the annotations you can also use XML metadata to define the persistence metadata.
You can create a file orm.xml within the META-INF directory to describes this data.
The following file describes the persistence data in an external file orm.xml. No annotations are required in Person.java. We use for illustration a simplified example of person.
package datamodel;
public interface IPerson {
public abstract String getId();
public abstract void setId(String Id);
public abstract String getFirstName();
public abstract void setFirstName(String firstName);
public abstract String getLastName();
public abstract void setLastName(String lastName);
public abstract String getNonsenseField();
public abstract void setNonsenseField(String nonsenseField);
}
package datamodel;
import javax.persistence.*;
@Entity
@Table(name="MYAPPLICATION.PEOPLETABLE")
public class Person implements IPerson {
private String id;
private String firstName;
private String lastName;
private String nonsenseField="";
@Id
public String getId() {
return id;
}
public void setId(String Id) {
this.id = Id;
}
// Name the column to "MYFIRST"
@Column(name="MYFIRST")
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
// Leave the standard column name of the table
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Transient
public String getNonsenseField() {
return nonsenseField;
}
public void setNonsenseField(String nonsenseField) {
this.nonsenseField = nonsenseField;
}
}
This is required orm.xml for this mapping.
0 comments:
Post a Comment