Hibernate - @ElementCollection - 奇怪的删除/插入行为 [英] Hibernate - @ElementCollection - Strange delete/insert behavior
问题描述
@Entity
public class Person {
@ElementCollection
@CollectionTable(name =PERSON_LOCATIONS,joinColumns = @JoinColumn( name =PERSON_ID))
私人列表<位置>位置;
[...]
}
@Embeddable
公共类位置{
[ ..]
}
考虑到以下类结构,当我尝试要将新位置添加到人员位置列表中,它总是会导致以下SQL查询:
从人员删除其中PERSON_ID =:idOfPerson
和
A lota'插入到PERSON_LOCATIONS表中
Hibernate(3.5.x / JPA 2)删除给定Person的所有关联记录,并重新插入所有以前的记录,再加上新记录。
我有这样的想法:equals / hashcode方法位置可以解决问题,但它不会改变任何内容。
任何提示都会被赞赏!
这个问题在页面中解释了关于J的 ElementCollection
PA wikibook:
CollectionTable中的主键
JPA 2.0规范不
提供了一种方法来定义Id
在
嵌入式
中。然而,要删除或
更新
ElementCollection
映射的元素,通常需要一些唯一的
键。否则,每次更新JPA提供者
时,
都需要从
CollectionTable
中删除实体中的所有内容
和
,然后插入值。因此,
JPA提供程序很可能会假设
,所有$ b $嵌入式中的b字段是唯一的,
与外键
(JoinColunm
(一个或多个))。然而,这可能是
低效率,或者如果
@Entity public class Person { @ElementCollection @CollectionTable(name = "PERSON_LOCATIONS", joinColumns = @JoinColumn(name = "PERSON_ID")) private List<Location> locations; [...] } @Embeddable public class Location { [...] }
Given the following class structure, when I try to add a new location to the list of Person's Locations, it always results in the following SQL queries:
DELETE FROM PERSON_LOCATIONS WHERE PERSON_ID = :idOfPerson
And
A lotsa' inserts into the PERSON_LOCATIONS table
Hibernate (3.5.x / JPA 2) deletes all associated records for the given Person and re-inserts all previous records, plus the new one.
I had the idea that the equals/hashcode method on Location would solve the problem, but it didn't change anything.
Any hints are appreciated!
解决方案The problem is somehow explained in the page about
ElementCollection
of the JPA wikibook:Primary keys in CollectionTable
The JPA 2.0 specification does not provide a way to define the
Id
in theEmbeddable
. However, to delete or update a element of theElementCollection
mapping, some unique key is normally required. Otherwise, on every update the JPA provider would need to delete everything from theCollectionTable
for theEntity
, and then insert the values back. So, the JPA provider will most likely assume that the combination of all of the fields in theEmbeddable
are unique, in combination with the foreign key (JoinColunm
(s)). This however could be inefficient, or just not feasible if theEmbeddable
is big, or complex.And this is exactly (the part in bold) what happens here (Hibernate doesn't generate a primary key for the collection table and has no way to detect what element of the collection changed and will delete the old content from the table to insert the new content).
However, if you define an
@OrderColumn
(to specify a column used to maintain the persistent order of a list - which would make sense since you're using aList
), Hibernate will create a primary key (made of the order column and the join column) and will be able to update the collection table without deleting the whole content.Something like this (if you want to use the default column name):
@Entity public class Person { ... @ElementCollection @CollectionTable(name = "PERSON_LOCATIONS", joinColumns = @JoinColumn(name = "PERSON_ID")) @OrderColumn private List<Location> locations; ... }
References
- JPA 2.0 Specification
- Section 11.1.12 "ElementCollection Annotation"
- Section 11.1.39 "OrderColumn Annotation"
- JPA Wikibook
这篇关于Hibernate - @ElementCollection - 奇怪的删除/插入行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!