| By Mike Keith, Merrick Schincariol | Article Rating: |
|
| October 20, 2006 02:00 PM EDT | Reads: |
29,176 |
Experience has taught us that it's not enough to simply have a persistence standard as part of an enterprise specification. It must be a standard that can solve people's problems and be useful to most of the applications that want to use it. While earlier versions of Enterprise JavaBeans (EJB) persistence met some of the needs, they were primarily focused on the distributed problem domain. It is now known, and has been proven by successful commercial products like Oracle TopLink and Open Source projects like JBoss Hibernate, that the objects to be persisted don't have to be anything more than simple Java objects. The proof was in the popularity of these Object-Relational Mapping (ORM) tools; most developers have tended to pick up and use these tools rather than adopt the Java 2 Enterprise Edition (J2EE) entity bean programming standard.
The problem was that even though ORM technology suited them, some corporate IT shops were somewhat uncomfortable with using proprietary APIs in their large-scale applications. They wanted and needed the flexibility and reduced risk that comes with standards-based development. The time for standardization of persistent POJOs (Plain Old Java Objects) had come and the EJB 3.0 Java Persistence API (JPA) was born. It was completed and released as part of Java Enterprise Edition 5 (Java EE 5) in May 2006. Now everybody who has been using a proprietary Java persistence product can develop to a standard set of APIs and benefit from the portability and common experience that standards bring to the table. In this article we will introduce you to a few parts of the JPA API and show how they can enable developers to write portable persistence applications. We will also highlight interesting portability pitfalls that could ensnare the unwary developer.
The Domain Model
The primary currency of the JPA is the entity, which is just a regular Java object that may be persisted to a relational database. Entities can be created, queried for, accessed, modified, and removed from the table or tables that contain the state and are uniquely identified by means of their persistent identity or primary key.
Note that entities are quite different from the entity beans of previous EJB versions. Entity beans were full-bodied components that contained built-in remoting, transactional and security logic inserted into container-generated sub-classes by the EJB container at deployment time. Entity beans were created and destined to be entity beans, and were not suited to be anything else. Conversely, entities are simple object classes that don't have to contain any JPA-specific code. A class may often be designated as an entity without even changing a line of code in it; however, if annotations are used, the developer can choose to add them to the code if he decides it's appropriate. The entity object model is completely agnostic not only to the vendor (called the persistence provider) but possibly even the fact that it's persistent. For example, a developer could take an existing non-persistent class called Flight and make it persistent simply by indicating that it's an entity through the use of an @Entity annotation in the class:
@Entity public class Flight { ... }
Or, the developer could leave the class entirely alone and just add an entity entry in a separate XML mapping file:
<entity class="Flight">
...
</entity>
Regardless of which approach is used, the Flight class will continue to function as either a non-persistent class or a persistence entity depending on how it's used. It may have DomesticFlight, InternationalFlight, or other classes that extend it, and these classes may be entities or non-entities, but regardless of the JPA implementation, the object model can be exactly the same. No additional constraints, such as having to implement an interface or extend a special super-class, are imposed on the Flight class by either the API or persistence vendor implementations of the API.
O-R Mapping Metadata
We just saw how either an annotation or XML can be used to designate a class as an entity. This is obviously just scratching the surface of the metadata that is available and that dictates how the entity can be used or mapped. There's a host of JPA metadata in both annotation and XML forms, and the fact that this metadata is defined by the specification is significant for portability.
The largest portion of metadata is typically applied to entities for purposes of object-relational mapping, or mapping the state in the entity to the tables and columns in the database. Until JPA came along every ORM tool had its own way of defining and storing the ORM information for the entities that were mapped to the database. The JPA specification defines specifically and exactly how the metadata should be formed for a group of entities or the entities that make up a persistence unit. For example, we can choose to mark up our Flight class using annotations to indicate how it's mapped to the database.
@Entity
public class Flight {
@Id
@Column(name="ID")
int flightNumber;
@Column(name="DEP_TIME")
Timestamp departureTime;
String dest;
@OneToMany(mappedBy="flight")
Collection<Passenger> passengerList;
...
}
The annotations denote how the Flight class is mapped to the database. The @Table annotation is used to indicate to which table the entity is mapped, but it's often not even required since a default table name will be applied in its absence. The default name that is used is the unqualified name of the class. In this case the table will be called FLIGHT. The attribute mappings show how the members of the Flight class correspond to the columns of the FLIGHT table. The @Id annotation indicates that flightNumber is the primary key attribute, and the accompanying @Column annotation shows that it maps to the primary key column ID in the FLIGHT table. Likewise, the @Column annotation on the departureTime attribute denotes that the departure time is stored in the "DEP_TIME" column. Since there's no annotation on the dest attribute, the column name is defaulted to the name of the attribute, or DEST. The passengerList attribute is annotated with an @OneToMany annotation, signifying that it's a one-to-many relationship and the name of the foreign key or join column in the database is specified by the Passenger.flight attribute mapping.
All of this mapping metadata is very convenient in that regardless of the JPA implementation runtime, the same annotation configuration will imply exactly the same OR mappings. Even the same default values will be used since the rules for defaulting are dictated by the specification.
The XML mapping file alternative is equally portable in that the same mapping file(s) can be used when running with any and every compliant JPA vendor. The mapping files may be used to increment or even override the mapping information stored in annotations, and because the overriding characteristics are defined to the level of entity attributes, they can be portably overridden. For example, if we had an XML mapping file that contained the following, it would cause the departure time and destination to be stored in the DEPT_TIME and DST columns, respectively.
<entity class="Flight">
<attributes>
<basic name="departureTime">
<column name="DEPT_TIME"/>
</basic>
<basic name="dest">
<column name="DST"/>
</basic>
</attributes>
</entity>
Persistence Unit Metadata
The other main type of metadata is the persistence unit metadata, or metadata that applies to an entire group or configuration of entities. This metadata is stored in a file called persistence.xml and includes the things that are normally defined for a given runtime environment. For example, although JPA can run in a Java SE environment it will typically be used in an application server. When running in Java EE the persistence provider will have to know which data source to use to connect to in order to retrieve and store entity data. The JNDI name of the data source can be specified in the persistence.xml file, and is portable as long as that data source is configured and present in the JNDI namespace of the server runtime being used.
A number of provider-specific properties can be included in the persistence.xml file. The properties are primarily for non-standard features, but they are specified in a standard way that lets different vendors use the same format. So while developers may need to specify a different property for each vendor, a given vendor will recognize the properties that apply to it but ignore those that it doesn't know about. As an example, if a developer wanted the logging level to be set to the level that included printing the generated SQL and he was running in either TopLink Essentials or Hibernate then he would have the following property section in his persistence.xml file:
<properties>
<property name="toplink.logging.level" value="FINE"/>
<property name="hibernate.show-sql" value="true"/>
</properties>
Spring 2.0 users can make use of the additional Spring abstractions over some of the more common properties, such as logging, thereby gaining an additional level of portability across vendors.
Published October 20, 2006 Reads 29,176
Copyright © 2006 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Mike Keith
Mike Keith has more than 15 years of teaching, research and practical experience in object-oriented and distributed systems, specializing in object persistence. He was the co-specification lead for EJB 3.0 (JSR 220), a member of the Java EE 5 expert group (JSR 244) and co-authored the premier JPA reference book Pro EJB 3: Java Persistence API. Mike is currently a persistence architect for Oracle and a popular speaker at numerous conferences and events around the world.
More Stories By Merrick Schincariol
Merrick Schincariol is a senior engineer for the Oracle OC4J Java EE Container. He was a lead engineer for Oracle's EJB 3.0 release and co-author of Pro EJB 3: Java Persistence API. Before joining Oracle, Merrick developed enterprise and large-scale systems for the telecomunications industry.
- Cloud People: A Who's Who of Cloud Computing
- New Relic Q1 2013 Blazes Past Growth Targets and Reaches 40,000 Active Customer Accounts
- Learn How To Use Google Apps Script
- Cloud Expo New York: Rethink IT and Reinvent Business with IBM SmartCloud
- Cloud Expo New York: API Security, Does My Business Need an OAuth Server?
- Session Topics: 12th Cloud Expo / Cloud Expo New York
- Cloud Expo NY: Best Practices for Delivering Oracle Database as a Service
- Measuring the Business Value of Cloud Computing
- Cloud Expo New York: Build Modern Business Applications
- Cloud Expo New York: Using APIs for Better Business Partnerships
- Five Big Data Features in SQL Server
- Cloud Expo New York: Evolving Cloud Computing Models
- Cloud People: A Who's Who of Cloud Computing
- New Relic Q1 2013 Blazes Past Growth Targets and Reaches 40,000 Active Customer Accounts
- Cloud Expo New York: Delivering Digital Marketing on the Cloud
- Learn How To Use Google Apps Script
- Cloud Expo New York: Rethink IT and Reinvent Business with IBM SmartCloud
- Cloud Expo New York: API Security, Does My Business Need an OAuth Server?
- Cloudant to Exhibit at Cloud Expo & Big Data Expo New York
- Session Topics: 12th Cloud Expo / Cloud Expo New York
- Cloud Expo New York: Basics of SSD Technology and Its Use in Cloud
- The Accessibility of the Cloud
- Cloud Expo NY: Best Practices for Delivering Oracle Database as a Service
- What CIOs Need to Know About Enterprise Virtualization
- A Cup of AJAX? Nay, Just Regular Java Please
- Java Developer's Journal Exclusive: 2006 "JDJ Editors' Choice" Awards
- JavaServer Faces (JSF) vs Struts
- The i-Technology Right Stuff
- Rich Internet Applications with Adobe Flex 2 and Java
- Java vs C++ "Shootout" Revisited
- Bean-Managed Persistence Using a Proxy List
- Reporting Made Easy with JasperReports and Hibernate
- Creating a Pet Store Application with JavaServer Faces, Spring, and Hibernate
- Why Do 'Cool Kids' Choose Ruby or PHP to Build Websites Instead of Java?
- What's New in Eclipse?
- Where Are RIA Technologies Headed in 2008?




















