Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用FetchMode休眠OneToOne(可选=true)。请尝试重新选择空值_Java_Hibernate_Jpa_Orm - Fatal编程技术网

Java 使用FetchMode休眠OneToOne(可选=true)。请尝试重新选择空值

Java 使用FetchMode休眠OneToOne(可选=true)。请尝试重新选择空值,java,hibernate,jpa,orm,Java,Hibernate,Jpa,Orm,我的问题是,hibernate急切地加载OneTONE关联对每个空关系执行+1 select 实体示例: @Entity class SideBlue { @Column(nullable = false) private Integer timestamp; @OneToOne(optional=true) @JoinColumn(name="timestamp", referenceColumn="timestamp", insertable = fal

我的问题是,hibernate急切地加载OneTONE关联对每个空关系执行+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;
}
CriteriaBuilder builder... CriteriaQuery query...
Root<SideBlue> root = query.from(SideBlue.class);
root.fetch(SideBlue_.sideRed, JoinType.LEFT);
entityManager().createQuery(query).getResultList();
(这是传统数据库架构,因此不允许修改数据库)

查询示例:

@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;
}
CriteriaBuilder builder... CriteriaQuery query...
Root<SideBlue> root = query.from(SideBlue.class);
root.fetch(SideBlue_.sideRed, JoinType.LEFT);
entityManager().createQuery(query).getResultList();
第一行包含蓝色和红色边,但第二行仅包含蓝色边。所以hibernate必须知道相关的红色面不存在。但是,在处理所有结果行之后

10:04:33.083 [main] DEBUG o.h.engine.internal.TwoPhaseLoad - Resolving associations for [BlueSide#1269721]
10:04:33.084 [main] DEBUG org.hibernate.loader.Loader - Loading entity: [RedSide#component[timestamp]{timestamp=1338937390}]
10:04:33.084 [main] DEBUG org.hibernate.SQL - /* load RedSide */ select ...
! Nothing really loaded because the previous SQL return empty result set, again !
10:04:33.211 [main] DEBUG org.hibernate.loader.Loader - Done entity load

在查询SideBlue时,您试图不加载SideRed。我认为这是一个与Hibernate的“限制”有关的延迟加载问题(从):

在加载B之后,您可以调用getCee()来获取C, getCee()是类的一个方法,Hibernate无法控制 信息技术Hibernate不知道何时会有人调用getCee()。 这意味着Hibernate必须在“cee”属性中输入适当的值 此时,它从数据库中加载B

如果为C启用了代理, Hibernate可以放置一个尚未加载的C-proxy对象,但它将 当有人使用它时会被加载。这会为用户提供延迟加载 一对一

但是现在想象你的B对象可能有,也可能没有 关联C(constrained=“false”)。当发生错误时,getCee()应该返回什么 特定的B没有C?无效的但请记住,Hibernate必须设置为 设置B时“cee”的正确值(因为它不知道 当有人调用getCee()时。代理在这里没有帮助,因为 代理本身已在非空对象中

所以简历:如果你的B->C 映射是必需的(constrained=true),Hibernate将使用代理 C导致延迟初始化。但是如果你允许B没有C, Hibernate只需在加载B时检查C是否存在。 但是,选择检查状态是低效的,因为 选择不仅可以检查是否存在,还可以加载整个对象。太懒了 装载消失了


你的例子令人困惑,上面有@JoinColumn注释的那一方定义为关系的所有者。我错了。我重新定义/改进de实体定义。这是我实体的简化版本,但我认为这已经足够了。数据库在两侧时间戳之间没有FK。