HH-11186 - Add examples for all Hibernate annotations

Document Target annotation
This commit is contained in:
Vlad Mihalcea 2017-04-19 12:53:28 +03:00
parent 9d3e917661
commit 6c810a422c
4 changed files with 205 additions and 3 deletions

View File

@ -1252,7 +1252,7 @@ The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibern
The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Target.html[`@Target`] annotation is used to specify an explicit target implementation when the current annotated association is using an interface type.
//TODO: Add example
See the <<chapters/domain/basic_types.adoc#mapping-Target,`@Target` mapping>> section for more info.
[[annotations-hibernate-tuplizer]]
==== `@Tuplizer`

View File

@ -2001,7 +2001,7 @@ The `country` association in the `User` entity is mapped by the `language` prope
Considering we have the following entities:
[[mapping-JoinColumnOrFormula-persistence-example]]
.`@JoinColumnOrFormula` mapping usage
.`@JoinColumnOrFormula` persist example
====
[source, JAVA, indent=0]
----
@ -2012,7 +2012,7 @@ include::{sourcedir}/basic/JoinColumnOrFormulaTest.java[tags=mapping-JoinColumnO
When fetching the `User` entities, the `country` property is mapped by the `@JoinColumnOrFormula` expression:
[[mapping-JoinColumnOrFormula-fetching-example]]
.`@JoinColumnOrFormula` mapping usage
.`@JoinColumnOrFormula` fetching example
====
[source, JAVA, indent=0]
----
@ -2026,3 +2026,60 @@ include::{extrasdir}/basic/mapping-JoinColumnOrFormula-fetching-example.sql[]
====
Therefore, the `@JoinColumnOrFormula` annotation is used to define a custom join association between the parent-child association.
[[mapping-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
http://docs.oracle.com/javaee/7/api/javax/persistence/ManyToOne.html[`@ManyToOne`],
http://docs.oracle.com/javaee/7/api/javax/persistence/OneToOne.html[`@OneToOne`],
http://docs.oracle.com/javaee/7/api/javax/persistence/OneToMany.html[`@OneToMany`], and
http://docs.oracle.com/javaee/7/api/javax/persistence/ManyToMany.html[`@ManyToMany`]
feature a http://docs.oracle.com/javaee/7/api/javax/persistence/ManyToOne.html#targetEntity--[`targetEntity`] attribute to specify the actual class of the entiity association when an interface is used for the mapping.
The http://docs.oracle.com/javaee/7/api/javax/persistence/ElementCollection.html[`@ElementCollection`] association has a http://docs.oracle.com/javaee/7/api/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.
[[mapping-Target-example]]
.`@Target` mapping usage
====
[source, JAVA, indent=0]
----
include::{sourcedir}/basic/TargetTest.java[tags=mapping-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:
[[mapping-Target-persist-example]]
.`@Target` persist example
====
[source, JAVA, indent=0]
----
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
====
[source, JAVA, indent=0]
----
include::{sourcedir}/basic/TargetTest.java[tags=mapping-Target-fetching-example]
----
[source, SQL, indent=0]
----
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.

View File

@ -0,0 +1,15 @@
SELECT
c.id as id1_0_0_,
c.latitude as latitude2_0_0_,
c.longitude as longitud3_0_0_,
c.name as name4_0_0_
FROM
City c
WHERE
c.id = ?
-- binding parameter [1] as [BIGINT] - [1]
-- extracted value ([latitude2_0_0_] : [DOUBLE]) - [46.7712]
-- extracted value ([longitud3_0_0_] : [DOUBLE]) - [23.6236]
-- extracted value ([name4_0_0_] : [VARCHAR]) - [Cluj]

View File

@ -0,0 +1,130 @@
/*
* 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.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.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;
/**
* @author Vlad Mihalcea
*/
public class TargetTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
City.class,
};
}
@Test
public void testLifecycle() {
//tag::mapping-Target-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-Target-persist-example[]
//tag::mapping-Target-fetching-example[]
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 );
} );
//end::mapping-Target-fetching-example[]
}
//tag::mapping-Target-example[]
public interface Coordinates {
double x();
double y();
}
@Embeddable
public static class GPS implements Coordinates {
private double latitude;
private double longitude;
private GPS() {
}
public GPS(double latitude, double longitude) {
this.latitude = latitude;
this.longitude = longitude;
}
@Override
public double x() {
return latitude;
}
@Override
public double y() {
return longitude;
}
}
@Entity(name = "City")
public static class City {
@Id
@GeneratedValue
private Long id;
private String name;
@Embedded
@Target( GPS.class )
private Coordinates coordinates;
//Getters and setters omitted for brevity
//end::mapping-Target-example[]
public Long getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Coordinates getCoordinates() {
return coordinates;
}
public void setCoordinates(Coordinates coordinates) {
this.coordinates = coordinates;
}
//tag::mapping-Target-example[]
}
//end::mapping-Target-example[]
}