Hibernate.orgCommunity Documentation
Table of Contents
Section 2.1 The Entity Class of the JPA 2.1 specification defines its requirements for an entity class. Applications that wish to remain portable across JPA providers should adhere to these requirements.
The entity class must be annotated with the javax.persistence.Entity
annotation (or be denoted as such in XML mapping)
The entity class must have a public or protected no-argument constructor. It may define additional constructors as well.
The entity class must be a top-level class.
An enum or interface may not be designated as an entity.
The entity class must not be final. No methods or persistent instance variables of the entity class may be final.
If an entity instance is to be used remotely as a detached object, the entity class must implement the Serializable interface.
Both abstract and concrete classes can be entities. Entities may extend non-entity classes as well as entity classes, and non-entity classes may extend entity classes.
The persistent state of an entity is represented by instance variables, which may correspond to JavaBean-style properties. An instance variable must be directly accessed only from within the methods of the entity by the entity instance itself. The state of the entity is available to clients only through the entity’s accessor methods (getter/setter methods) or other business methods.
Hibernate, however, is not as strict in its requirements. The differences from the list above include:
The entity class must have a no-argument constructor, which may be public, protected or package visibility. It may define additional constructors as well.
The entity class need not be a top-level class.
Technically Hibernate can persist final classes or classes with final persistent state accessor (getter/setter) methods. However, it is generally not a good idea as doing so will stop Hibernate from being able to generate proxies for lazy-loading the entity.
Hibernate does not really care if you expose direct access to your instance variables and use them from outside the entity itself. The validity of such a paradigm, however, is debatable at best.
Let's look at each requirement in detail.
This is a requirement for JPA. It is more of a recommendation for Hibernate.
A central feature of Hibernate is the ability to lazy load an entity's data via runtime proxies. This feature depends upon the entity class being non-final or else implementing an interface that declares all the attribute getters/setters. You can still persist classes that are declared final and that do not implement such an interface with Hibernate; you just will not be able to use proxies for lazy association fetching which will ultimately limit your options for performance tuning.
Starting in 5.0 Hibernate offers a more robust version of bytecode enhancement as another means for handling lazy loading. Hibernate had some bytecode re-writing capabilities prior to 5.0 but they were very rudimentary.
You should also avoid declaring persistent attribute getters and setters as final for the reasons already mentioned. And of course making the instance variable hold the entiy's persistent state would just simply not make any sense.
The entity class should have a no-argument constructor. Both Hibernate and JPA require this.
JPA requires that this constructor be defined as public or protected. Hibernate for the most part does note care about the visibility as long as the system's SecurityManager allows overriding the visibility. That said, the constructor should be defined with at least package visibility if you wish to leverage runtime proxy generation.
Standard, portable JPA essentially requires this. Otherwise your model would violate the requirement quoted above in regards to accessing the entity persistent state fields directly from outside the entity itself.
Although Hibernate does not require it, it is recommended to follow JavaBean conventions by defining getters and setters for you entities persistent attributes. You can still tell Hibernate to directly access the entity's fields.
Attributes (whether fields or getters/setters) need not be declared public. Hibernate can deal with attributes declared with public, protected, package or private visibility. Again, if wanting to use runtime proxy generation for lazy loading the visibility for the getter/setter should be at least package visibility.
Historically this was considered optional. However, not defining identifier attribute(s) on the entity should be considered a deprecated feature that will be removed in an upcoming release.
The identifier attribute does not necessarily need to be mapped to the column(s) that physically define the primary key. However, it should map to column(s) that can uniquely identify each row.
We recommend that you declare consistently-named identifier attributes on persistent classes and that you use a nullable (i.e., non-primitive) type.
The main piece in mapping the entity is the javax.persistence.Entity
annotation. The Entity annotation defines just one attribute name
which
is used to give the entity a specific name for use in JPQL queries; by default the name is the
unqualified name of the entity class.
Example 2.1. Simple @Entity
@Entity public class Simple { @Id private Integer id; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } }
An entity models a database table. The identifier uniquely identifies each row in that table. By
default the name of the table is assumed to be the same as the name of the entity. To explicitly
give the name of the table or to specify other information about the table, we would use the
javax.persistence.Table
annotation.
Example 2.2. Simple @Entity with @Table
@Entity @Table( catalog="CRM", schema="purchasing", name="t_simple" ) public class Simple { @Id private Integer id; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } }
For details on mapping the identifier, see Chapter 6, Identifiers
JPA defines support for optimistic locking based on either a version (sequential numeric) or timestamp
strategy. To enable this style of optimistic locking simply add the
javax.persistence.Version
to the persistent attribute that defines the
optimistic locking value. According to JPA, the valid types for these attributes are limited to:
int, or Integer
short, or Short
long, or Long
java.sql.Timestamp
Example 2.3. Version
@Entity public class Course { @Id private Integer id; @Version private Integer version; ... }
@Entity public class Thing { @Id private Integer id; @Version Timestamp ts; ... }
@Entity public class Thing2 { @Id private Integer id; @Version private Instant ts; ... }
Hibernate supports a form of optimistic locking that does not require a dedicated "version attribute".
This is intended mainly for use with modeling legacy schemas. The idea is that you can get Hibernate
to perform "version checks" using either all of the entity's attributes, or just the attributes that
have changed. This is achieved through the use of the
org.hibernate.annotations.OptimisticLocking
annotation which defines a
single attribute of type org.hibernate.annotations.OptimisticLockType
.
There are 4 available OptimisticLockTypes:
NONE
- optimistic locking is disabled. Even if there is a @Version
annotation present.
VERSION
(the default) - performs optimistic locking based on a @Version
as described above.
ALL
- Perform optimistic locking based on *all* fields as part of an
expanded WHERE clause restriction for the UPDATE/DELETE SQL statement.
DIRTY
- Perform optimistic locking based on *dirty* fields as part of
an expanded WHERE clause restriction for the UPDATE/DELETE SQL statement
* dynamic models (hbm.xml) * Map mode * proxy solutions (hibernate-core/src/test/java/org/hibernate/test/dynamicentity/tuplizer2)