我正在尝试在Hibernate控制的数据库中将子对象从一个父对象移动到另一个父对象。我在Hibernate通过@OneToMany
注释创建和控制的表上收到错误。希望有人知道解决这个问题。
我有两个对象,一个包含另一个的List。我们称他们为狗窝和狗。我正在做的是将Dog
从一个Kennel
移到另一个Kennel
:
Dog dog = dogService.getDog(dogId);
Kennel oldKennel = dog.getKennel();
if (oldKennel.getDogs().contains(dog)) {
oldKennel.getDogs().remove(dog);
}
Kennel newKennel = kennelService.getKennel(newKennelId);
newKennel.getDogs().add(dog);
dog.setKennel(newKennel);
涉及三个表:
-- Table is mapped to Kennel object
TABLE kennels (kennel_id int)
-- Table is a join table controlled by Hibernate
TABLE kennels_dogs (kennels_kennel_id int, dogs_dog_id int)
-- Table is mapped to Dog object
TABLE dogs (dog_id int)
我得到的具体错误是在联接表kennels_dogs
java.sql.BatchUpdateException: Duplicate entry '14' for key 'dogs_dog_id'
但是文件中只有一条带有该ID的记录 - 我正在尝试更新的记录。 Hibernate似乎正在做的是尝试插入 kennels_dogs
表中的记录,并在 DELETES 旧记录之前使用新值。
例如,假设{id = 14的Dog
位于Kennel
,ID = 12。我们希望将狗移动到狗窝,id = 47。手动,您可以使用以下命令执行此操作:
DELETE FROM kennels_dogs WHERE kennels_kennel_id=12 AND dogs_dog_id=12
INSERT INTO kennels_dogs (kennels_kennel_id, dogs_dog_id) VALUES (47, 12)
Hibernate所做的是以相反的顺序执行这些操作:
INSERT INTO kennels_dogs (kennels_kennel_id, dogs_dog_id) VALUES (47, 12)
DELETE FROM kennels_dogs WHERE kennels_kennel_id=12 AND dogs_dog_id=12
由于字段INSERT
上的唯一索引,dogs_dog_id
失败 - 表中已存在dogs_dog_id
= 12的记录。
似乎显而易见的解决方案可能是删除唯一索引,但不知道它为什么存在,我对删除它犹豫不决(从逻辑上讲,它是正确的 - Dog
只能在一个地方一次。)
任何人都有很好的解决方法吗?
答案 0 :(得分:0)
我觉得你有一个kennels_dogs连接表似乎很奇怪。对于@OneToMany来说,这不是必需的。根据Hibernate文档:
6.2.5。一对多关联
一对多关联通过外键将两个类的表链接起来 干预收集表。
我会确保您在Kennel课程中对狗集合进行@OneToMany(mappedBy = "dog")
注释,@ManyToOne
@JoinColumn(name = "kennel_id", nullable = false)
在你的Dog课上注明。