简体   繁体   English

在获取联接中休眠重载实体

[英]Hibernate reloading entities in a fetch join

I am having a problem with Hibernate reloading the entities in a query even though they are being fetched as part of the main query. 我将Hibernate重新加载查询中的实体时遇到问题,即使它们是作为主查询的一部分来获取的。

The entities are as follows (simplified) 实体如下(简化)

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;
}

This is modelling a closure table of parent / child relationships. 这是建模父/子关系的关闭表。

I have set up some criteria as follows 我建立了一些标准如下

    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));

This results in the following SQL query 这导致以下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<>?

which looks like it is correctly implementing the join fetch. 看起来好像正确地实现了连接提取。 However when I execute 但是当我执行

    List list = criteria.list();

I see one of these entries in the SQL log per row in the result set 我在结果集中每行的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)

It is looks like even though the DataContents is marked as lazily loaded, it's being loaded eagerly. 看起来即使DataContents被标记为延迟加载,它仍在急切地加载。

So I either want some way in my query to fetch join DataClosure and Data and lazily fetch DataContents, or to fetch join the DataContents if that is not possible. 因此,我要么希望查询中的某种方式来获取联接DataClosure和Data并懒惰地获取DataContents,要么如果不可能的话就获取联接DataContents。

Edit: 编辑:

Modelling the closure table like this 像这样建模闭合表

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;
}

fixed the problem. 解决了问题。 In other words, having @Id annotation on entities from other tables seemed to cause the issue, even though there was nothing wrong with the queries generated. 换句话说,即使生成的查询没有问题,对来自其他表的实体使用@Id注释似乎也可能导致此问题。

I think your problem here might be this 我认为您的问题可能是这个

@NotFound(action = NotFoundAction.IGNORE)

There are plenty of google results where using that causes the lazy loading to become eager. 有大量的google结果,其中使用会导致延迟加载变得迫切。 I think it is a bug in Hibernate. 我认为这是Hibernate中的错误。

Adding this to the list of annotations should fix the problem 将其添加到注释列表中可以解决此问题

@LazyToOne(value=LazyToOneOption.NO_PROXY)

Since that informs Hibernate that you will not try to use that property later on so no proxy is required. 由于这会通知Hibernate您以后将不再尝试使用该属性,因此不需要代理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM