[[entity]]
=== Entity types
:sourcedir-locking: ../../../../../test/java/org/hibernate/userguide/locking
:sourcedir-mapping: ../../../../../test/java/org/hibernate/userguide/mapping
:sourcedir-proxy: ../../../../../test/java/org/hibernate/userguide/proxy
:sourcedir-persister: ../../../../../test/java/org/hibernate/userguide/persister
:extrasdir: extras

.Usage of the word _entity_
[NOTE]
====
The entity type describes the mapping between the actual persistable domain model object and a database table row.
To avoid any confusion with the annotation that marks a given entity type, the annotation will be further referred to as `@Entity`.

Throughout this chapter and thereafter, entity types will be simply referred to as _entity_.
====

[[entity-pojo]]
==== POJO Models

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 restrict the application developer from exposing instance variables and referencing them from outside the entity class itself.
The validity of such a paradigm, however, is debatable at best.

Let's look at each requirement in detail.

[[entity-pojo-final]]
==== Prefer non-final classes

A central feature of Hibernate is the ability to load lazily certain entity instance variables (attributes) 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 final classes that do not implement such an interface with Hibernate,
but you will not be able to use proxies for fetching lazy associations, therefore limiting your options for performance tuning.
For the very same reason, you should also avoid declaring persistent attribute getters and setters as final.

[NOTE]
====
Starting with 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.
See the <<chapters/pc/BytecodeEnhancement.adoc#BytecodeEnhancement,Bytecode Enhancement>> for additional information on fetching and on bytecode enhancement.
====

[[entity-pojo-constructor]]
==== Implement a no-argument constructor

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 not care about the constructor visibility, as long as the system SecurityManager allows overriding the visibility setting.
That said, the constructor should be defined with at least package visibility if you wish to leverage runtime proxy generation.

[[entity-pojo-accessors]]
==== Declare getters and setters for persistent attributes

The JPA specification requires this, otherwise, the model would prevent accessing the entity persistent state fields directly from outside the entity itself.

Although Hibernate does not require it, it is recommended to follow the JavaBean conventions and define getters and setters for entity persistent attributes.
Nevertheless, you can still tell Hibernate to directly access the entity fields.

Attributes (whether fields or getters/setters) need not be declared public.
Hibernate can deal with attributes declared with the public, protected, package or private visibility.
Again, if wanting to use runtime proxy generation for lazy loading, the getter/setter should grant access to at least package visibility.

[[entity-pojo-identifier]]
==== Providing identifier attribute(s)

[IMPORTANT]
====
Historically, providing identifier attributes was considered optional.

However, not defining identifier attributes 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.

[NOTE]
====
We recommend that you declare consistently-named identifier attributes on persistent classes and that you use a wrapper (i.e., non-primitive) type (e.g. `Long` or `Integer`).
====

The placement of the `@Id` annotation marks the <<chapters/domain/access.adoc#access,persistence state access strategy>>.

[[entity-pojo-identifier-mapping-example]]
.Identifier mapping
====
[source,java]
----
include::{sourcedir-mapping}/identifier/SimpleEntityTest.java[tag=entity-pojo-identifier-mapping-example, indent=0]
----
====

Hibernate offers multiple identifier generation strategies, see the <<chapters/domain/identifiers.adoc#identifiers,Identifier Generators>> chapter for more about this topic.

[[entity-pojo-mapping]]
==== Mapping the entity

The main piece in mapping the entity is the {jpaJavadocUrlPrefix}Entity.html[`javax.persistence.Entity`] annotation.

The `@Entity` annotation defines just the {jpaJavadocUrlPrefix}Entity.html#name--[`name`] attribute which is used to give a specific entity name for use in JPQL queries.

By default, if the name attribute of the `@Entity` annotation is missing, the unqualified name of the entity class itself will be used as the entity name.

[IMPORTANT]
====
Because the entity name is given by the unqualified name of the class, Hibernate does not allow registering multiple entities with the same name even if the entity classes reside in different packages.

Without imposing this restriction, Hibernate would not know which entity class is referenced in a JPQL query if the unqualified entity name is associated with more then one entity classes.
====

In the following example, the entity name (e.g. `Book`) is given by the unqualified name of the entity class name.

[[entity-pojo-mapping-implicit-name-example]]
.`@Entity` mapping with an implicit name
====
[source,java]
----
include::{sourcedir-mapping}/identifier/Book.java[tag=entity-pojo-mapping-implicit-name-example, indent=0]
----
====

However, the entity name can also be set explicitly as illustrated by the following example.

[[entity-pojo-mapping-example]]
.`@Entity` mapping with an explicit name
====
[source,java]
----
include::{sourcedir-mapping}/identifier/SimpleEntityTest.java[tag=entity-pojo-mapping-example, indent=0]
----
====

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.

[[entity-pojo-table-mapping-example]]
.Simple `@Entity` with `@Table`
====
[source,java]
----
include::{sourcedir-mapping}/identifier/SimpleEntityTableTest.java[tag=entity-pojo-table-mapping-example, indent=0]
----
====

[[mapping-entity-table-catalog]]
===== Mapping the catalog of the associated table

Without specifying the catalog of the associated database table a given entity is mapped to, Hibernate will use the default catalog associated with the current database connection.

However, if your database hosts multiple catalogs, you can specify the catalog where a given table is located using the `catalog` attribute of the JPA {jpaJavadocUrlPrefix}Table.html[`@Table`] annotation.

Let's assume we are using MySQL and want to map a `Book` entity to the `book` table located in the `public` catalog
which looks as follows.

[[mapping-post-table-catalog-mysql-example]]
.The `book` table located in the `public` catalog
====
[source,sql]
----
include::{extrasdir}/entity/mapping-post-table-catalog-mysql-example.sql[]
----
====

Now, to map the `Book` entity to the `book` table in the `public` catalog we can use the `catalog` attribute of the `@Table` JPA annotation.

[[mapping-entity-table-catalog-mysql-example]]
.Specifying the database catalog using the `@Table` annotation
====
[source,java]
----
include::{sourcedir-mapping}/identifier/EntityTableCatalogTest.java[tag=mapping-entity-table-catalog-mysql-example, indent=0]
----
====

[[mapping-entity-table-schema]]
===== Mapping the schema of the associated table

Without specifying the schema of the associated database table a given entity is mapped to, Hibernate will use the default schema associated with the current database connection.

However, if your database supports schemas, you can specify the schema where a given table is located using the `schema` attribute of the JPA {jpaJavadocUrlPrefix}Table.html[`@Table`] annotation.

Let's assume we are using PostgreSQL and want to map a `Book` entity to the `book` table located in the `library` schema
which looks as follows.

[[mapping-post-table-schema-postgresql-example]]
.The `book` table located in the `library` schema
====
[source,sql]
----
include::{extrasdir}/entity/mapping-post-table-schema-postgresql-example.sql[]
----
====

Now, to map the `Book` entity to the `book` table in the `library` schema we can use the `schema` attribute of the `@Table` JPA annotation.

[[mapping-entity-table-catalog-mysql-example]]
.Specifying the database schema using the `@Table` annotation
====
[source,java]
----
include::{sourcedir-mapping}/identifier/EntityTableSchemaTest.java[tag=mapping-entity-table-schema-postgresql-example, indent=0]
----
====

[IMPORTANT]
====
The `schema` attribute of the `@Table` annotation works only if the underlying database supports schemas (e.g. PostgreSQL).

Therefore, if you're using MySQL or MariaDB, which do not support schemas natively (schemas being just an alias for catalog), you need to use the
`catalog` attribute, and not the `schema` one.
====

[[mapping-model-pojo-equalshashcode]]
==== Implementing `equals()` and `hashCode()`

[NOTE]
====
Much of the discussion in this section deals with the relation of an entity to a Hibernate Session, whether the entity is managed, transient or detached.
If you are unfamiliar with these topics, they are explained in the <<chapters/pc/PersistenceContext.adoc#pc,Persistence Context>> chapter.
====

Whether to implement `equals()` and `hashCode()` methods in your domain model, let alone how to implement them, is a surprisingly tricky discussion when it comes to ORM.

There is really just one absolute case: a class that acts as an identifier must implement equals/hashCode based on the id value(s).
Generally, this is pertinent for user-defined classes used as composite identifiers.
Beyond this one very specific use case and few others we will discuss below, you may want to consider not implementing equals/hashCode altogether.

So what's all the fuss? Normally, most Java objects provide a built-in `equals()` and `hashCode()` based on the object's identity, so each new object will be different from all others.
This is generally what you want in ordinary Java programming.
Conceptually, however, this starts to break down when you start to think about the possibility of multiple instances of a class representing the same data.

This is, in fact, exactly the case when dealing with data coming from a database.
Every time we load a specific `Person` from the database we would naturally get a unique instance.
Hibernate, however, works hard to make sure that does not happen within a given `Session`.
In fact, Hibernate guarantees equivalence of persistent identity (database row) and Java identity inside a particular session scope.
So if we ask a Hibernate `Session` to load that specific Person multiple times we will actually get back the same __instance__:

[[entity-pojo-identity-scope-example]]
.Scope of identity
====
[source,java]
----
include::{sourcedir-mapping}/identifier/SimpleEntityTest.java[tag=entity-pojo-identity-scope-example, indent=0]
----
====

Consider we have a `Library` parent entity which contains a `java.util.Set` of `Book` entities:

[[entity-pojo-set-mapping-example]]
.Library entity mapping
====
[source,java]
----
include::{sourcedir-mapping}/identifier/SimpleEntityTest.java[tag=entity-pojo-set-mapping-example, indent=0]
----
====

[[entity-pojo-set-identity-scope-example]]
.Set usage with Session-scoped identity
====
[source,java]
----
include::{sourcedir-mapping}/identifier/SimpleEntityTest.java[tag=entity-pojo-set-identity-scope-example, indent=0]
----
====

However, the semantic changes when we mix instances loaded from different Sessions:

[[entity-pojo-multi-session-identity-scope-example]]
.Mixed Sessions
====
[source,java]
----
include::{sourcedir-mapping}/identifier/SimpleEntityTest.java[tag=entity-pojo-multi-session-identity-scope-example, indent=0]
----

[source,java]
----
include::{sourcedir-mapping}/identifier/SimpleEntityTest.java[tag=entity-pojo-multi-session-set-identity-scope-example, indent=0]
----
====

Specifically, the outcome in this last example will depend on whether the `Book` class
implemented equals/hashCode, and, if so, how.

If the `Book` class did not override the default equals/hashCode,
then the two `Book` object references are not going to be equal since their references are different.

Consider yet another case:

[[entity-pojo-transient-set-identity-scope-example]]
.Sets with transient entities
====
[source,java]
----
include::{sourcedir-mapping}/identifier/SimpleEntityTest.java[tag=entity-pojo-transient-set-identity-scope-example, indent=0]
----
====

In cases where you will be dealing with entities outside of a Session (whether they be transient or detached),
especially in cases where you will be using them in Java collections,
you should consider implementing equals/hashCode.

A common initial approach is to use the entity's identifier attribute as the basis for equals/hashCode calculations:

[[entity-pojo-naive-equals-hashcode-example]]
.Naive equals/hashCode implementation
====
[source,java]
----
include::{sourcedir-mapping}/identifier/NaiveEqualsHashCodeEntityTest.java[tag=entity-pojo-naive-equals-hashcode-example, indent=0]
----
====

It turns out that this still breaks when adding transient instance of `Book` to a set as we saw in the last example:

[[entity-pojo-naive-equals-hashcode-persist-example]]
.Auto-generated identifiers with Sets and naive equals/hashCode
====
[source,java]
----
include::{sourcedir-mapping}/identifier/NaiveEqualsHashCodeEntityTest.java[tag=entity-pojo-naive-equals-hashcode-persist-example, indent=0]
----
====

The issue here is a conflict between the use of the generated identifier, the contract of `Set`, and the equals/hashCode implementations.
`Set` says that the equals/hashCode value for an object should not change while the object is part of the `Set`.
But that is exactly what happened here because the equals/hasCode are based on the (generated) id, which was not set until the JPA transaction is committed.

Note that this is just a concern when using generated identifiers.
If you are using assigned identifiers this will not be a problem, assuming the identifier value is assigned prior to adding to the `Set`.

Another option is to force the identifier to be generated and set prior to adding to the `Set`:

[[entity-pojo-naive-equals-hashcode-persist-force-flush-example]]
.Forcing the flush before adding to the Set
====
[source,java]
----
include::{sourcedir-mapping}/identifier/NaiveEqualsHashCodeEntityTest.java[tag=entity-pojo-naive-equals-hashcode-persist-force-flush-example, indent=0]
----
====

But this is often not feasible.

The final approach is to use a "better" equals/hashCode implementation, making use of a natural-id or business-key.

[[entity-pojo-natural-id-equals-hashcode-example]]
.Natural Id equals/hashCode
====
[source,java]
----
include::{sourcedir-mapping}/identifier/NaturalIdEqualsHashCodeEntityTest.java[tag=entity-pojo-natural-id-equals-hashcode-example, indent=0]
----
====

This time, when adding a `Book` to the `Library` `Set`, you can retrieve the `Book` even after it's being persisted:

[[entity-pojo-natural-id-equals-hashcode-persist-example]]
.Natural Id equals/hashCode persist example
====
[source,java]
----
include::{sourcedir-mapping}/identifier/NaturalIdEqualsHashCodeEntityTest.java[tag=entity-pojo-natural-id-equals-hashcode-persist-example, indent=0]
----
====

As you can see the question of equals/hashCode is not trivial, nor is there a one-size-fits-all solution.

[TIP]
====
Although using a natural-id is best for `equals` and `hashCode`, sometimes you only have the entity identifier that provides a unique constraint.

It's possible to use the entity identifier for equality check, but it needs a workaround:

- you need to provide a constant value for `hashCode` so that the hash code value does not change before and after the entity is flushed.
- you need to compare the entity identifier equality only for non-transient entities.
====

For details on mapping the identifier, see the <<chapters/domain/identifiers.adoc#identifiers,Identifiers>> chapter.

[[entity-sql-query-mapping]]
==== Mapping the entity to a SQL query

You can map an entity to a SQL query using the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Subselect.html[`@Subselect`] annotation.

[[mapping-Subselect-example]]
.`@Subselect` entity mapping
====
[source,java]
----
include::{sourcedir-mapping}/basic/SubselectTest.java[tag=mapping-Subselect-example,indent=0]
----
====

In the example above, the `Account` entity does not retain any balance since every account operation is registered as an `AccountTransaction`.
To find the `Account` balance, we need to query the `AccountSummary` which shares the same identifier with the `Account` entity.

However, the `AccountSummary` is not mapped to a physical table, but to an SQL query.

So, if we have the following `AccountTransaction` record, the `AccountSummary` balance will match the proper amount of money in this `Account`.

[[mapping-Subselect-entity-find-example]]
.Finding a `@Subselect` entity
====
[source,java]
----
include::{sourcedir-mapping}/basic/SubselectTest.java[tag=mapping-Subselect-entity-find-example,indent=0]
----
====

If we add a new `AccountTransaction` entity and refresh the `AccountSummary` entity, the balance is updated accordingly:

[[mapping-Subselect-refresh-find-example]]
.Refreshing a `@Subselect` entity
====
[source,java]
----
include::{sourcedir-mapping}/basic/SubselectTest.java[tag=mapping-Subselect-entity-refresh-example,indent=0]
----
====

[TIP]
====
The goal of the `@Synchronize` annotation in the `AccountSummary` entity mapping is to instruct Hibernate which database tables are needed by the
underlying `@Subselect` SQL query. This is because, unlike JPQL and HQL queries, Hibernate cannot parse the underlying native SQL query.

With the `@Synchronize` annotation in place,
when executing an HQL or JPQL which selects from the `AccountSummary` entity,
Hibernate will trigger a Persistence Context flush if there are pending `Account`, `Client` or `AccountTransaction` entity state transitions.
====

[[entity-proxy]]
==== Define a custom entity proxy

By default, when it needs to use a proxy instead of the actual POJO, Hibernate is going to use a Bytecode manipulation library like
https://jboss-javassist.github.io/javassist/[Javassist] or
https://bytebuddy.net/[Byte Buddy].

However, if the entity class is final, Javassist will not create a proxy and you will get a POJO even when you only need a proxy reference.
In this case, you could proxy an interface that this particular entity implements, as illustrated by the following example.

[[entity-proxy-interface-mapping]]
.Final entity class implementing the `Identifiable` interface
====
[source,java]
----
include::{sourcedir-proxy}/ProxyInterfaceTest.java[tag=entity-proxy-interface-mapping,indent=0]
----
====

The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Proxy.html[`@Proxy`]
annotation is used to specify a custom proxy implementation for the current annotated entity.

When loading the `Book` entity proxy, Hibernate is going to proxy the `Identifiable` interface instead as illustrated by the following example:

[[entity-proxy-persist-mapping]]
.Proxying the final entity class implementing the `Identifiable` interface
====
[source,java]
----
include::{sourcedir-proxy}/ProxyInterfaceTest.java[tag=entity-proxy-persist-mapping,indent=0]
----

[source,sql]
----
include::{extrasdir}/entity/entity-proxy-persist-mapping.sql[]
----
====

As you can see in the associated SQL snippet, Hibernate issues no SQL SELECT query since the proxy can be
constructed without needing to fetch the actual entity POJO.

[[entity-tuplizer]]
==== Dynamic entity proxies using the @Tuplizer annotation

It is possible to map your entities as dynamic proxies using
the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Tuplizer.html[`@Tuplizer`] annotation.

In the following entity mapping, both the embeddable and the entity are mapped as interfaces, not POJOs.

[[entity-tuplizer-entity-mapping]]
.Dynamic entity proxy mapping
====
[source,java]
----
include::{sourcedir-proxy}/tuplizer/Cuisine.java[tag=entity-tuplizer-entity-mapping,indent=0]
----

[source,java]
----
include::{sourcedir-proxy}/tuplizer/Country.java[tag=entity-tuplizer-entity-mapping,indent=0]
----
====

The `@Tuplizer` instructs Hibernate to use the `DynamicEntityTuplizer` and `DynamicEmbeddableTuplizer` to handle
the associated entity and embeddable object types.

Both the `Cuisine` entity and the `Country` embeddable types are going to be instantiated as Java dynamic proxies,
as you can see in the following `DynamicInstantiator` example:

[[entity-tuplizer-instantiator]]
.Instantiating entities and embeddables as dynamic proxies
====
[source,java]
----
include::{sourcedir-proxy}/tuplizer/DynamicEntityTuplizer.java[tag=entity-tuplizer-instantiator,indent=0]
----

[source,java]
----
include::{sourcedir-proxy}/tuplizer/DynamicEmbeddableTuplizer.java[tag=entity-tuplizer-instantiator,indent=0]
----

[source,java]
----
include::{sourcedir-proxy}/tuplizer/DynamicInstantiator.java[tag=entity-tuplizer-instantiator,indent=0]
----

[source,java]
----
include::{sourcedir-proxy}/tuplizer/ProxyHelper.java[tag=entity-tuplizer-instantiator,indent=0]
----

[source,java]
----
include::{sourcedir-proxy}/tuplizer/DataProxyHandler.java[tag=entity-tuplizer-instantiator,indent=0]
----
====

With the `DynamicInstantiator` in place, we can work with the dynamic proxy entities just like with POJO entities.

[[entity-tuplizer-dynamic-proxy-example]]
.Persisting entities and embeddables as dynamic proxies
====
[source,java]
----
include::{sourcedir-proxy}/tuplizer/TuplizerTest.java[tag=entity-tuplizer-dynamic-proxy-example,indent=0]
----
====

[[entity-persister]]
==== Define a custom entity persister

The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Persister.html[`@Persister`] annotation is used to specify a custom entity or collection persister.

For entities, the custom persister must implement the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/persister/entity/EntityPersister.html[`EntityPersister`] interface.

For collections, the custom persister must implement the https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/persister/collection/CollectionPersister.html[`CollectionPersister`] interface.

[[entity-persister-mapping]]
.Entity persister mapping
====
[source,java]
----
include::{sourcedir-persister}/Author.java[tag=entity-persister-mapping,indent=0]
----

[source,java]
----
include::{sourcedir-persister}/Book.java[tag=entity-persister-mapping,indent=0]
----
====

By providing your own `EntityPersister` and `CollectionPersister` implementations,
you can control how entities and collections are persisted into the database.