[英]What's the JPA equivalent of the Hibernate @LazyToOne annotation?
I am currently using the Hibernate @LazyToOne
annotation.我目前正在使用 Hibernate @LazyToOne
注释。
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?由于我正在从 Hibernate 切换到 JPA,我想知道@LazyToOne
在 JPA 中是否可用,或者是否有任何其他注释在 JPA 中提供相同的功能?
@LazyToOne
and LazyToOneOption
@LazyToOne
和LazyToOneOption
The legacy @LazyToOne
annotation provides the following options:遗留的@LazyToOne
注释提供以下选项:
FALSE
PROXY
NO_PROXY
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. FALSE
选项等效于 JPA FetchType.EAGER
注释,因此应避免使用,因为它会导致严重的性能问题。
LazyToOneOption.PROXY
The PROXY
option is equivalent to the JPA [ FetchType.LAZY
] strategy. PROXY
选项等效于 JPA [ FetchType.LAZY
] 策略。 However, you should prefer using the fetch
attribute of the JPA @OneToOne
or @ManyToOne
associations instead.但是,您应该更喜欢使用 JPA @OneToOne
或@ManyToOne
关联的fetch
属性。
LazyToOneOption.NO_PROXY
This strategy is useful when using the @OneToOne
association on the parent side.在父端使用@OneToOne
关联时,此策略很有用。
So, assuming you have the following Post
and PostDetails
entities:因此,假设您有以下Post
和PostDetails
实体:
If the Post
maps the parent-side of this one-to-one table relationship:如果Post
映射了这个一对一表关系的父端:
@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:即使关联使用了FetchType.LAZY
策略,我们也可以看到,如果我们要获取Post
实体:
Post post = doInJPA(entityManager -> {
return entityManager.find(Post.class, 1L);
});
The PostDetails
is going to be fetched eagerly: PostDetails
将被急切地获取:
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.这是因为 Hibernate 不知道如何初始化details
属性,因为它需要决定是使用null
还是 Proxy,而找出这一点的唯一方法是发出 SELECT 查询。
So, to fix this issue, we need to things:因此,要解决此问题,我们需要:
NO_PROXY
strategy使用NO_PROXY
策略To enable lazy loading bytecode enhancement, we can use this Hibernate Maven plugin:要启用延迟加载字节码增强,我们可以使用这个 Hibernate Maven 插件:
<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:而且,我们还需要使用NO_PROXY
策略:
@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.有了这个更改,父端@OneToOne
关联将被延迟获取。
You can use:您可以使用:
@OneToOne(fetch = FetchType.LAZY)
More details in this question: Making a OneToOne-relation lazy这个问题的更多细节: 使一对一关系变得懒惰
You can create a jpql
, like:您可以创建一个jpql
,例如:
User user = em.createQuery("SELECT NEW com.model.User(u.id, u.name, u.password)
FROM User u WHERE u.id = :id", User.class)
.setParameter("id", 1L)
.gerSingleResult();`
It may solve your problem.它可能会解决您的问题。 But, you have to remember to write the default constructor.但是,您必须记住编写默认构造函数。
It should be它应该是
@OneToOne(fetch = FetchType.LAZY, optional=false)
Found on this forum: https://forum.hibernate.org/viewtopic.php?p=2388783在这个论坛上找到: https : //forum.hibernate.org/viewtopic.php?p=2388783
The reason, I guess, is that the only way for JPA to know if an attribute has already been fetched is to check it has a value, but if null is a valid value then there's no way to tell.我猜,原因是 JPA 知道一个属性是否已经被获取的唯一方法是检查它是否有一个值,但如果 null 是一个有效值,那么就没有办法判断了。 Hence optional attributes are always fetched regardless.因此,无论如何总是获取可选属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.