[英]Hibernate reloading entities in a fetch join
我將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和Data並懶惰地獲取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)
有大量的google結果,其中使用會導致延遲加載變得迫切。 我認為這是Hibernate中的錯誤。
將其添加到注釋列表中可以解決此問題
@LazyToOne(value=LazyToOneOption.NO_PROXY)
由於這會通知Hibernate您以后將不再嘗試使用該屬性,因此不需要代理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.