HHH-11290 - Migrate all documentation snippets that derive the source code from extras instead of actual Unit Tests

Fixed in the Embeddable chapter
This commit is contained in:
Vlad Mihalcea 2017-06-29 10:55:22 +03:00
parent c39a337418
commit c42df6a11b
17 changed files with 739 additions and 285 deletions

View File

@ -6,7 +6,9 @@
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.
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]
@ -16,16 +18,12 @@ To avoid any confusion with the annotation that marks a given embeddable type, t
Throughout this chapter and thereafter, for brevity sake, embeddable types may also be referred as _embeddable_.
====
.Simple embeddable type example
[[embeddable-type-mapping-example]]
.Embeddable type example
====
[source,java]
----
include::{extrasdir}/embeddable/Name.java[]
----
[source,java]
----
include::{extrasdir}/embeddable/Address.java[]
include::{sourcedir}/NestedEmbeddableTest.java[tag=embeddable-type-mapping-example, indent=0]
----
====
@ -37,40 +35,42 @@ Embeddable types can be made up of basic values as well as associations, with th
Most often, embeddable types are used to group multiple basic type mappings and reuse them across several entities.
[[simple-embeddable-type-mapping-example]]
.Simple Embeddedable
====
[source,java]
----
include::{extrasdir}/embeddable/Person.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. `Name`).
`@Embedded` is for referencing a given embeddable type (e.g. `person.name`).
`@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 `Name` class and the parent makes use of it through the `person.name` object composition.
.Person table
====
[source,sql]
----
include::{extrasdir}/embeddable/Person1.sql[]
----
====
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 OO data modeling (idiomatic Java).
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::{extrasdir}/embeddable/Person_alt.java[]
include::{sourcedir}/SimpleEmbeddableEquivalentTest.java[tag=embeddable-type-mapping-example, indent=0]
----
====
@ -79,14 +79,6 @@ The composition form is certainly more Object-oriented, and that becomes more ev
[[embeddable-multiple]]
==== Multiple embeddable types
.Multiple embeddable types
====
[source,java]
----
include::{extrasdir}/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.
@ -96,77 +88,12 @@ When including multiple embeddables, the implicit name-based mapping rule doesn'
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::{extrasdir}/embeddable/Contact-AttributeOverride.java[]
----
====
This way, the mapping conflict is resolved by setting up explicit name-based property-column type mappings.
[[embeddable-multiple-namingstrategy]]
==== Embeddables and 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::{extrasdir}/embeddable/component-safe-implicit-naming.java[]
----
====
====
[source,sql]
----
include::{extrasdir}/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.
====
[[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 Embeddabe type is used multiple times in some entity, you need to use the
http://docs.oracle.com/javaee/7/api/javax/persistence/AttributeOverride.html[`@AttributeOverride`] and
http://docs.oracle.com/javaee/7/api/javax/persistence/AssociationOverride.html[`@AssociationOverride`] annotations
@ -208,4 +135,66 @@ include::{extrasdir}/embeddable/embeddable-type-override-mapping-example.sql[]
----
====
[[embeddable-multiple-namingstrategy]]
==== Embeddables and ImplicitNamingStrategy
[IMPORTANT]
====
This 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 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.
====

View File

@ -1,22 +0,0 @@
@Embeddable
public class Address {
private String line1;
private String line2;
@Embedded
private ZipCode zipCode;
...
@Embeddable
public static class ZipCode {
private String postalCode;
private String plus4;
...
}
}

View File

@ -1,74 +0,0 @@
@Entity
public class Contact {
@Id
private Integer id;
@Embedded
private Name name;
@Embedded
@AttributeOverrides(
@AttributeOverride(
name = "line1",
column = @Column( name = "home_address_line1" ),
),
@AttributeOverride(
name = "line2",
column = @Column( name = "home_address_line2" )
),
@AttributeOverride(
name = "zipCode.postalCode",
column = @Column( name = "home_address_postal_cd" )
),
@AttributeOverride(
name = "zipCode.plus4",
column = @Column( name = "home_address_postal_plus4" )
)
)
private Address homeAddress;
@Embedded
@AttributeOverrides(
@AttributeOverride(
name = "line1",
column = @Column( name = "mailing_address_line1" ),
),
@AttributeOverride(
name = "line2",
column = @Column( name = "mailing_address_line2" )
),
@AttributeOverride(
name = "zipCode.postalCode",
column = @Column( name = "mailing_address_postal_cd" )
),
@AttributeOverride(
name = "zipCode.plus4",
column = @Column( name = "mailing_address_postal_plus4" )
)
)
private Address mailingAddress;
@Embedded
@AttributeOverrides(
@AttributeOverride(
name = "line1",
column = @Column( name = "work_address_line1" ),
),
@AttributeOverride(
name = "line2",
column = @Column( name = "work_address_line2" )
),
@AttributeOverride(
name = "zipCode.postalCode",
column = @Column( name = "work_address_postal_cd" )
),
@AttributeOverride(
name = "zipCode.plus4",
column = @Column( name = "work_address_postal_plus4" )
)
)
private Address workAddress;
...
}

View File

@ -1,19 +0,0 @@
create table Contact(
id integer not null,
name_firstName VARCHAR,
name_middleName VARCHAR,
name_lastName VARCHAR,
homeAddress_line1 VARCHAR,
homeAddress_line2 VARCHAR,
homeAddress_zipCode_postalCode VARCHAR,
homeAddress_zipCode_plus4 VARCHAR,
mailingAddress_line1 VARCHAR,
mailingAddress_line2 VARCHAR,
mailingAddress_zipCode_postalCode VARCHAR,
mailingAddress_zipCode_plus4 VARCHAR,
workAddress_line1 VARCHAR,
workAddress_line2 VARCHAR,
workAddress_zipCode_postalCode VARCHAR,
workAddress_zipCode_plus4 VARCHAR,
...
)

View File

@ -1,20 +0,0 @@
@Entity
public class Contact {
@Id
private Integer id;
@Embedded
private Name name;
@Embedded
private Address homeAddress;
@Embedded
private Address mailingAddress;
@Embedded
private Address workAddress;
...
}

View File

@ -1,11 +0,0 @@
@Embeddable
public class Name {
private String firstName;
private String middleName;
private String lastName;
...
}

View File

@ -1,11 +0,0 @@
@Entity
public class Person {
@Id
private Integer id;
@Embedded
private Name name;
...
}

View File

@ -1,7 +0,0 @@
create table Person (
id integer not null,
firstName VARCHAR,
middleName VARCHAR,
lastName VARCHAR,
...
)

View File

@ -1,14 +0,0 @@
@Entity
public class Person {
@Id
private Integer id;
private String firstName;
private String middleName;
private String lastName;
...
}

View File

@ -1,8 +0,0 @@
MetadataSources sources = ...;
sources.addAnnotatedClass( Address.class );
sources.addAnnotatedClass( Name.class );
sources.addAnnotatedClass( Contact.class );
Metadata metadata = sources.getMetadataBuilder().applyImplicitNamingStrategy( ImplicitNamingStrategyComponentPathImpl.INSTANCE )
...
.build();

View File

@ -0,0 +1,10 @@
create table Book (
id bigint not null,
author varchar(255),
ebookPublisher_name varchar(255),
paperBackPublisher_name varchar(255),
title varchar(255),
ebookPublisher_country_id bigint,
paperBackPublisher_country_id bigint,
primary key (id)
)

View File

@ -0,0 +1,8 @@
create table Book (
id bigint not null,
author varchar(255),
publisher_country varchar(255),
publisher_name varchar(255),
title varchar(255),
primary key (id)
)

View File

@ -0,0 +1,203 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.userguide.mapping.embeddable;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import org.hibernate.annotations.NaturalId;
import org.hibernate.boot.MetadataBuilder;
import org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
/**
* @author Vlad Mihalcea
*/
public class EmbeddableImplicitOverrideTest
extends BaseNonConfigCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Book.class,
Country.class
};
}
@Override
protected void initialize(MetadataBuilder metadataBuilder) {
super.initialize( metadataBuilder );
//tag::embeddable-multiple-ImplicitNamingStrategyComponentPathImpl[]
metadataBuilder.applyImplicitNamingStrategy(
ImplicitNamingStrategyComponentPathImpl.INSTANCE
);
//end::embeddable-multiple-ImplicitNamingStrategyComponentPathImpl[]
}
@Test
public void testLifecycle() {
doInHibernate( this::sessionFactory, session -> {
Country canada = new Country();
canada.setName( "Canada" );
session.persist( canada );
Country usa = new Country();
usa.setName( "USA" );
session.persist( usa );
} );
doInHibernate( this::sessionFactory, session -> {
Country canada = session.byNaturalId( Country.class ).using( "name", "Canada" ).load();
Country usa = session.byNaturalId( Country.class ).using( "name", "USA" ).load();
Book book = new Book();
book.setTitle( "High-Performance Java Persistence" );
book.setAuthor( "Vlad Mihalcea" );
book.setEbookPublisher( new Publisher( "Leanpub", canada ) );
book.setPaperBackPublisher( new Publisher( "Amazon", usa ) );
session.persist( book );
} );
}
//tag::embeddable-multiple-namingstrategy-entity-mapping[]
@Entity(name = "Book")
public static class Book {
@Id
@GeneratedValue
private Long id;
private String title;
private String author;
private Publisher ebookPublisher;
private Publisher paperBackPublisher;
//Getters and setters are omitted for brevity
//end::embeddable-multiple-namingstrategy-entity-mapping[]
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Publisher getEbookPublisher() {
return ebookPublisher;
}
public void setEbookPublisher(Publisher ebookPublisher) {
this.ebookPublisher = ebookPublisher;
}
public Publisher getPaperBackPublisher() {
return paperBackPublisher;
}
public void setPaperBackPublisher(Publisher paperBackPublisher) {
this.paperBackPublisher = paperBackPublisher;
}
//tag::embeddable-multiple-namingstrategy-entity-mapping[]
}
@Embeddable
public static class Publisher {
private String name;
@ManyToOne(fetch = FetchType.LAZY)
private Country country;
public Publisher(String name, Country country) {
this.name = name;
this.country = country;
}
private Publisher() {}
//Getters and setters are omitted for brevity
//end::embeddable-multiple-namingstrategy-entity-mapping[]
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
//tag::embeddable-multiple-namingstrategy-entity-mapping[]
}
@Entity(name = "Country")
public static class Country {
@Id
@GeneratedValue
private Long id;
@NaturalId
private String name;
//Getters and setters are omitted for brevity
//end::embeddable-multiple-namingstrategy-entity-mapping[]
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//tag::embeddable-multiple-namingstrategy-entity-mapping[]
}
//end::embeddable-multiple-namingstrategy-entity-mapping[]
}

View File

@ -0,0 +1,175 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.userguide.mapping.embeddable;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
/**
* @author Vlad Mihalcea
*/
public class NestedEmbeddableTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Book.class
};
}
@Test
public void testLifecycle() {
doInJPA( this::entityManagerFactory, entityManager -> {
Book book = new Book();
book.setTitle( "High-Performance Java Persistence" );
book.setAuthor( "Vlad Mihalcea" );
book.setPublisher(
new Publisher(
"Amazon",
new Location(
"USA",
"Seattle"
)
)
);
entityManager.persist( book );
} );
}
@Entity(name = "Book")
public static class Book {
@Id
@GeneratedValue
private Long id;
private String title;
private String author;
private Publisher publisher;
//Getters and setters are omitted for brevity
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Publisher getPublisher() {
return publisher;
}
public void setPublisher(Publisher publisher) {
this.publisher = publisher;
}
}
//tag::embeddable-type-mapping-example[]
@Embeddable
public static class Publisher {
private String name;
private Location location;
public Publisher(String name, Location location) {
this.name = name;
this.location = location;
}
private Publisher() {}
//Getters and setters are omitted for brevity
//end::embeddable-type-mapping-example[]
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
//tag::embeddable-type-mapping-example[]
}
@Embeddable
public static class Location {
private String country;
private String city;
public Location(String country, String city) {
this.country = country;
this.city = city;
}
private Location() {}
//Getters and setters are omitted for brevity
//end::embeddable-type-mapping-example[]
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
//tag::embeddable-type-mapping-example[]
}
//end::embeddable-type-mapping-example[]
}

View File

@ -0,0 +1,113 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.userguide.mapping.embeddable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
/**
* @author Vlad Mihalcea
*/
public class SimpleEmbeddableEquivalentTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Book.class
};
}
@Test
public void testLifecycle() {
doInJPA( this::entityManagerFactory, entityManager -> {
Book book = new Book();
book.setTitle( "High-Performance Java Persistence" );
book.setAuthor( "Vlad Mihalcea" );
book.setPublisherName("Amazon");
book.setPublisherCountry("USA");
entityManager.persist( book );
} );
}
//tag::embeddable-type-mapping-example[]
@Entity(name = "Book")
public static class Book {
@Id
@GeneratedValue
private Long id;
private String title;
private String author;
@Column(name = "publisher_name")
private String publisherName;
@Column(name = "publisher_country")
private String publisherCountry;
//Getters and setters are omitted for brevity
//end::embeddable-type-mapping-example[]
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getPublisherName() {
return publisherName;
}
public void setPublisherName(String publisherName) {
this.publisherName = publisherName;
}
public String getPublisherCountry() {
return publisherCountry;
}
public void setPublisherCountry(String publisherCountry) {
this.publisherCountry = publisherCountry;
}
//tag::embeddable-type-mapping-example[]
}
//end::embeddable-type-mapping-example[]
}

View File

@ -0,0 +1,142 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.userguide.mapping.embeddable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
/**
* @author Vlad Mihalcea
*/
public class SimpleEmbeddableTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Book.class
};
}
@Test
public void testLifecycle() {
doInJPA( this::entityManagerFactory, entityManager -> {
Book book = new Book();
book.setTitle( "High-Performance Java Persistence" );
book.setAuthor( "Vlad Mihalcea" );
book.setPublisher(
new Publisher(
"Amazon",
"USA"
)
);
entityManager.persist( book );
} );
}
//tag::embeddable-type-mapping-example[]
@Entity(name = "Book")
public static class Book {
@Id
@GeneratedValue
private Long id;
private String title;
private String author;
private Publisher publisher;
//Getters and setters are omitted for brevity
//end::embeddable-type-mapping-example[]
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Publisher getPublisher() {
return publisher;
}
public void setPublisher(Publisher publisher) {
this.publisher = publisher;
}
//tag::embeddable-type-mapping-example[]
}
@Embeddable
public static class Publisher {
@Column(name = "publisher_name")
private String name;
@Column(name = "publisher_country")
private String country;
public Publisher(String name, String country) {
this.name = name;
this.country = country;
}
private Publisher() {}
//Getters and setters are omitted for brevity
//end::embeddable-type-mapping-example[]
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
//tag::embeddable-type-mapping-example[]
}
//end::embeddable-type-mapping-example[]
}

View File

@ -296,7 +296,7 @@ public class BaseNonConfigCoreFunctionalTestCase extends BaseUnitTestCase {
protected void afterMetadataSourcesApplied(MetadataSources metadataSources) {
}
private void initialize(MetadataBuilder metadataBuilder) {
protected void initialize(MetadataBuilder metadataBuilder) {
metadataBuilder.enableNewIdentifierGeneratorSupport( true );
metadataBuilder.applyImplicitNamingStrategy( ImplicitNamingStrategyLegacyJpaImpl.INSTANCE );
}