|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 2 of 4
The EJB entity bean is the "official" ORM solution in Java EE. However, in EJB 1.x and 2.x, the entity beans are notoriously difficult to use for two reasons:
In short, the EJB 1.x and 2.x entity bean is a poorly designed ORM framework that addresses the needs of neither the Java
object data model nor the relational table data model. Unsatisfied with EJB 1.x and 2.x entity beans, developers look to other
solutions for ORM. In the real world, the open source Hibernate (developed by JBoss) and Oracle's TopLink are the two most
successful Java ORM frameworks. Both Hibernate and TopLink are POJO-based: they do not rely on any predefined component model.
Instead, they take POJO data objects (in simple JavaBeans style) and automatically decipher how to map them, as well as the
relationships among them, to relational databases. Usually one JavaBeans class maps to one database table, and relationships
between the classes are mapped via foreign key fields in the tables. You can specify ORM metadata, such as the JavaBeans class's
corresponding table name and the property's corresponding column name, in a simple and intuitive XML configuration file. You
operate on those POJOs (e.g., saving, retrieving, and searching) via a utility class in the framework (e.g., the Session class in Hibernate).
The EJB 3.0 entity bean builds upon the ideas and success of Hibernate and TopLink. It provides a standard POJO ORM framework for Java EE. In addition, EJB 3.0 has two crucial innovations over existing POJO persistence solutions:
Now, let's check out how EJB 3.0 accomplishes POJO ORM via several simple examples.
In EJB 3.0, each entity bean is a simple JavaBeans-style class. To tell the EJB 3.0 container that this class should be mapped
for persistence, you should annotate the class with the @Entity annotation.
Each entity bean class is mapped to a relational database table. By default, the table name matches the class name. You can
specify another table name for the class using the @Table annotation. Each JavaBeans property of the bean class is mapped to a column in the table. Again, the column name is the property
name by default, and you can change that by tagging the @Column annotation to the property's setter method. Below is a simple example of an EJB 3.0 entity bean class:
@Entity
// @Table (name="AlternativeTableName")
public class Person implements Serializable {
protected int id;
protected String name;
protected Date dateOfBirth;
public void setId (int id) {
this.id = id;
}
@Id(generate = GeneratorType.AUTO)
public int getId () {
return id;
}
public void setName (String name) {
this.name = name;
}
// @Column (name="AlternativeColumnName")
public String getName () {
return name;
}
public void setDateOfBirth (Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
public Date getDateOfBirth () {
return dateOfBirth;
}
}
After the container maps the Person class to the Person SQL database table, each Person instance is a row of data in the table.
Mapping a simple JavaBeans class is easy. But the advantage of automatic ORM frameworks really kicks in when you need to map interrelated objects. In the next section, let's see how EJB 3.0 handles object relationships.
In a data model, classes typically have relationships with each other. For instance, a Person object can be associated with one Resume object and vice versa (one-to-one relationship); a Person object can be associated with multiple CreditCard objects, while a CreditCard only corresponds to one Person (one-to-many relationship); multiple Person objects can be associated with an Address object, while one Address only corresponds to one Person (many-to-one relationship).
In an object model, object references handle those relationships. For instance, a Person object can have a property (i.e., field) that references a Resume object and another property that is a collection of CreditCard objects. To tell the EJB 3.0 container about the relationship between the objects, you simply annotate those JavaBeans properties
in the POJO:
@Entity
public class Person implements Serializable {
// ... ...
protected Resume resume;
protected CreditCard [] cards;
protected Address addr;
// ... ...
@OneToOne
public Resume getResume () {
return resume;
}
// ... ...
@ManyToOne
// @JoinColumn (name="MyCustomId")
public Address getAddr () {
return addr;
}
// ... ...
@OneToMany
public Collection <CreditCard> getCards () {
return cards;
}
}
In relational databases, those relationships are automatically reconstructed by the EJB 3.0 container using foreign key fields.
For instance, the Person table has a foreign key field that contains the primary key of the corresponding row in the Resume table. At runtime, the EJB 3.0 container enforces the one-to-one relationship: it guarantees that the Resume key value must be unique for each row in the Person table. To enable two-way lookup from the Resume table to the Person table, you can also define a Person property in the Resume and annotate it with the @OneToOne annotation as well.
The Person table also has a foreign key field that contains the primary key of the corresponding row in the Address table. In this case, the same Address primary key can appear in several Person rows due to the many-to-one relationship. For one-to-many relationships, the mapping is a little more complex as the foreign
key column is defined in the source of the many-to-one table. So, in the CreditCard class, you must define a Person property with the @ManyToOne annotation.
| Change the foreign key column name |
|---|
The name of the foreign key column used in ORM is determined by the container or explicitly specified with the @JoinColumn annotation.
|
The association relationship discussed above is only one type of entity relationship. Another important relationship between entity bean classes is inheritance.
A key concept behind object-oriented design is inheritance. Using inheritance, you can build a complex tree of objects without
duplicated code. For instance, a consultant is a person who provides consulting services for a fee. Hence, in our data-object
model, the Consultant class inherits from the Person class with an additional rate property. Unfortunately, the inheritance concept does not exist in the world of relational databases. The ORM framework relies
on mainly two approaches for mimicking this behavior:
EJB 3.0 entity bean supports both inheritance mapping strategies, with the one-table mapping strategy being the default. You
can simply annotate the subclass to specify the inheritance strategy and the name of the differentiator column. Below is the
example of the Consultant class, which inherits from the Person class:
@Entity
@Inheritance(discriminatorValue="C")
@DiscriminatorColumn(name="person_type")
public class Consultant extends Person {
protected double rate;
public void setRate (double rate) {
this.rate = rate;
}
public double getRate () {
return rate;
}
}
In the above example, the container uses the default strategy to map the Consultant class in the same table as the Person class. If the person_type column in the table has value C, the current row represents a Consultant object. Otherwise, the current row represents a regular Person object.
Now that you have a set of annotated EJB 3.0 entity bean classes for your data model, you can bundle them together and deploy
them into a server environment. EJB 3.0 defines a special archive file format, known as the persistence archive (.par file suffix), for entity beans.
Archived Discussions (Read only)