当前位置: 首页 > 面试题库 >

Hibernate-@ElementCollection-奇怪的删除/插入行为

澹台庆
2023-03-14
问题内容

@Entity
public class Person {

    @ElementCollection
    @CollectionTable(name = "PERSON_LOCATIONS", joinColumns = @JoinColumn(name = "PERSON_ID"))
    private List<Location> locations;

    [...]

}

@Embeddable
public class Location {

    [...]

}

给定以下类结构,当我尝试将新位置添加到“人的位置”列表中时,它总是导致以下SQL查询:

DELETE FROM PERSON_LOCATIONS WHERE PERSON_ID = :idOfPerson

A lotsa' inserts into the PERSON_LOCATIONS table

Hibernate(3.5.x / JPA 2)删除给定Person的所有关联记录,然后重新插入所有以前的记录以及新的记录。

我有一个想法,即Location上的equals / hashcode方法可以解决此问题,但是它没有任何改变。

任何提示表示赞赏!


问题答案:

在有关ElementCollectionJPA Wikibook 的页面中以某种方式解释了该问题:

CollectionTable中的主键

JPA 2.0规范不提供一种方式来定义IdEmbeddable但是,要删除或更新ElementCollection映射的元素,
通常需要一些唯一的键。否则,在每次更新的JPA的供应商将需要删除一切从
CollectionTableEntity,然后插入值回。

因此,JPA提供程序将最有可能假定中的所有字段的Embeddable组合与外键组合是唯一的JoinColunm。但是,这可能效率低下,或者如果Embeddable规模较大或过于复杂,那将是不可行的。

而这恰好是这里的内容(粗体部分)(Hibernate不会为集合表生成主键,也无法检测集合中 哪些元素 已更改,并且将删除表中的旧内容以插入新内容)。

但是, 如果 定义一个@OrderColumn(以指定用于维护列表的持久顺序的列-
由于使用List,这将很有意义),则Hibernate将创建一个 主键 (由 order列和join列组成
)并且能够在不删除全部内容的情况下更新收藏表。

这样的事情(如果您想使用默认的列名):

@Entity
public class Person {
    ...
    @ElementCollection
    @CollectionTable(name = "PERSON_LOCATIONS", joinColumns = @JoinColumn(name = "PERSON_ID"))
    @OrderColumn
    private List<Location> locations;
    ...
}

参考文献

  • JPA 2.0规范
    • 第11.1.12节“ ElementCollection批注”
    • 第11.1.39节“ OrderColumn注释”
  • JPA Wikibook
    • Java持久性/ ElementCollection


 类似资料:
  • 我正在使用ListView。向ListView添加新项很容易,但如何删除? 我通过以下方式构建ListView: Listcell Y的一个实例在setGraphics中设置了一个标签。要从我的观察列表中删除与之关联的字符串,我添加了一个MouseEvent处理程序: 虽然这段代码通过从ObservableList中删除每个单击的项目来工作,但listView的行为很奇怪。每次单击标签时,它都会成

  • 问题内容: 请考虑以下示例Java类(下面的pom.xml): 我写一个FileOutputStream,然后尝试删除该文件, 而不先关闭Stream 。这是我最初的问题,当然是错误的,但它导致了一些奇怪的发现。 在Windows 7上运行主方法时,它将产生以下输出: 为什么第一次调用Files.delete()不会引发异常? 为什么以下对Files.exist()的调用返回false? 为什么无

  • 参考Symfony 2关于文件上传的Cookbook,我尝试使用Doctrine的@PostRemove事件监听器在文件从数据库中删除后删除文件。 Document.php File.php 数据库: 当我删除ID为1的文档时,不知何故学说也解除关联ID为1的文件。 据我所知,这些步骤导致了这种奇怪的行为: 1-条令的将调用方法,该方法反过来调用 2-在中,参与者根据文档的id删除了文档的文件,然

  • 在我的应用程序中,左侧有一个,我根据中的选择更新右侧的窗格。一个非常直接的场景。当选择为空时,我会在窗格中显示类似“请进行选择”的消息,即我也会在 ,以防用户单击某些。侦听器还附加到所选的的,以防用户没有单击某些项目,但所选项目的值因某种原因而更改。用户可以通过单击其中的删除按钮来删除特定项目。在任何时候,用户可以点击更新按钮来更新显示当前选择的标签内容,以防我的处理程序错过了一些事件。 在这个简

  • 我有以下代码来解析一个JSON文件: 要处理以下JSON文件: 如果我执行此代码,我将收到以下错误: 所以我开始一步一步地调试应用程序,看看part processing()中的哪个代码部分抛出了这个异常。令人惊讶的是,那里的所有代码都正常执行:没有抛出异常,也没有返回结果I except。 更让我惊讶的是,当我稍微改变第一种方法的代码时,它可以在不产生异常的情况下工作。 我不知道println方

  • 问题内容: 这是成功的一个例子: 请注意,insert-select中的第二列是明确为null。 这是一个失败的示例: 请注意,在此示例中,我得到了,而不是第二列中的显式null ,它从delete语句作为null返回。 如果两个值都为null,那么第二个示例为什么会因为这个错误而困扰我?我已经仔细检查了两者,这是唯一的功能差异。 问题答案: 在第一个示例中,您为语句提供了一个 尚未输入类型的 N