小编Ign*_*aca的帖子

使用FetchMode.JOIN的Hibernate OneToOne(optional = true)尝试重新选择空值

我的问题是,对于每个空关系,Hibernate急切加载OneToOne关联会执行+1 select.

实体示例:

@Entity 
class SideBlue {
    @Column(nullable = false)
    private Integer timestamp;

    @OneToOne(optional=true) 
    @JoinColumn(name="timestamp", referenceColumn="timestamp", insertable = false, updatable = false) 
    SideRed redSide; 
}
@Entity 
class SideRed {
    @Column(nullable = false)
    private Integer timestamp;
}
Run Code Online (Sandbox Code Playgroud)

(这是遗留数据库模式,因此不允许进行数据库修改)

查询示例:

CriteriaBuilder builder... CriteriaQuery query...
Root<SideBlue> root = query.from(SideBlue.class);
root.fetch(SideBlue_.sideRed, JoinType.LEFT);
entityManager().createQuery(query).getResultList();
Run Code Online (Sandbox Code Playgroud)

结果:如果所有蓝色边实体都有一个红色边,一切都正常,所以hibernate只对数据库执行一个查询,无论哪个实体都将被检索.

但是,如果蓝方实体没有关联的红色实体,那么hibernate会再次尝试找到另一方.Hibernate sql注释为每个null redSide属性说'/*load RedSide*/select ...'.

如何跳过第二次选择?

当延迟不是非常低时,出现实际问题.如果我尝试选择1百万行,并且1/3具有空的"红色边",则添加的总延迟是一个真正的问题.

编辑:

这是查询的调试日志

10:04:32.812 [main] DEBUG org.hibernate.loader.Loader - Result set row: 0
10:04:32.815 [main] DEBUG org.hibernate.loader.Loader - Result row: EntityKey[SideBlue#1269721], EntityKey[SideRed#3620564]
10:04:32.833 [main] DEBUG …
Run Code Online (Sandbox Code Playgroud)

java orm hibernate jpa

5
推荐指数
1
解决办法
4622
查看次数

标签 统计

hibernate ×1

java ×1

jpa ×1

orm ×1