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
enhancement and the capabilities introduced into the domain model by the enhancement.
== The capabilities
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.
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]]
==== `@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]]
==== `@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[]
}