[[embeddables]]
=== Embeddable types
:sourcedir: ../../../../../test/java/org/hibernate/userguide/mapping/embeddable
:extrasdir: extras

Historically Hibernate called these components.
JPA calls them embeddables.
Either way, the concept is the same: a composition of values.

For example, we might have a `Publisher` class that is a composition of `name` and `country`,
or a `Location` class that is a composition of `country` and `city`.

.Usage of the word _embeddable_
[NOTE]
====
To avoid any confusion with the annotation that marks a given embeddable type, the annotation will be further referred to as `@Embeddable`.

Throughout this chapter and thereafter, for brevity sake, embeddable types may also be referred to as _embeddable_.
====

[[embeddable-type-mapping-example]]
.Embeddable type example
====
[source,java]
----
include::{sourcedir}/NestedEmbeddableTest.java[tag=embeddable-type-mapping-example, indent=0]
----
====

An embeddable type is another form of a value type, and its lifecycle is bound to a parent entity type, therefore inheriting the attribute access from its parent (for details on attribute access, see <<chapters/domain/entity.adoc#access-embeddable-types,Access strategies>>).

Embeddable types can be made up of basic values as well as associations, with the caveat that, when used as collection elements, they cannot define collections themselves.

==== Component / Embedded

Most often, embeddable types are used to group multiple basic type mappings and reuse them across several entities.

[[simple-embeddable-type-mapping-example]]
.Simple Embeddable
====
[source,java]
----
include::{sourcedir}/SimpleEmbeddableTest.java[tag=embeddable-type-mapping-example, indent=0]
----

[source,sql]
----
include::{extrasdir}/embeddable/simple-embeddable-type-mapping-example.sql[]
----
====

[NOTE]
====
JPA defines two terms for working with an embeddable type: `@Embeddable` and `@Embedded`.

`@Embeddable` is used to describe the mapping type itself (e.g. `Publisher`).

`@Embedded` is for referencing a given embeddable type (e.g. `book.publisher`).
====

So, the embeddable type is represented by the `Publisher` class and
the parent entity makes use of it through the `book#publisher` object composition.

The composed values are mapped to the same table as the parent table.
Composition is part of good object-oriented data modeling (idiomatic Java).
In fact, that table could also be mapped by the following entity type instead.

[[alternative-to-embeddable-type-mapping-example]]
.Alternative to embeddable type composition
====
[source,java]
----
include::{sourcedir}/SimpleEmbeddableEquivalentTest.java[tag=embeddable-type-mapping-example, indent=0]
----
====

The composition form is certainly more object-oriented, and that becomes more evident as we work with multiple embeddable types.

[[embeddable-multiple]]
==== Multiple embeddable types

Although from an object-oriented perspective, it's much more convenient to work with embeddable types, this example doesn't work as-is.
When the same embeddable type is included multiple times in the same parent entity type, the JPA specification demands to set the associated column names explicitly.

This requirement is due to how object properties are mapped to database columns.
By default, JPA expects a database column having the same name with its associated object property.
When including multiple embeddables, the implicit name-based mapping rule doesn't work anymore because multiple object properties could end-up being mapped to the same database column.

We have a few options to handle this issue.

[[embeddable-override]]
==== Overriding Embeddable types

JPA defines the `@AttributeOverride` annotation to handle this scenario.
This way, the mapping conflict is resolved by setting up explicit name-based property-column type mappings.

If an Embeddable type is used multiple times in some entity, you need to use the
https://javaee.github.io/javaee-spec/javadocs/javax/persistence/AttributeOverride.html[`@AttributeOverride`] and
https://javaee.github.io/javaee-spec/javadocs/javax/persistence/AssociationOverride.html[`@AssociationOverride`] annotations
to override the default column names defined by the Embeddable.

Considering you have the following `Publisher` embeddable type
which defines a `@ManyToOne` association with the `Country` entity:

[[embeddable-type-association-mapping-example]]
.Embeddable type with a `@ManyToOne` association
====
[source,java]
----
include::{sourcedir}/EmbeddableOverrideTest.java[tag=embeddable-type-association-mapping-example, indent=0]
----

[source,sql]
----
include::{extrasdir}/embeddable/embeddable-type-association-mapping-example.sql[]
----
====

Now, if you have a `Book` entity which declares two `Publisher` embeddable types for the ebook and paperback versions,
you cannot use the default `Publisher` embeddable mapping since there will be a conflict between the two embeddable column mappings.

Therefore, the `Book` entity needs to override the embeddable type mappings for each `Publisher` attribute:

[[embeddable-type-override-mapping-example]]
.Overriding embeddable type attributes
====
[source,java]
----
include::{sourcedir}/EmbeddableOverrideTest.java[tag=embeddable-type-override-mapping-example, indent=0]
----

[source,sql]
----
include::{extrasdir}/embeddable/embeddable-type-override-mapping-example.sql[]
----
====

[[embeddable-multiple-namingstrategy]]
==== Embeddables and ImplicitNamingStrategy

[IMPORTANT]
====
The `ImplicitNamingStrategyComponentPathImpl` is a Hibernate-specific feature.
Users concerned with JPA provider portability should instead prefer explicit column naming with `@AttributeOverride`.
====

Hibernate naming strategies are covered in detail in <<chapters/domain/naming.adoc#naming,Naming>>.
However, for the purposes of this discussion, Hibernate has the capability to interpret implicit column names in a way that is safe for use with multiple embeddable types.

[[embeddable-multiple-namingstrategy-entity-mapping]]
.Implicit multiple embeddable type mapping
====
[source,java]
----
include::{sourcedir}/EmbeddableImplicitOverrideTest.java[tag=embeddable-multiple-namingstrategy-entity-mapping, indent=0]
----
====

To make it work, you need to use the `ImplicitNamingStrategyComponentPathImpl` naming strategy.

[[embeddable-multiple-ImplicitNamingStrategyComponentPathImpl]]
.Enabling implicit embeddable type mapping using the component path naming strategy
====
[source,java]
----
include::{sourcedir}/EmbeddableImplicitOverrideTest.java[tag=embeddable-multiple-ImplicitNamingStrategyComponentPathImpl, indent=0]
----
====

Now the "path" to attributes are used in the implicit column naming:

[source,sql]
----
include::{extrasdir}/embeddable/embeddable-multiple-namingstrategy-entity-mapping.sql[]
----

You could even develop your own naming strategy to do other types of implicit naming strategies.

[[embeddable-collections]]
==== Collections of embeddable types

Collections of embeddable types are specifically valued collections (as embeddable types are value types).
Value collections are covered in detail in <<chapters/domain/collections.adoc#collections-value,Collections of value types>>.

[[embeddable-mapkey]]
==== Embeddable type as a Map key

Embeddable types can also be used as `Map` keys.
This topic is converted in detail in <<chapters/domain/collections.adoc#collections-map,Map - key>>.

[[embeddable-identifier]]
==== Embeddable type as identifier

Embeddable types can also be used as entity type identifiers.
This usage is covered in detail in <<chapters/domain/identifiers.adoc#identifiers-composite,Composite identifiers>>.

[IMPORTANT]
====
Embeddable types that are used as collection entries, map keys or entity type identifiers cannot include their own collection mappings.
====

[[embeddable-Target]]
==== `@Target` mapping

The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Target.html[`@Target`] annotation is used to specify the implementation class of a given association that is mapped via an interface.
The
https://javaee.github.io/javaee-spec/javadocs/javax/persistence/ManyToOne.html[`@ManyToOne`],
https://javaee.github.io/javaee-spec/javadocs/javax/persistence/OneToOne.html[`@OneToOne`],
https://javaee.github.io/javaee-spec/javadocs/javax/persistence/OneToMany.html[`@OneToMany`], and
https://javaee.github.io/javaee-spec/javadocs/javax/persistence/ManyToMany.html[`@ManyToMany`]
feature a https://javaee.github.io/javaee-spec/javadocs/javax/persistence/ManyToOne.html#targetEntity--[`targetEntity`] attribute to specify the actual class of the entity association when an interface is used for the mapping.

The https://javaee.github.io/javaee-spec/javadocs/javax/persistence/ElementCollection.html[`@ElementCollection`] association has a https://javaee.github.io/javaee-spec/javadocs/javax/persistence/ElementCollection.html#targetClass--[`targetClass`] attribute for the same purpose.

However, for simple embeddable types, there is no such construct and so you need to use the Hibernate-specific `@Target` annotation instead.

[[embeddable-Target-example]]
.`@Target` mapping usage
====
[source, JAVA, indent=0]
----
include::{sourcedir}/TargetTest.java[tags=embeddable-Target-example]
----
====

The `coordinates` embeddable type is mapped as the `Coordinates` interface.
However, Hibernate needs to know the actual implementation tye, which is `GPS` in this case,
hence the `@Target` annotation is used to provide this information.

Assuming we have persisted the following `City` entity:

[[embeddable-Target-persist-example]]
.`@Target` persist example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/TargetTest.java[tags=embeddable-Target-persist-example]
----
====

When fetching the `City` entity, the `coordinates` property is mapped by the `@Target` expression:

[[embeddable-Target-fetching-example]]
.`@Target` fetching example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/TargetTest.java[tags=embeddable-Target-fetching-example]
----

[source, SQL, indent=0]
----
include::{extrasdir}/embeddable/embeddable-Target-fetching-example.sql[]
----
====

Therefore, the `@Target` annotation is used to define a custom join association between the parent-child association.

[[embeddable-Parent]]
==== `@Parent` mapping

The Hibernate-specific `@Parent` annotation allows you to reference the owner entity from within an embeddable.

[[embeddable-Parent-example]]
.`@Parent` mapping usage
====
[source, JAVA, indent=0]
----
include::{sourcedir}/ParentTest.java[tags=embeddable-Parent-example]
----
====

Assuming we have persisted the following `City` entity:

[[embeddable-Parent-persist-example]]
.`@Parent` persist example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/ParentTest.java[tags=embeddable-Parent-persist-example]
----
====

When fetching the `City` entity, the `city` property of the embeddable type acts as a back reference to the owning parent entity:

[[embeddable-Parent-fetching-example]]
.`@Parent` fetching example
====
[source, JAVA, indent=0]
----
include::{sourcedir}/ParentTest.java[tags=embeddable-Parent-fetching-example]
----
====

Therefore, the `@Parent` annotation is used to define the association between an embeddable type and the owning entity.
