diff --git a/documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc b/documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc index 9fd2738257..54d8440bd4 100644 --- a/documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc +++ b/documentation/src/main/asciidoc/userguide/appendices/Annotations.adoc @@ -1099,7 +1099,7 @@ like <>, <> section for more info. [[annotations-hibernate-persister]] ==== `@Persister` diff --git a/documentation/src/main/asciidoc/userguide/chapters/domain/basic_types.adoc b/documentation/src/main/asciidoc/userguide/chapters/domain/basic_types.adoc index ef2d53c58d..02cac15d92 100644 --- a/documentation/src/main/asciidoc/userguide/chapters/domain/basic_types.adoc +++ b/documentation/src/main/asciidoc/userguide/chapters/domain/basic_types.adoc @@ -2069,7 +2069,7 @@ include::{sourcedir}/basic/TargetTest.java[tags=mapping-Target-persist-example] When fetching the `City` entity, the `coordinates` property is mapped by the `@Target` expression: [[mapping-Target-fetching-example]] -.`@Target` mapping usage +.`@Target` fetching example ==== [source, JAVA, indent=0] ---- @@ -2083,3 +2083,41 @@ include::{extrasdir}/basic/mapping-Target-fetching-example.sql[] ==== Therefore, the `@Target` annotation is used to define a custom join association between the parent-child association. + +[[mapping-Parent]] +==== `@Parent` mapping + +The Hibernate-specific `@Parent` annotation allows you to reference the owner entity from within an embeddable. + +[[mapping-Parent-example]] +.`@Parent` mapping usage +==== +[source, JAVA, indent=0] +---- +include::{sourcedir}/basic/ParentTest.java[tags=mapping-Parent-example] +---- +==== + +Assuming we have persisted the following `City` entity: + +[[mapping-Parent-persist-example]] +.`@Parent` persist example +==== +[source, JAVA, indent=0] +---- +include::{sourcedir}/basic/ParentTest.java[tags=mapping-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: + +[[mapping-Parent-fetching-example]] +.`@Parent` fetching example +==== +[source, JAVA, indent=0] +---- +include::{sourcedir}/basic/ParentTest.java[tags=mapping-Parent-fetching-example] +---- +==== + +Therefore, the `@Parent` annotation is used to define the association between an embeddable type and the owning entity. \ No newline at end of file diff --git a/documentation/src/test/java/org/hibernate/userguide/mapping/basic/ParentTest.java b/documentation/src/test/java/org/hibernate/userguide/mapping/basic/ParentTest.java new file mode 100644 index 0000000000..178b8523a5 --- /dev/null +++ b/documentation/src/test/java/org/hibernate/userguide/mapping/basic/ParentTest.java @@ -0,0 +1,137 @@ +/* + * 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 . + */ +package org.hibernate.userguide.mapping.basic; + +import javax.persistence.Embeddable; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +import org.hibernate.annotations.Parent; +import org.hibernate.annotations.Target; +import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; + +import org.junit.Test; + +import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; + +/** + * @author Vlad Mihalcea + */ +public class ParentTest extends BaseEntityManagerFunctionalTestCase { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { + City.class, + }; + } + + @Test + public void testLifecycle() { + //tag::mapping-Parent-persist-example[] + doInJPA( this::entityManagerFactory, entityManager -> { + + City cluj = new City(); + cluj.setName( "Cluj" ); + cluj.setCoordinates( new GPS( 46.77120, 23.62360 ) ); + + entityManager.persist( cluj ); + } ); + //end::mapping-Parent-persist-example[] + + + //tag::mapping-Parent-fetching-example[] + doInJPA( this::entityManagerFactory, entityManager -> { + + City cluj = entityManager.find( City.class, 1L ); + + assertSame( cluj, cluj.getCoordinates().getCity() ); + } ); + //end::mapping-Parent-fetching-example[] + } + + //tag::mapping-Parent-example[] + + @Embeddable + public static class GPS { + + private double latitude; + + private double longitude; + + @Parent + private City city; + + private GPS() { + } + + public GPS(double latitude, double longitude) { + this.latitude = latitude; + this.longitude = longitude; + } + + public double getLatitude() { + return latitude; + } + + public double getLongitude() { + return longitude; + } + + public City getCity() { + return city; + } + + public void setCity(City city) { + this.city = city; + } + } + + @Entity(name = "City") + public static class City { + + @Id + @GeneratedValue + private Long id; + + private String name; + + @Embedded + @Target( GPS.class ) + private GPS coordinates; + + //Getters and setters omitted for brevity + + //end::mapping-Parent-example[] + + public Long getId() { + return id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public GPS getCoordinates() { + return coordinates; + } + + public void setCoordinates(GPS coordinates) { + this.coordinates = coordinates; + } + //tag::mapping-Parent-example[] + } + //end::mapping-Parent-example[] +} diff --git a/documentation/src/test/java/org/hibernate/userguide/mapping/basic/TargetTest.java b/documentation/src/test/java/org/hibernate/userguide/mapping/basic/TargetTest.java index 117e2f0c15..1d7ac4538b 100644 --- a/documentation/src/test/java/org/hibernate/userguide/mapping/basic/TargetTest.java +++ b/documentation/src/test/java/org/hibernate/userguide/mapping/basic/TargetTest.java @@ -50,6 +50,7 @@ public class TargetTest extends BaseEntityManagerFunctionalTestCase { doInJPA( this::entityManagerFactory, entityManager -> { City cluj = entityManager.find( City.class, 1L ); + assertEquals( 46.77120, cluj.getCoordinates().x(), 0.00001 ); assertEquals( 23.62360, cluj.getCoordinates().y(), 0.00001 ); } );