2020-06-24

Hibernate JPA @LazyToOne Example

@LazyToOne

The @LazyToOne annotation is used to specify the laziness options, represented by LazyToOneOption, available for a @OneToOne or @ManyToOne association.

LazyToOne Define the laziness options available for a ToOne (ie OneToOne or ManyToOne) association.

LazyToOneOption defines the following alternatives:

FALSE
Eagerly load the association. This one is not needed since the JPA FetchType.EAGER offers the same behavior.

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.


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 @LazyToOne annotation as well.

Example - Bidirectional @OneToOne lazy parent-side association

@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;

//Getters and setters are omitted for brevity

public void addDetails(PhoneDetails details) {
details.setPhone( this );
this.details = details;
}

public void removeDetails() {
if ( details != null ) {
details.setPhone( null );
this.details = null;
}
}
}

@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;

//Getters and setters are omitted for brevity

}

No comments:

Post a Comment