【问题标题】:JPA EclispeLink Insert/Persist replaces null list with emptylistJPA EclispeLink Insert/Persist 用空列表替换空列表
【发布时间】:2015-11-22 21:00:52
【问题描述】:

我有两个实体PersonPersonImage

@Entity
public class Person {

....

    @OneToMany(mappedBy = "person", cascade = { CascadeType.PERSIST,
            CascadeType.REMOVE }, orphanRemoval = true, fetch = FetchType.LAZY)
    private List<PersonImage> images;

....
}

@Entity
public class PersonImage {

....

    @Lob
    private byte[] content;

    @ManyToOne
    private Person person;
....

}

问题是,当我插入Person(没有附加任何图像)之前,插入images 列表是null。但是插入列表后是一个空的IndirectList 实例。我在调试时可以看到它从null 更改为{[]}

为什么会这样?我希望它是 null 或未初始化的 IndirectList(在调试时应该看起来像 {IndirectList: not instantiated})。我怎样才能做到这一点?

【问题讨论】:

  • 为了让 JPA 实现保留关于集合是空还是 null 的知识,它必须在表中有一列来存储该信息。我怀疑 EclipseLink 支持这一点,所以大概只是实例化一个空列表
  • @NeilStockton AFAIK 一个 JPA 实现应该假定任何惰性集合都未初始化,并且在访问时它会对引用的表进行查询。所以我假设列表最初是空的,但也被标记为未初始化 - 还是我弄错了?
  • 您指的是 Hibernate 如何做到这一点,并且认为这是不正确的。其他实现默认使用字节码增强,因此没有未初始化的代理。 EclipseLink 默认是怎么做的我不知道。
  • @NeilStockton 嗯,我主要使用 Hibernate,但实际上我并没有假设它在 EclipseLink 中的工作方式相同。仅从逻辑的角度来看,不知道惰性集合是否具有任何元素的 JPA 实现应该具有 some 手段来检测它(我很确定这是JPA 规范)——事实上 EclipseLink 似乎有类似的东西,因为调试器显示了不同的字符串表示。
  • 知道它是否有一些元素不是问题。好的,所以它没有元素。这并不是说它是 null 还是空列表……回到我的第一条评论。

标签: java jpa persistence eclipselink


【解决方案1】:

猜你看到了 org.eclipse.persistence.indirection.IndirectList 实例,它在内部用于表示这种 1:N 关系。 它在内部保存 Vector 委托实例,并且 IndirectList 和 Vector 在调用 persist 时都被实例化。这是默认的 EclipseLink 行为。

空值和空列表1:N关系的语义相同:没有与Person关联的PersonImage实例。您是否有一些严肃的理由将 null 与空列表区分开来?如果是这样,您必须将其保存在单独的属性中。

【讨论】:

    猜你喜欢
    • 2015-06-26
    • 1970-01-01
    • 2019-07-26
    • 2020-03-31
    • 2020-10-14
    • 1970-01-01
    • 1970-01-01
    • 2021-06-27
    • 1970-01-01
    相关资源
    最近更新 更多