[[embeddables]]
=== Embeddable types
:sourcedir: 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 Name class that is a composition of first-name and last-name, or an Address class that is a composition of street, city, postal code, etc.

.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 as `@Embeddable`.

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

.Simple embeddable type example
====
[source,java]
----
include::{sourcedir}/embeddable/Name.java[]
----

[source,java]
----
include::{sourcedir}/embeddable/Address.java[]
----
====

An embeddable type is another form of 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 Embeddedable
====
[source,java]
----
include::{sourcedir}/embeddable/Person.java[]
----
====

[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. `Name`).
`@Embedded` is for referencing a given embeddable type (e.g. `person.name`).
====

So, the embeddable type is represented by the `Name` class and the parent makes use of it through the `person.name` object composition.

.Person table
====
[source,sql]
----
include::{sourcedir}/embeddable/Person1.sql[]
----
====

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

.Alternative to embeddable type composition
====
[source,java]
----
include::{sourcedir}/embeddable/Person_alt.java[]
----
====

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

.Multiple embeddable types
====
[source,java]
----
include::{sourcedir}/embeddable/Contact.java[]
----
====

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 setting 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-multiple-jpa]]
==== JPA's AttributeOverride

JPA defines the `@AttributeOverride` annotation to handle this scenario.

.JPA's AttributeOverride
====
[source,java]
----
include::{sourcedir}/embeddable/Contact-AttributeOverride.java[]
----
====

This way, the mapping conflict is resolved by setting up explicit name-based property-column type mappings.

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

[IMPORTANT]
====
This is a Hibernate specific feature.
Users concerned with JPA provider portability should instead prefer explicit column naming with <<embeddable-multiple-jpa,`@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.

.Enabling embeddable type safe implicit naming
====
[source,java]
----
include::{sourcedir}/embeddable/component-safe-implicit-naming.java[]
----
====

====
[source,sql]
----
include::{sourcedir}/embeddable/Contact-ImplicitNamingStrategy.sql[]
----
====

Now the "path" to attributes are used in the implicit column naming.
You could even develop your own to do special implicit naming.

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

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

[[embeddable-mapkey]]
==== Embeddable types as 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 types as identifiers

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.
====