java - 急切获取嵌套(递归)对象 - Hibernate

标签 java hibernate jpa fetch

我想急切地填充我的对象层次结构。问题是 Hibernate 在某些时候停止获取;它使关系字段(列表)未填充。

层次结构是(省略了一些代码,例如 id、getters,希望这部分看起来没问题):

public class User {
    private Container container;

    @OneToOne(fetch = FetchType.EAGER)
    public Container getContainer() {
        return container;
    }
}


public class Container {
    private List<Backpack> backpacks;
    private List<Item> items;

    @OneToMany(fetch = FetchType.EAGER, mappedBy="container")
    @Fetch(FetchMode.SELECT)
    private List<Item> getItems() {
        return items;
    }


    @OneToMany(fetch = FetchType.EAGER, mappedBy="container")
    @Fetch(FetchMode.SELECT)
    private List<Backpack> getBackpacks() {
        return backpacks;
    }
}


public class Backpack {
    ...
    private Container container;            /* Unidirectional relationship - ID of container which contains this backpack */
    private Container backpackContainer;    /* Unidirectional relationship - ID of container which represents backpack's storge */
    ...

    @NotNull
    @ManyToOne(fetch = FetchType.EAGER)
    @Fetch(FetchMode.SELECT)
    public Container getContainer() {
        return container;
    }


    @OneToOne(fetch = FetchType.EAGER)
    @Fetch(FetchMode.SELECT)
    public Container getBackpackContainer() {
        return backpackContainer;
    }
}

结果:

User(
    uid=2,
    name=admin,
    ....,

    container=Container(
        id=1,

        items=[
            Item(...),
            Item(...),
            Item(...),
            Item(...)
        ],

        backpacks=[
            Backpack(
                container=1,

                backpackContainer=Container(
                    id=3,
                    items=null, /* Problem! Shouldn't be empty array [] at least or array with items? */
                    backpacks=null /* Problem! Shouldn't be empty array [] at least or array with backpacks? */
                )
            )
        ]
    )
)

当我注释结果时,嵌套字段项目和背包为空,这表明存在一个巨大的问题。 Hibernate 倾向于使用空集而不是 null,我也不想到处添加 null 检查器。

什么可能导致此问题?

此外,这个层次结构并不是无限深的,用户的容器可以有任意数量的背包,但这些背包可能不包含其他背包。

最佳答案

唯一合乎逻辑的解释是,您正在同一个持久性上下文( session )中读取 User 图,在该持久性上下文中您保存了一个新的( transient )Container 实例,其中包含随后加载和组装 User 图时分配给 backpackContainer 引用的 nulls。

Hibernate 在保存实例时不会填充关联,但它会在从数据库加载实例时填充关联,因此您使用 null 来创建它,并且它在持久性上下文中仍然如此。当您随后阅读 User 图时,Hibernate 会重用持久化上下文中当前存在的所有内容,包括它分配给 backpackContainerContainer 实例字段。

所以,你有两个选择:

  • 如果您确实打算在同一个持久性上下文中使用双向关系的两侧(更简洁的方法),请更新双向关系的两侧;
  • 或者在读取用户之前简单地刷新并清除持久性上下文(如果您希望所有事情都发生在同一个事务中):

    entityManager.flush();
    entityManager.clear();
    

关于java - 急切获取嵌套(递归)对象 - Hibernate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44596690/

相关文章:

java - 两次之间的差异始终返回 2 或更大

java - Spring Data CrudRepository 应用自动级联类型

java - HQL意外的AST节点: {vector} when using an ArrayList as parameter

java - 从值中包含空格的字符串中提取键值

Java - 空指针异常

java - 如何使用枚举的简单性设计易于扩展的 API?

java - Hibernate 映射异常,使用注释

spring - JPA 和 Hibernate 中的 LazyInitializationException

java - 使用spring jpa获取数据

java - QueryDSL 将此路径作为源添加到查询异常