liveBook · Manning

Embeddable type

As explained in Java Persistence with Spring Data and Hibernate epub

The @Embeddable annotation declares that a Java class defines a JPA embeddable type whose state can be mapped into an owning persistent class.

An embeddable type groups related values in a Java class without giving that class its own persistence identity. Mark the class @Embeddable, then use it as a property of an entity. Its state belongs to the owning class: an Address property on a User maps its street, zipcode, and city to columns of the USERS table, rather than requiring an Address identifier. section 6.2.2

Listing 6.7 Address class: An embeddable component
Path: Ch06/mapping-value-types/src/main/java/com/manning/javapersistence
 /ch06/model/Address.java
 
@Embeddable                                                               #1
public class Address {
    @NotNull                                                              #2
    @Column(nullable = false)                                             #3
    private String street;
 
    @NotNull
    @Column(nullable = false, length = 5)                                 #4
    private String zipcode;
 
    @NotNull                                                              #5
    @Column(nullable = false)                                             #5
    private String city;                                                  #5
 
    public Address() {                                                    #6
    }
 
    public Address(String street, String zipcode, String city) {          #7
        this.street = street;
        this.zipcode = zipcode;
        this.city = city;
    }
    //getters and setters
}
#1 Instead of <kbd>@Entity</kbd>, this component POJO is marked with <kbd>@Embeddable</kbd>. It has no identifier property.
#2 The <kbd>@NotNull</kbd> annotation is ignored by the DDL generation.
#3 <kbd>@Column(nullable=false)</kbd> is used for DDL generation.
#4 The length argument of the <kbd>@Column</kbd> annotation will override the default generation of a column as <kbd>VARCHAR(255)</kbd>.
#5 The type of the <kbd>city</kbd> column will by default be <kbd>VARCHAR(255)</kbd>.
#6 Hibernate or Spring Data JPA using Hibernate call this no-argument constructor to create an instance and then populate the fields directly.
#7 We can have additional (public) constructors for convenience.

The Address listing shows @Embeddable on a POJO and @Column settings on its persistent fields. section 6.2.2

An embeddable’s properties are persistent by default, just like an entity’s properties. Use familiar mappings such as @Basic and @Column to adjust them. When a property’s class is @Embeddable, the owner need not annotate that property @Embedded; @Embedded can also mark a property for embedding. Embeddable components inherit their owner’s field- or property-access strategy, so place mapping annotations consistently with that strategy. section 6.1 section 6.2.2

An address on a user

Declare `@Embeddable class Address` with `street`, `zipcode`, and `city` fields, and give `@Entity class User` a `private Address homeAddress` field. With the Address class annotated, that field needs no additional embedding annotation. For a required database column, use `@Column(nullable = false)`: in the described Hibernate Validator setup, `@NotNull` alone validates at runtime but does not generate a NOT NULL schema constraint for an embeddable property. section 6.2.2

Composition can continue inside an embeddable. If Address contains an embeddable City, all their embedded properties still map to columns of the owning User table. Use @AttributeOverride to adapt a nested property’s column mapping; an override on the root entity can address it with a dotted path such as `city.name`. A converter offers a different mapping choice when a value must occupy one database column: a MonetaryAmount mapped by a converter can instead become @Embeddable when the schema offers separate amount and currency columns. section 6.2.4 section 6.3.2

Embeddables can also serve as collection values or map keys through @ElementCollection. For an embeddable map key, its mapped columns participate in the collection table’s composite primary key and cannot be nullable; implement equals() and hashCode() so keys compare by value. Choose this mapping when a value is a useful domain object, not when it needs an independent entity identifier. section 8.2.4 section 8.2.5

How Java Persistence with Spring Data and Hibernate epub covers it

How deep it goes
Works through annotations, default persistence, column placement, inherited access, nested overrides, and collection-key constraints; entity references receive only a brief mention.
Examples
Uses an address embedded in a user, a nested city, monetary amounts, and image collections keyed by filenames.
What it assumes
Assumes Java classes and basic entity mapping while explaining how an embeddable differs from an entity with an identifier.
What you can do after
Build it from scratch: define an embeddable, map it into an owner, override nested columns, and account for collection-key equality.
How it connects
Connects entity mapping, value types, nested composition, attribute overrides, attribute converters, and element collections.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Java Persistence with Spring Data and Hibernate epub. The section links point to the parts of the book it draws on.