当前位置: 首页 > 知识库问答 >
问题:

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

柯梓
2023-03-14

我在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被标记为懒加载,它也在急切地加载。

因此,我要么希望在我的查询中以某种方式获取加入数据闭包和数据并懒惰地获取数据内容,要么在不可能的情况下获取加入数据内容。

编辑:

像这样模拟关闭表

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注释似乎会导致问题,尽管生成的查询没有任何问题。

共有1个答案

司立果
2023-03-14

我想你的问题可能是这个

@NotFound(action = NotFoundAction.IGNORE)

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

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

@LazyToOne(value=LazyToOneOption.NO_PROXY)

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

 类似资料:
  • 是否可以在Java中获取重新加载的url? 我需要检索令牌附加到url后加载下面的超文本标记语言页面。 最初,URL将为 http://localhost:8080/validate.html?invisible=true代码 成功后它将是 <代码>http://localhost:8080/validate.html?token=xyz 我需要在Java中检索令牌值。 我尝试了下面的代码,但va

  • 在web应用程序上,我们使用Spring 3.2和Hibernate 4.1.1,并实现了一个类似插件的架构。插件可以在运行时添加和删除。对于每个模块,我们定义了一个单独的类加载器,并在spring上创建了单独的子应用程序上下文。完整的配置是使用注释完成的,不再需要对beans进行XML配置。 Spring Hibernate配置类 现在的问题是:一些插件包含自己的实体(DAO)类,这些类在运行时

  • 我目前正在开发一个应用程序,可以在用户手机上找到所有MP3,然后将它们放入列表中。这是非常好的工作,非常快,即使有很多歌曲。现在,我为列表中的每个项目填充一个新列表,然后将其显示在我的recyclerview中。问题是,我的手机上有700首歌曲,这在相当长的一段时间内会阻塞UI线程。 现在,我想使用回收站视图不将列表中的所有项目一次加载到对象中,而是仅在它们即将显示时加载-但我不知道如何做到这一点

  • 我想开发一个Kafka连接器,但为了快速测试,我想重新加载插件,而不是重新加载我的docker堆栈中的容器。有办法做到吗? 实际上,我编译了连接器,并将jar文件移动到绑定在容器kafka connect上的文件夹中。移动文件后,我重新加载容器。 先谢谢你。

  • 问题内容: 这肯定是一个普遍的问题…而且我觉得在使用Google搜索和SOing之后,我肯定只是没有彻底地环顾四周以获得足够的答案,或者没有人问过这个问题…所以请原谅我。 我正在使用Spring Security和Hibernate等 因此,用户/主要用户已登录并对其个人资料进行了一些更改。 我使用DAO更新配置文件(UserDetails),并且希望我的Principal自动反映此更新。 但是,

  • 我需要从Rest控件获取一个实体及其集合,但我对spring data JPA有一个非常奇怪的行为。 我对带有懒惰加载的实体有一种莫名其妙的关系。