具有共享主键的java JPA单向@OneToOne关系始终会触发辅助查询,即使fetchType是急切的
我正在构建一个博客系统,并且喜欢为博客提供向上投票/向下投票功能。由于博客的计票数应该保持不变,所以我选择使用MySQL作为数据存储。我使用Spring JPA(Hibernate)来完成ORM工作。以下是我的数据对象:
class Blog{
// ...
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@OneToOne(optional = false, fetch = FetchType.EAGER)
@PrimaryKeyJoinColumn
private BlogVoteCounter voteCounter;
}
还有柜台:
@Entity
public class BlogVoteCounter extends ManuallyAssignIdEntitySuperClass<Long> {
@Id
private Long id;
private Integer value;
}
我之所以将BlogVoteCounter
与Blog
分开,是因为我认为voteCount
字段的修改频率与博客的其他字段完全不同,因为我想使用缓存来缓存Blog
,在这个guide之后,我选择将它们分开
然而,由于在将Blog对象返回前端时可能总是需要VoteCount
字段,并且为了避免n+1问题,我在Blog类中用EAGER fetch类型声明了BlogVoteCounter
字段
我已经看过了。因此,根据我个人的理解,我使用单向关系,只在Blog
端声明OneToOne
然而,当我检查查询时,发现jpa仍然会触发一个二级查询,从数据库中检索BlogVoteCounter
,而不只是在BlogRepository
上使用findAll
方法时使用联接
select
blogvoteco0_.id as id1_2_0_,
blogvoteco0_.value as value2_2_0_
from
blog_vote_counter blogvoteco0_
where
blogvoteco0_.id=?
因此,我应该如何配置,以便总是急切地获取Blog
中的BlogVoteCounter
字段
ManuallyAssignIdEntitySuperClass
的用法是在Spring JPA doc之后使用的,因为我手动为BlogVoteCounter
类分配id
@MappedSuperclass
public abstract class ManuallyAssignIdEntitySuperClass<ID> implements Persistable<ID> {
@Transient
private boolean isNew = true;
@Override
public boolean isNew() {
return isNew;
}
@PrePersist
@PostLoad
void markNotNew(){
this.isNew = false;
}
}
而BlogRepository
是从JpaRepository
派生出来的
public interface BlogRepository extends JpaRepository<Blog, Long>{
// ...
}
我使用findAll
方法触发查询,但使用findById
或其他条件查询似乎没有什么区别
# 1 楼答案
1。为
repository.findById(blogId);
生成的查询2。更新的地图
3。当前映射的问题
blog
和votecounter
,因为它会导致chicken and egg
问题。 i、 e4。变化
5。注意事项
repository.findAll
生成了2个查询,所以我重写了该方法来生成一个连接查询