The Entity Bean
Entity beans in the Java Persistence 1.0 specification are available only as plain old Java objects (POJOs), and are mapped to tables in a relational database. Unlike other EJB types, entities can be allocated, serialized, and sent across the network like any other POJO.
A good rule of thumb is that entity beans model business concepts that can be expressed as nouns. For example, an entity bean might represent a customer, a piece of equipment, an item in inventory, or even a place. In other words, entity beans model real-world objects; these objects are usually persistent records in some kind of database. Our hypothetical cruise line will need entity beans that represent cabins, customers, ships, etc.
A good way to understand the design of entity beans is to look at how you'd go about implementing one. To implement an entity bean, you need to define a bean class
and decide what field you will use as the identifier (primary key)
of that bean class:
Primary key
-
The primary key is something that provides a pointer into the database. It gives the entity bean class's identity both in memory as an object and in the database as a row in a table. The primary key can be a class or a primitive type.
Bean class
-
The entity bean class may contain business logic but is usually just the object representation of persistence storage. In general, only business logic like validation should be placed in the entity bean class. The bean class is a POJO that does not have to implement any interface or even be serializable. It must be tagged with the @javax.persistence.Entity
annotation and have at least one field or getter method that is designated as the primary key of the entity bean class in the database. This is usually done with the @javax.persistence.Id
annotation. Entities have other annotations available to define a full object-relational database mapping as well.
In Java Persistence, entity beans are not components like their EJB 2.1 counterparts are. Application code works directly with the entity bean classes and does not interact with the entity through a component interface, as you would with an EJB session bean. So how is an entity queried? How is it stored? Is some magic involved? No. To interact with entity beans, Java Persistence provides a new service called the EntityManager
. All access to an entity goes through this service. It provides a query API and life cycle methods for the entity. No magic. No bytecode manipulation. No special proxies. Just plain Java.
Unlike older versions of the EJB specification, in Java Persistence, entity beans and the EntityManager do not require an application server to be used. You can use Java Persistence in unit tests and standalone Java applications like you would any other Java library. However, the EJB 3.0 specification does provide additional tight integration with Java Persistence to make it easier to manage persistence services. Other than allowing you to write less code, this integration has additional features that are not available in Java Persistence.
The Entity Bean Class
Before we get any further, let's decide on some naming conventions for our entity beans. When we speak about an entity bean, we will call it by its common business name followed by the word entity. For example, an entity bean that is developed to model a cabin on a ship will be called the Cabin entity.
Entity beans are different from EJB session beans in that they are POJOs. They do not have a remote or local interface and can be accessed only as POJOs. Later on, we'll see how to interact with an entity bean using the EntityManager service, but for now, we'll just take a peek at how to implement this bean type. To define an entity bean, all we'll need to do is define the bean class and annotate it:
import javax.persistence.* ;
@Entity
@Table(name="CABIN")
public class Cabin {
private int id;
private String name;
private int deckLevel;
@Id
@GeneratedValue
@Column(name="CABIN_ID")
public int getId( ) { return id; }
public void setId(int pk) { this.id = pk; }
@Column(name="CABIN_NAME")
public String getName( ) { return name; }
public void setName(String str) { this.name = str; }
@Column(name="CABIN_DECK_LEVEL")
public int getDeckLevel( ) { return deckLevel; }
public void setDeckLevel(int level) { this.deckLevel = level; }
}
Unlike EJB 2.1, in which entity beans were implemented as abstract classes, Java Persistence
entity beans are real objects. They don't implement any particular EJB interface. They have fields that represent the persistent state and setter and getter methods to access those fields. The bean classes are annotated with @javax.persistence.Entity
. Java Persistence defines a relatively complete object-to-relational database mapping (ORM). This is what the rest of the annotations
in the bean class are doing. The @javax.persistence.Table
annotation specifies the database table to which the entity will be mapped. The @javax.persistence.Column
is attached to the getter methods of the persistent properties of the entity bean. It defines which column the property is mapped to in the entity bean's relational table. Finally, the @javax.persistence.Id
specifies the primary key's property, and the @javax.persistence.GeneratedValue
specifies that the container or the database will automatically generate the ID when instances of the Cabin entity are created within the database.
That's all we need to do to define an entity. We'll see later in this chapter how to create/access entity beans through the EntityManager service.
XML Deployment Descriptors and JAR Files
Once you have written your entity bean classes, you need to be able to deploy them in your environment. Entity beans are grouped into a finite set of classes called a persistence unit
. There is an EntityManager service that manages a persistence unit, and it must be identified so that it can be referenced in application code. Also, each persistence unit must be associated to a particular database so that the persistence provider knows where, how, and with what kind of database it is interacting. This information is stored in an XML deployment descriptor named persistence.xml and is a required artifact.
Annotations allow developers to specify database-mapping metadata directly in the bean class file. Although this is a very simple way to define this information, whether annotations
should be used in development is a much-heated debate in the Java community. Many feel that database mappings are configuration metadata that should be defined separate from the entity bean class. To facilitate this requirement, the Java Persistence specification allows you to define the bean to database mappings in an additional XML deployment descriptor called a mapping file. This XML mapping file can be used instead of bean class annotations. If bean class annotations already exist, then this mapping file can either override these annotations or provide additional metadata. XML mapping files always take precedence over any bean class annotations.
Once you have defined your XML deployment descriptors
and entity bean classes, you must package them all in a Java Archive (JAR) file. The JAR file is used as both a library at runtime and a holder for deployment information. Whether you are using persistence in an application server or within a standalone Java application, the persistence provider will examine the JAR file to determine how to deploy one or more persistence units into your environment.
|