gpt4 book ai didi

java - Hibernate 在获取连接中重新加载实体

转载 作者:行者123 更新时间:2023-12-02 13:34:33 24 4
gpt4 key购买 nike

我在 Hibernate 重新加载查询中的实体时遇到问题,即使它们是作为主查询的一部分获取的。

实体如下(简化)

class Data {
@Id
String guid;

@ManyToOne(fetch = FetchType.LAZY)
@NotFound(action = NotFoundAction.IGNORE)
DataContents contents;
}

class DataClosure {
@Id
@ManyToOne(fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
@JoinColumn(name = "ancestor_id", nullable = false)
private Data ancestor;

@Id
@ManyToOne(fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
@JoinColumn(name = "descendant_id", nullable = false)
private Data descendant;

private int length;
}

这是对父/子关系的闭包表进行建模。

我设置了一些标准如下

    final Criteria criteria = getSession()
.createCriteria(DataClosure.class, "dc");
criteria.createAlias("dc", "a");
criteria.createAlias("dc.descendant", "d");
criteria.setFetchMode("a", FetchMode.JOIN);
criteria.setFetchMode("d", FetchMode.JOIN);
criteria.add(Restrictions.eq("d.metadataGuid",guidParameter));
criteria.add(Restrictions.ne("a.metadataGuid",guidParameter));

这会产生以下 SQL 查询

select
this_.descendant_id as descenda2_21_2_,
this_.ancestor_id as ancestor3_21_2_,
this_.length as length1_21_2_,
d2_.guid as metadata1_20_0_,
d2_.name as name5_20_0_,
a1_.guid as metadata1_20_1_,
a1_.name as name6_20_1_
from
data_closure this_
inner join
data d2_
on this_.descendant_id=d2_.metadata_guid
inner join
data a1_
on this_.ancestor_id=a1_.metadata_guid
where
d2_.guid=?
and a1_.guid<>?

看起来它正确地实现了连接获取。但是当我执行时

    List list = criteria.list();

我在结果集中的每行 SQL 日志中看到其中一个条目

Result set row: 0
DEBUG Loader - Loading entity: [Data#testGuid19]
DEBUG SQL -
select
data0_.guid as guid1_20_0_,
data0_.title as title5_20_0_,
from
data data0_
where
data0_.guid=?
Hibernate:
(omitted)
DEBUG Loader - Result set row: 0
DEBUG Loader - Result row: EntityKey[Data#testGuid19]
DEBUG TwoPhaseLoad - Resolving associations for [Data#testGuid19]
DEBUG Loader - Loading entity: [DataContents#7F1134F890A446BBB47F3EB64C1CF668]
DEBUG SQL -
select
dataContents0_.guid as guid_12_0_,
dataContents0_.isoCreationDate as isoCreat2_12_0_,
from
dataContents dataContents0_
where
dataContents0_.guid=?
Hibernate:
(omitted)

看起来即使 DataContents 被标记为延迟加载,它也会被急切地加载。

因此,我要么希望在查询中以某种方式获取联接 DataClosure 和数据并延迟获取 DataContents,要么在不可能的情况下获取联接 DataContents。

编辑:

像这样对闭包表进行建模

class DataClosure {
@Id
@Column(name = "ancestor_id", nullable = false, length =36 )
private String ancestorId;

@Id
@Column(name = "descendant_id", nullable = false, length =36 )
private String descendantId;

@ManyToOne(fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
@JoinColumn(name = "ancestor_id", nullable = false)
private Data ancestor;

@ManyToOne(fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
@JoinColumn(name = "descendant_id", nullable = false)
private Data descendant;

private int length;
}

解决了问题。换句话说,即使生成的查询没有任何问题,对其他表中的实体使用 @Id 注释似乎也会导致问题。

最佳答案

我认为你的问题可能是这样的

@NotFound(action = NotFoundAction.IGNORE)

有很多谷歌结果,使用它会导致延迟加载变得急切。我认为这是 Hibernate 中的一个错误。

将其添加到注释列表应该可以解决问题

@LazyToOne(value=LazyToOneOption.NO_PROXY)

因为这会通知 Hibernate 您稍后不会尝试使用该属性,因此不需要代理。

关于java - Hibernate 在获取连接中重新加载实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43069330/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com