Persistent classes are classes in an application that implement the entities of the business problem (e.g. Customer and Order in an E-commerce application). Not all instances of a persistent class are considered to be in the persistent state - an instance may instead be transient or detached.
Hibernate works best if these classes follow some simple rules, also known
as the Plain Old Java Object (POJO) programming model. However, none of these
rules are hard requirements. Indeed, Hibernate3 assumes very little about
the nature of your persistent objects. You may express a domain model in other
ways: using trees of Map
instances, for example.
Most Java applications require a persistent class representing felines.
package eg; import java.util.Set; import java.util.Date; public class Cat { private Long id; // identifier private Date birthdate; private Color color; private char sex; private float weight; private int litterId; private Cat mother; private Set kittens = new HashSet(); private void setId(Long id) { this.id=id; } public Long getId() { return id; } void setBirthdate(Date date) { birthdate = date; } public Date getBirthdate() { return birthdate; } void setWeight(float weight) { this.weight = weight; } public float getWeight() { return weight; } public Color getColor() { return color; } void setColor(Color color) { this.color = color; } void setSex(char sex) { this.sex=sex; } public char getSex() { return sex; } void setLitterId(int id) { this.litterId = id; } public int getLitterId() { return litterId; } void setMother(Cat mother) { this.mother = mother; } public Cat getMother() { return mother; } void setKittens(Set kittens) { this.kittens = kittens; } public Set getKittens() { return kittens; } // addKitten not needed by Hibernate public void addKitten(Cat kitten) { kitten.setMother(this); kitten.setLitterId( kittens.size() ); kittens.add(kitten); } }
There are four main rules to follow here:
Cat
has a no-argument constructor. All persistent classes must
have a default constructor (which may be non-public) so that Hibernate can instantiate
them using Constructor.newInstance()
. We strongly recommend having a
default constructor with at least package visibility for runtime proxy
generation in Hibernate.
Cat
has a property called id
. This property
maps to the primary key column of a database table. The property might have been called
anything, and its type might have been any primitive type, any primitive "wrapper"
type, java.lang.String
or java.util.Date
. (If
your legacy database table has composite keys, you can even use a user-defined class
with properties of these types - see the section on composite identifiers later.)
The identifier property is strictly optional. You can leave them off and let Hibernate keep track of object identifiers internally. We do not recommend this, however.
In fact, some functionality is available only to classes which declare an identifier property:
Transitive reattachment for detached objects (cascade update or cascade merge) - see Section 10.11, “Transitive persistence”
Session.saveOrUpdate()
Session.merge()
We recommend you declare consistently-named identifier properties on persistent classes. We further recommend that you use a nullable (ie. non-primitive) type.
A central feature of Hibernate, proxies, depends upon the persistent class being either non-final, or the implementation of an interface that declares all public methods.
You can persist final
classes that do not implement an interface
with Hibernate, but you won't be able to use proxies for lazy association fetching -
which will limit your options for performance tuning.
You should also avoid declaring public final
methods on the
non-final classes. If you want to use a class with a public final
method, you must explicitly disable proxying by setting lazy="false"
.
Cat
declares accessor methods for all its persistent fields.
Many other ORM tools directly persist instance variables. We believe it is
better to provide an indirection between the relational schema and internal
data structures of the class. By default, Hibernate persists JavaBeans style
properties, and recognizes method names of the form getFoo
,
isFoo
and setFoo
. You may switch to direct
field access for particular properties, if needed.
Properties need not be declared public - Hibernate can
persist a property with a default, protected
or
private
get / set pair.