HHH-11186 - Add examples for all Hibernate annotations

Document @LazyToOne annotation
This commit is contained in:
Vlad Mihalcea 2017-06-19 15:36:14 +03:00
parent e50809e631
commit e5044c51c1
4 changed files with 179 additions and 2 deletions

View File

@ -4,7 +4,6 @@
This guide covers Hibernate's ability to enhance an applications domain model, the ways to perform that This guide covers Hibernate's ability to enhance an applications domain model, the ways to perform that
enhancement and the capabilities introduced into the domain model by the enhancement. enhancement and the capabilities introduced into the domain model by the enhancement.
== The capabilities == The capabilities
Hibernate will enhance the classes in an application's domain model in order to add one or more of the Hibernate will enhance the classes in an application's domain model in order to add one or more of the

View File

@ -960,7 +960,7 @@ FALSE:: Eagerly load the association. This one is not needed since the JPA `Fetc
NO_PROXY:: This option will fetch the association lazily while returning real entity object. NO_PROXY:: This option will fetch the association lazily while returning real entity object.
PROXY:: This option will fetch the association lazily while returning a proxy instead. PROXY:: This option will fetch the association lazily while returning a proxy instead.
//TODO: Add example See the <<chapters/domain/associations.adoc#associations-one-to-one-bidirectional-lazy,`@LazyToOne` mapping example>> section for more info.
[[annotations-hibernate-listindexbase]] [[annotations-hibernate-listindexbase]]
==== `@ListIndexBase` ==== `@ListIndexBase`

View File

@ -225,6 +225,31 @@ include::{sourcedir}/OneToOneBidirectionalTest.java[tags=associations-one-to-one
---- ----
==== ====
[[associations-one-to-one-bidirectional-lazy]]
====== Bidirectional `@OneToOne` lazy association
Although you might annotate the parent-side association to be fetched lazily,
Hibernate cannot honor this request since it cannot know whether the association is `null` or not.
The only way to figure out whether there is an associated record on the child side is to fetch the child association using a secondary query.
Because this can lead to N+1 query issues, it's much more efficient to use unidirectional `@OneToOne` associations with the `@MapsId` annotation in place.
However, if you really need to use a bidirectional association and want to make sure that this is always going to be fetched lazily,
then you need to enable lazy state initialization bytecode enhancement and use the
https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/LazyToOne.html[`@LazyToOne`] annotation as well.
[[associations-one-to-one-bidirectional-lazy-example]]
.Bidirectional `@OneToOne` lazy parent-side association
====
[source,java]
----
include::{sourcedir}/OneToOneBidirectionalLazyTest.java[tags=associations-one-to-one-bidirectional-lazy-example,indent=0]
----
====
For more about how to enable Bytecode enhancement,
see the <<chapters/pc/BytecodeEnhancement.adoc#BytecodeEnhancement, BytecodeEnhancement chapter>>.
[[associations-many-to-many]] [[associations-many-to-many]]
==== `@ManyToMany` ==== `@ManyToMany`

View File

@ -0,0 +1,153 @@
/*
* 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.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import org.hibernate.annotations.LazyToOne;
import org.hibernate.annotations.LazyToOneOption;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.junit.Assert;
import org.junit.Test;
import org.jboss.logging.Logger;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
/**
* @author Vlad Mihalcea
*/
public class OneToOneBidirectionalLazyTest extends BaseEntityManagerFunctionalTestCase {
private static final Logger log = Logger.getLogger( OneToOneBidirectionalLazyTest.class );
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Phone.class,
PhoneDetails.class,
};
}
@Test
public void testLifecycle() {
}
//tag::associations-one-to-one-bidirectional-lazy-example[]
@Entity(name = "Phone")
public static class Phone {
@Id
@GeneratedValue
private Long id;
@Column(name = "`number`")
private String number;
@OneToOne(
mappedBy = "phone",
cascade = CascadeType.ALL,
orphanRemoval = true,
fetch = FetchType.LAZY
)
@LazyToOne( LazyToOneOption.NO_PROXY )
private PhoneDetails details;
public Phone() {
}
public Phone(String number) {
this.number = number;
}
//Getters and setters are omitted for brevity
//end::associations-one-to-one-bidirectional-lazy-example[]
public Long getId() {
return id;
}
public String getNumber() {
return number;
}
public PhoneDetails getDetails() {
return details;
}
public void addDetails(PhoneDetails details) {
details.setPhone( this );
this.details = details;
}
public void removeDetails() {
if ( details != null ) {
details.setPhone( null );
this.details = null;
}
}
//tag::associations-one-to-one-bidirectional-lazy-example[]
}
@Entity(name = "PhoneDetails")
public static class PhoneDetails {
@Id
@GeneratedValue
private Long id;
private String provider;
private String technology;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "phone_id")
private Phone phone;
public PhoneDetails() {
}
public PhoneDetails(String provider, String technology) {
this.provider = provider;
this.technology = technology;
}
//Getters and setters are omitted for brevity
//end::associations-one-to-one-bidirectional-lazy-example[]
public String getProvider() {
return provider;
}
public String getTechnology() {
return technology;
}
public void setTechnology(String technology) {
this.technology = technology;
}
public Phone getPhone() {
return phone;
}
public void setPhone(Phone phone) {
this.phone = phone;
}
//tag::associations-one-to-one-bidirectional-lazy-example[]
}
//end::associations-one-to-one-bidirectional-lazy-example[]
}