Hibernate.orgCommunity Documentation

Chapter 2. Entity

Table of Contents

2.1. POJO Models
2.1.1. Prefer non-final classes
2.1.2. Implement a no-argument constructor
2.1.3. Declare getters and setters for persistent attributes
2.1.4. Provide identifier attribute(s)
2.1.5. Mapping the entity
2.1.6. Mapping optimistic locking
2.1.7. Inheritance

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.

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


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)