Use ejb3 Java persistence API to standardize Java persistence operations

Source: Internet
Author: User
Tags dname glassfish jboss jboss application server
Persistence is crucial for most enterprise applications because they need to access relational databases, such as Oracle Database 10 Gb. If you are using Java to develop applications, you may be responsible for some tedious work, such as using JDBC and SQL to write update or read database code. In the past few years, some object-link ing frameworks, such as Oracle toplink and JBoss hibernate, have become very popular because they simplify persistence operations, free Java developers from boring and trivial JDBC code so that they can pay more attention to business logic. Some Java standards, such as the persistent Entity Bean managed by containers in ejb2.x, also try to solve the persistence problem, but their efforts are not very successful.

Although many options can be used to build the persistence layer of the application, there is no unified standard that can be used in the Java EE environment and Java SE environment. Ejb3java persistence API brings us good news, as part of the EJB 3.0 specification (JSR-220), It standardizes the persistence API under the Java platform. JSR-220 has been widely supported by O-R mapping software manufacturers, such as toplink and hibernate, while it is also supported by some application server manufacturers and JDO manufacturers. The ejb3 specification provides a mandatory choice for Java Enterprise applications to build a persistence layer.

In this article, I will use a simple object model as an example to introduce ejb3 Java persistence API.

Author: Debu panda; shenpipi
Original article: http://www.onjava.com/pub/a/onjava/2006/05/17/standardizing-with-ejb3-java-persistence-api.html
Matrix: http://www.matrix.org.cn/resource/article/44/44549_EJB3.html

Domain Model

When you build an enterprise application, you first design the domain model that needs to be persisted to the database. Then, you need to design the database structure together with the Database Designer. Domain models represent persistent objects or entities. An object can be a person, a place, or any other data you want to store. It also contains data and behavior. A rich domain model has all oo features, such as inheritance and polymorphism ).
The simple domain model we use as an example is as follows: the department and employee entities have a two-way one-to-multiple relationship, while the full-time employee (fulltime) the contractor entity is inherited from the employee entity.


Figure 1. Example domain object model

Basics of O-R ing framework and ejb3 JPA

If you have used a O-R ing framework like Oracle toplink to build a persistence layer for an application, you will notice that each persistence framework provides three mechanisms.

1. Declarative O-R ing method. This method, called O-R ing metadata, enables you to map an object to one or more tables in the database. Most O-R ing frameworks use XML to store metadata for O-R ing.

2. APIs used to operate entities (for example, crud operations ). The API allows you to persistently obtain, update, or delete objects. Based on the use of O-R ing metadata and APIs, The O-R ing framework replaces you with various database operations. API saves you from tedious JDBC and SQL code.

3. A Query Language to obtain objects. This is an important aspect of persistent operations, because improper SQL statements will slow down your database operations. This query language avoids mixing a large number of SQL statements in applications.

Ejb3 Java persistence API standardizes the persistence operation under the Java platform, it provides a standard O-R ing mechanism, a group of entitymanager APIs for crud operations, and an extended EJB-QL language to get entities. I will discuss these three aspects separately.

Metadata Annotation

Java SE 5.0 introduces Metadata Annotation. All Java EE components, including ejb3 JPA, use Metadata Annotation in large quantities to simplify Enterprise Java application development. For more information about Metadata Annotation, see the Bridging the Gap: j2se 5.0 annotations article written by Kyle Downey. In ejb3 JPA, metadata can be used to define objects, relationships, O-R ing, and injection of persistent context. JPA also provides methods to use XML descriptors to provide persistent metadata. The author will focus on the tagging method, because it makes development easier. However, in the product deployment phase, you may prefer to use the XML descriptor. You can use the XML descriptor to overwrite the persistence behavior defined by the annotation.

Standardization of O-R mappings in JPA

Define persistence object: Object
An object is a lightweight domain object-A pojo that needs to be persisted to a relational database. Like other pojo, an object can be an abstract class or a specific class, and it can be extended from other pojo. You can use the javax. Persistence. entity annotation to mark a pojo as an entity.

The following is an example of how to change the Department object in a domain model into an entity:

package onjava;
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.*;
@Entity
@NamedQuery(name="findAllDepartment", query="select o from Department o")
@Table(name="DEPT")
public class Department implements Serializable {
    @Id
    @Column(nullable=false)
    protected Long deptNo;
    @Column(name="DNAME")
    protected String name;
    @Column(name="LOC")
    protected String location;
    @OneToMany(mappedBy="department")
    protected Collection<Employee> employees;
    public Department() {
    }
    ...
    public Collection<Employee> getEmployees() {
        return employees;
    }
      public void setEmployees(Collection<Employee> employees)    {
        this.employees = employees;
    }
    public Employee addEmployee(Employee employee) {
        getEmployees().add(employee);
        employee.setDepartment(this);
        return employee;
    }
    public Employee removeEmployee(Employee employee) {
        getEmployees().remove(employee);
        employee.setDepartment(null);
        return employee;
    }
}

Each object has a primary key. You can use ID Annotation on a persistent field or attribute to use it as a primary key. An object can maintain its state by using fields or attributes (using the setter and getter methods. It depends on where you use ID annotation. In the preceding example, field-based access is used, and Id annotation is used for the deptno field. If you want to use a property-based access, you need to use the ID Annotation on the property.

@Id
public Long getDeptNo() {
        return deptNo;
}
public void setDeptNo(Long deptNo) {
        this.deptNo = deptNo;
}

Note that all objects in an entity inheritance system must use a common access type, fields, or attributes.
All fields defined in an object are persisted by default. If you do not want to store a field (or attribute), you must define the field (or attribute) as temporary by using the @ transient annotation or the transient modifier.

Embedded object
An embedded object is a persistent object with no ID. It is part of another entity. For example, assume that the address object does not have its own ID and is stored as part of the employee object. Therefore, address is an embedded object.
You can use the following method to create an embedded object.

@Embeddable 
public class Address {
protected String streetAddr1;
protected String streetAddr2;
protected String city;
protected String state;
..
}

The following describes how to embed an object into a target object.

    @Entity
    public class Employee {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    protected Long id;                                              
    ...
    @Embedded
    protected Address address;                                      
    ...
}

Link
In a typical domain model, entities may interact with each other or have certain relationships. The relationship between two entities may be one-to-one, one-to-one, and one-to-one ), multiple-to-many ). The relationships between entities can be described using onetoone, onetomany, manytoone, or manytomany annotations. In our example, the department and employee entities adopt a two-way onetoworkflow relationship.

Since we use field-based access in the object, we use the Annotation on the Link field of the Department object, as shown below:

@OneToMany(mappedBy="department") 
protected Collection<Employee> employees ;

For a two-way relationship, you must specify the mappedby element, as shown in the preceding figure. by specifying the field name or attribute name that owns the link, you can point out how to map the reverse link.

Standardized O-R ing
You can use Java annotations or XML to define the O-R ing of objects. Ejb3 JPA defines several annotations for O-R ing, such as table, secondarytable, column, joincolumn, and primarykeyjoincolumn. Refer to the ejb3 JPA specification to obtain information about all labels.
In our example, you can use table annotation to define the table to which the object should be mapped. For example:

@Table(name="DEPT") 
public class Department implements Serializable {

In ejb3 JPA, all mappings generally have default values. If you do not define table ing, the persistence provider assumes that the object will be mapped to a table with the same name as the object class name (in this example, the Deparment table ). If your object needs to be mapped to multiple tables, you can use secondarytable annotation.
You can use the column annotation to map a field or attribute to a field in the database, as shown below:

@Column(name="DNAME") 
protected String name;

Here, dname is the field name in the database to which the persistent field name is to be mapped. If you do not use column to define field ing, the persistence engine will try to use database Field names that are the same as field names or attribute names for persistence.

Entity inheritance
Ejb3 JPA uses multiple methods to support object inheritance. It requires two types of inherited table ing policies: Single-table-per-entity and joined-subclass. It is best to avoid using an optional table-per-class hierarchy.

The single-table-per-entity inheritance hierarchy policy allows all objects in an inheritance hierarchy to be mapped to a single table. In our example, both fulltime and contractor inherit from employee, and all their examples will be mapped to a table called EMP. In other words, all data related to employee, fulltime, and contractor will be stored in the same table.

If you use the joined-subclass policy, you can map common data to a super-class (such as employee) table, and define a table for each subclass to store the unique data of the subclass.

The inheritance annotation must be used on the superclass to specify the inherited ing policy, just like the code below. This example demonstrates how to use the single-table-per-entity policy at the Object Inheritance level.

 @Entity 
@Table(name="EMP")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="EMPLOYEE_TYPE",
                discriminatorType=DiscriminatorType.STRING, length=1)
public abstract class Employee implements Serializable {
...
}

Each subclass must specify the values used to differentiate object types, as shown below:

@Entity 
@DiscriminatorValue(value="F")
public class FullTime extends Employee {
@Column(name="SAL")
protected Double salary;
@Column(name="COMM")
protected Double commission;
@Column(name="DESIG")
protected String designation;
...
}

Entity Manager API: standard API for entity Operations

Javax. Persistence. entitymanager is used to manage object declaration cycles. It provides several methods to perform object crud operations.

The entitymanager API is called in a transaction context. You can call it outside the EJB container. For example, you can call it from a Web application. Using the entitymanager API does not necessarily require a sesssion bean facade (facade ).

Before you perform entity Operations, you must obtain an entitymanager instance. You can use the Entity Manager managed by the container or the Entity Manager managed by the application. At the same time, you can use the JNDI query or dependency injection to obtain the entitymanager instance. As the name suggests, Java EE container manages the lifecycle of Entity Manager in the case of Container Management Entity Manager. This is usually used in Enterprise Java applications.

You can use the persistencecontext annotation for dependency injection to obtain an instance of the container-managed Entity Manager, as shown below:

 @PersistenceContext(unitName="onjava")
  private EntityManager em;

If you want to use the Entity Manager managed by the application, you must manage its declaration cycle on your own. You can use the following method to create an instance.

  @PersistenceUnit(unitName="onjava")
  private EntityManagerFactory emf;
  private EntityManager em = emf.createEntityManager();

Then, you can use the entitymanager instance to perform object crud operations. To disable the Entity Manager instance managed by the application, call the em. Close () method after the operation is completed.

As mentioned above, an operation that contains any Database Change entity manager must be performed in a transaction context.
The following table lists some important methods of the entitymanager interface for entity Operations.

Objective
Public void persist (Object entity); persists an object instance.
Public <t> T Merge (T entity); merges a detached object
Public void remove (Object entity); deletes an object instance.
Public <t> t find (class <t> entityclass, object primarykey); obtains the instance of the object through the primary key.
Public void flush (); synchronize the object state with the database

You can use the persist () method to persist an object instance. For example, if you want to persist an instance of a contractor, use the following code:

@PersistenceContext(unitName="onjava")
private EntityManager em;
...
Contractor pte = new Contractor();
pte.setName("Nistha")
pte.setHourlyRate(new Double(100.0));
em.persist(pte);

If an object persists and the cascadetype of the relationship on the object is set to persist or all, the state changes of any object associated with the object will be extended. Unless you use an extended persistent context, the entity changes to the detached state after the transaction ends. The merge operation allows you to store a detached object to the database using a persistent context. The status of the detached object will be synchronized with the database. This will free you from the DTO anti-pattern, which is widely used in the EJB 2.x era, because the entities are all pojo and can be passed between layers. The only requirement for object classes is to implement the java. Io. serializable interface.

Query API

Another important issue of persistence is the acquisition of entities. When ejb3 JPA is used, the query is expressed in the Java persistent query language. Jpql is an extension of ejb ql (introduced in ejb2.0. However, ejb3 JPA solves some restrictions of ejb ql and adds new functions to make it a powerful query language.
Jpql enhancements to ejbql 2.x

The following are some new features of jpql:
--- Simplified query syntax
--- Connection operation
--- Group by and having statements
--- Subquery
--- Dynamic query
--- Named Parameters
--- Batch update and delete

Moreover, you can use native SQL to query entities if you need specific database query extensions.

Dynamic query vs. name query

You can use dynamic query or named query. A naming query is stored together with an object and can be reused in a program.
To create a dynamic query, use the createquery method of the Entity Manager interface as follows:

 Query query = em.createQuery( 
"select e from Employee e where e.empNo > ?1");
query.setParameter(1,100);
return query.getResultList();

If you want to use the name query for this query, use the namedquery annotation in the object class as follows:

@Entity 
@NamedQuery(name="findAllEmployee",
   query="select e from Employee e where e.empNo > ?1")
public abstract class Employee implements Serializable {
}

To execute a name query, first use the createnamedquery method of the entitymanager interface to create a query instance, as shown below:

query = em.createNamedQuery(" findAllEmployee"); 
query.setParameter(1,100);
return query.getResultList();

Naming Parameters
You can use named parameters in ejbql to replace location parameters. For example, you can rewrite the preceding query using the following method:

"select e from Employee e where e.empNo > :empNo "

If you use named parameters in a query, you must use the following method to set the parameters:

 query = em.createNamedQuery("findAllEmployee"); 
query.setParameter("empNo",100);
return query.getResultList();

Package
Ejb3 JPA standardizes pojo persistence operations. Therefore, entities are not limited to EJB modules. They can be packaged in a web module, an EJB-jar module, an ear-level class module, or a standard JAR file. You can also use entities in the j2se environment. You must package a deployment descriptor file (in persistence. XML.

<persistence> 
<persistence-unit name="onjava">
<provider>oracle.toplink.essentials.PersistenceProvider</provider>
<jta-data-source>jdbc/OracleDS</jta-data-source>
...
</persistence-unit>
</persistence>

This deployment descriptor identifies the data sources used by persistence providers, persistence units, and persistence units. As the name implies, a persistence unit is a group of entities that need to be managed together. If you define a unique persistence unit in a specific module, you do not need to define the object class in persistence. xml. The persistence provider will automatically find the object class.

Toplink essen: reference implementation
Toplink essenins are derived from a major commercial O-R ing framework Oracle toplink, which is a reference implementation of ejb3 JPA. You can find it on the Java persistence API implementation home page.
You can use the code in this article on a reference server or other application servers that follow the fixed ejb3 JPA.

Ejb3 JPA Tool
The development tool does help you create better applications-and it can be tricky if you use XML to define O-R mappings. Eclipse Dali O-R ing project is committed to making ejb3 JPA easier, it provides integrated tools in the eclipse web tools project, this project is led by Oracle, and by JBoss, supported by BEA and versant. For more information about Dali, visit its home page.
Similarly, tools such as Oracle jdeveloper 10.1.3 and Bea workshop studio support ejb3 JPA.

Conclusion
Ejb3 Java persistence API standardizes the persistence operations on the Java platform. It simplifies transparent persistence operations by using Metadata Annotation. Several application servers, including Oracle Application Server 10g (10.1.3), Sun's open-source glassfish application server, and JBoss Application Server 4.0, all provide support for ejb3 specifications. When Java ee5.0 and EJB 3.0 are finalized, you can quickly see that many leading application servers and persistence providers have implemented the ejb3 Java persistence API. You can use the reference implementation provided by The glassfish project to start the persistent use of ejb3.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.