Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the JPA equivalent of the Hibernate @LazyToOne annotation?

I am currently using the Hibernate @LazyToOne annotation.

Since I'm switching from Hibernate to JPA, I'd like to know whether @LazyToOne is available in JPA, or is there any other annotation that provides the same functionality in JPA?

like image 430
Sanjaya Liyanage Avatar asked Dec 29 '25 09:12

Sanjaya Liyanage


1 Answers

@LazyToOne and LazyToOneOption

The legacy @LazyToOne annotation provides the following options:

  • FALSE
  • PROXY
  • NO_PROXY

LazyToOne annotation

LazyToOneOption.FALSE

The FALSE option is equivalent to the JPA FetchType.EAGER annotation, so it should be avoided as it can cause serious performance issues.

LazyToOneOption.PROXY

The PROXY option is equivalent to the JPA [FetchType.LAZY] strategy. However, you should prefer using the fetch attribute of the JPA @OneToOne or @ManyToOne associations instead.

LazyToOneOption.NO_PROXY

This strategy is useful when using the @OneToOne association on the parent side.

So, assuming you have the following Post and PostDetails entities:

Post and PostDetails entities

If the Post maps the parent-side of this one-to-one table relationship:

@OneToOne(
    mappedBy = "post",
    fetch = FetchType.LAZY,
    cascade = CascadeType.ALL
)
private PostDetails details;

Even if the association uses the FetchType.LAZY strategy, we can see that if we want to fetch the Post entity:

Post post = doInJPA(entityManager -> {
    return entityManager.find(Post.class, 1L);
});

The PostDetails is going to be fetched eagerly:

SELECT p.id AS id1_0_0_,
       p.title AS title2_0_0_
FROM post p
WHERE p.id = 1
 
SELECT pd.id AS id1_1_0_,
       pd.created_by AS created_2_1_0_,
       pd.created_on AS created_3_1_0_
FROM post_details pd
WHERE pd.id = 1

This is because Hibernate doesn't know how to initialize the details property since it needs to decide whether to use null or a Proxy, and the only way to find that out is to issue a SELECT query.

So, to fix this issue, we need to things:

  • enable lazy fetching bytecode enhancement
  • use the NO_PROXY strategy

To enable lazy loading bytecode enhancement, we can use this Hibernate Maven plugin:

<plugin>
    <groupId>org.hibernate.orm.tooling</groupId>
    <artifactId>hibernate-enhance-maven-plugin</artifactId>
    <version>${hibernate.version}</version>
    <executions>
        <execution>
            <configuration>
                <enableLazyInitialization>true</enableLazyInitialization>
            </configuration>
            <goals>
                <goal>enhance</goal>
            </goals>
        </execution>
    </executions>
</plugin>

And, we also need to use the NO_PROXY strategy:

@OneToOne(
    mappedBy = "post",
    fetch = FetchType.LAZY,
    cascade = CascadeType.ALL
)
@LazyToOne(LazyToOneOption.NO_PROXY)
private PostDetails details;

With this change in place, the parent-side @OneToOne association is going to be fetched lazily.

like image 79
Vlad Mihalcea Avatar answered Dec 30 '25 22:12

Vlad Mihalcea



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!