HHH-11837 - MapsId and PrimaryKeyJoinColumn examples in the documentation should use OneToOne rather than ManyToOne

This commit is contained in:
Vlad Mihalcea 2017-06-26 14:47:43 +03:00
parent 3d2baa8d56
commit 664a9d568a
6 changed files with 277 additions and 138 deletions

View File

@ -1,29 +0,0 @@
@Entity
public class PersonDetails {
@Id
private Long id;
private String nickName;
@ManyToOne
@PrimaryKeyJoinColumn
private Person person;
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
this.id = person.getId();
}
}

View File

@ -1,53 +0,0 @@
@Entity
public class Person {
@Id
@GeneratedValue
private Long id;
@NaturalId
private String registrationNumber;
public Person() {}
public Person(String registrationNumber) {
this.registrationNumber = registrationNumber;
}
public Long getId() {
return id;
}
public String getRegistrationNumber() {
return registrationNumber;
}
}
@Entity
public class PersonDetails {
@Id
private Long id;
private String nickName;
@ManyToOne
@MapsId
private Person person;
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}

View File

@ -1,6 +1,7 @@
[[identifiers]] [[identifiers]]
=== Identifiers === Identifiers
:sourcedir: ../../../../../test/java/org/hibernate/userguide/mapping/identifier :sourcedir: ../../../../../test/java/org/hibernate/userguide/mapping/identifier
:sourcedir-associations: ../../../../../test/java/org/hibernate/userguide/associations
:extrasdir: extras :extrasdir: extras
Identifiers model the primary key of an entity. They are used to uniquely identify each specific entity. Identifiers model the primary key of an entity. They are used to uniquely identify each specific entity.
@ -482,12 +483,22 @@ JPA 2.0 added support for derived identifiers which allow an entity to borrow th
==== ====
[source,java] [source,java]
---- ----
include::{extrasdir}/id/DerivedIdentifier.java[] include::{sourcedir-associations}/OneToOneMapsIdTest.java[tag=identifiers-derived-mapsid, indent=0]
---- ----
==== ====
In the example above, the `PersonDetails` entity uses the `id` column for both the entity identifier and for the many-to-one association to the `Person` entity. In the example above, the `PersonDetails` entity uses the `id` column for both the entity identifier and for the many-to-one association to the `Person` entity.
The value of the `PersonDetails` entity identifier is "derived" from the identifier of its parent `Person` entity. The value of the `PersonDetails` entity identifier is "derived" from the identifier of its parent `Person` entity.
[[identifiers-derived-mapsid-persist-example]]
.Derived identifier with `@MapsId` persist example
====
[source,java]
----
include::{sourcedir-associations}/OneToOneMapsIdTest.java[tag=identifiers-derived-mapsid-persist-example, indent=0]
----
====
The `@MapsId` annotation can also reference columns from an `@EmbeddedId` identifier as well. The `@MapsId` annotation can also reference columns from an `@EmbeddedId` identifier as well.
The previous example can also be mapped using `@PrimaryKeyJoinColumn`. The previous example can also be mapped using `@PrimaryKeyJoinColumn`.
@ -497,13 +508,14 @@ The previous example can also be mapped using `@PrimaryKeyJoinColumn`.
==== ====
[source,java] [source,java]
---- ----
include::{extrasdir}/id/CompositeIdAssociationPrimaryKeyJoinColumn.java[] include::{sourcedir-associations}/OneToOnePrimaryKeyJoinColumnTest.java[tag=identifiers-derived-primarykeyjoincolumn, indent=0]
---- ----
==== ====
[NOTE] [NOTE]
==== ====
Unlike `@MapsId`, the application developer is responsible for ensuring that the identifier and the many-to-one (or one-to-one) association are in sync. Unlike `@MapsId`, the application developer is responsible for ensuring that the identifier and the many-to-one (or one-to-one) association are in sync
as you can see in the `PersonDetails#setPerson` method.
==== ====
[[identifiers-rowid]] [[identifiers-rowid]]

View File

@ -0,0 +1,126 @@
/*
* 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.associations;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.MapsId;
import javax.persistence.OneToOne;
import org.hibernate.annotations.NaturalId;
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 OneToOneMapsIdTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Person.class,
PersonDetails.class
};
}
@Test
public void testLifecycle() {
//tag::identifiers-derived-mapsid-persist-example[]
doInJPA( this::entityManagerFactory, entityManager -> {
Person person = new Person( "ABC-123" );
person.setId( 1L );
entityManager.persist( person );
PersonDetails personDetails = new PersonDetails();
personDetails.setNickName( "John Doe" );
personDetails.setPerson( person );
entityManager.persist( personDetails );
} );
doInJPA( this::entityManagerFactory, entityManager -> {
PersonDetails personDetails = entityManager.find( PersonDetails.class, 1L );
assertEquals("John Doe", personDetails.getNickName());
} );
//end::identifiers-derived-mapsid-persist-example[]
}
//tag::identifiers-derived-mapsid[]
@Entity(name = "Person")
public static class Person {
@Id
private Long id;
@NaturalId
private String registrationNumber;
public Person() {}
public Person(String registrationNumber) {
this.registrationNumber = registrationNumber;
}
//Getters and setters are omitted for brevity
//end::identifiers-derived-mapsid[]
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getRegistrationNumber() {
return registrationNumber;
}
//tag::identifiers-derived-mapsid[]
}
@Entity(name = "PersonDetails")
public static class PersonDetails {
@Id
private Long id;
private String nickName;
@OneToOne
@MapsId
private Person person;
//Getters and setters are omitted for brevity
//end::identifiers-derived-mapsid[]
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
//tag::identifiers-derived-mapsid[]
}
//end::identifiers-derived-mapsid[]
}

View File

@ -0,0 +1,136 @@
/*
* 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.associations;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.MapsId;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import org.hibernate.annotations.NaturalId;
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 OneToOnePrimaryKeyJoinColumnTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Person.class,
PersonDetails.class
};
}
@Test
public void testLifecycle() {
//tag::identifiers-derived-primarykeyjoincolumn-persist-example[]
doInJPA( this::entityManagerFactory, entityManager -> {
Person person = new Person( "ABC-123" );
person.setId( 1L );
entityManager.persist( person );
PersonDetails personDetails = new PersonDetails();
personDetails.setNickName( "John Doe" );
personDetails.setPerson( person );
entityManager.persist( personDetails );
} );
doInJPA( this::entityManagerFactory, entityManager -> {
PersonDetails personDetails = entityManager.find( PersonDetails.class, 1L );
assertEquals("John Doe", personDetails.getNickName());
} );
//end::identifiers-derived-primarykeyjoincolumn-persist-example[]
}
//tag::identifiers-derived-primarykeyjoincolumn[]
@Entity(name = "Person")
public static class Person {
@Id
private Long id;
@NaturalId
private String registrationNumber;
public Person() {}
public Person(String registrationNumber) {
this.registrationNumber = registrationNumber;
}
//Getters and setters are omitted for brevity
//end::identifiers-derived-primarykeyjoincolumn[]
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getRegistrationNumber() {
return registrationNumber;
}
//tag::identifiers-derived-primarykeyjoincolumn[]
}
@Entity(name = "PersonDetails")
public static class PersonDetails {
@Id
private Long id;
private String nickName;
@OneToOne
@PrimaryKeyJoinColumn
private Person person;
public void setPerson(Person person) {
this.person = person;
this.id = person.getId();
}
//Other getters and setters are omitted for brevity
//end::identifiers-derived-primarykeyjoincolumn[]
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public Person getPerson() {
return person;
}
//tag::identifiers-derived-primarykeyjoincolumn[]
}
//end::identifiers-derived-primarykeyjoincolumn[]
}

View File

@ -1,53 +0,0 @@
/*
* 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.persister;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.persister.entity.SingleTableEntityPersister;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* @author Shawn Clowater
*/
public class PersisterTest extends BaseNonConfigCoreFunctionalTestCase {
@Test
public void testEntityEntityPersisterAndPersisterSpecified() throws Exception {
//checks to see that the persister specified with the @Persister annotation takes precedence if a @Entity.persister() is also specified
PersistentClass persistentClass = metadata().getEntityBinding( Author.class.getName() );
assertEquals( "Incorrect Persister class for " + persistentClass.getMappedClass(), EntityPersister.class,
persistentClass.getEntityPersisterClass() );
}
@Test
public void testEntityEntityPersisterSpecified() throws Exception {
//tests the persister specified with an @Entity.persister()
PersistentClass persistentClass = metadata().getEntityBinding( Book.class.getName() );
assertEquals( "Incorrect Persister class for " + persistentClass.getMappedClass(),
SingleTableEntityPersister.class, persistentClass.getEntityPersisterClass() );
}
@Test
public void testCollectionPersisterSpecified() throws Exception {
//tests the persister specified by the @Persister annotation on a collection
Collection collection = metadata().getCollectionBinding( Author.class.getName() + ".cards" );
assertEquals( "Incorrect Persister class for collection " + collection.getRole(), CollectionPersister.class,
collection.getCollectionPersisterClass() );
}
@Override
protected Class[] getAnnotatedClasses() {
return new Class[]{
Book.class,
Author.class
};
}
}