簡體   English   中英

在獲取聯接中休眠重載實體

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM