Persistent Classes 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). Persistent classes have, as the name implies, transient and also persistent instance stored in the database. Hibernate works best if these classes follow some simple rules, also known as the Plain Old Java Object (POJO) programming model. However, Hibernate3 also allows you to express a domain model as nested dynamic Maps, if required. A simple POJO example Most Java applications require a persistent class representing felines. There are four main rules to follow here: Declare accessors and mutators for persistent fields Cat declares accessor methods for all its persistent fields. Many other ORM tools directly persist instance variables. We believe it is far better to decouple this implementation detail from the persistence mechanism. Hibernate persists JavaBeans style properties, and recognizes method names of the form getFoo, isFoo and setFoo. You may however 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. Implement a no-argument constructor Cat has a no-argument constructor. All persistent classes must have a default constructor (which may be non-public) so Hibernate can instantiate them using Constructor.newInstance(). We recommend to give the constructor at least package visibility for runtime proxy generation in Hibernate. Provide an identifier property (optional) Cat has a property called id. This property holds 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 optional. You can leave it off and let Hibernate keep track of object identifiers internally. However, for many applications it is still a good (and very popular) design decision. What's more, some functionality is available only to classes which declare an identifier property: Cascaded updates (see "Lifecycle Objects") Session.saveOrUpdate() We recommend you declare consistently-named identifier properties on persistent classes. We further recommend that you use a nullable (ie. non-primitive) type. Prefer non-final classes (optional) 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 - which will limit your options for performance tuning somewhat. Implementing inheritance A subclass must also observe the first and second rules. It inherits its identifier property from Cat. Implementing <literal>equals()</literal> and <literal>hashCode()</literal> You have to override the equals() and hashCode() methods if you intend to mix objects of persistent classes (e.g. in a Set). This only applies if these objects are loaded in two different Sessions, as Hibernate only guarantees JVM identity ( a == b , the default implementation of equals()) inside a single Session! Even if both objecs a and b are the same database row (they have the same primary key value as their identifier), we can't guarantee that they are the same Java instance outside of a particular Session context. The most obvious way is to implement equals()/hashCode() by comparing the identifier value of both objects. If the value is the same, both must be the same database row, they are therefore equal (if both are added to a Set, we will only have one element in the Set). Unfortunately, we can't use that approach. Hibernate will only assign identifier values to objects that are persistent, a newly created instance will not have any identifier value! We recommend implementing equals() and hashCode() using Business key equality. Business key equality means that the equals() method compares only the properties that form the business key, a key that would identify our instance in the real world (a natural candidate key): Keep in mind that our candidate key (in this case a composite of name and birthday) has to be only valid for a particular comparison operation (maybe even only in a single use case). We don't need the stability criteria we usually apply to a real primary key! Dynamic models Hibernate also supports dynamic domain models, using Maps of Maps. With this approach, you don't write persistent classes, a Hibernate mapping file for each "entity" is sufficient: ]]> At runtime, you only use Maps and use the Hibernate entity name to refer to a particular type. TODO: Document user-extension framework in the property and proxy package