【发布时间】:2014-10-10 01:37:48
【问题描述】:
我正在尝试将子对象从一个父对象移动到另一个父对象,该对象位于由 Hibernate 控制的数据库中。我在 Hibernate 通过 @OneToMany 注释创建和控制的表上遇到错误。希望有人知道解决此问题的方法。
我有两个对象,一个包含另一个的列表。让我们称它们为犬舍和狗。我正在做的是将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 似乎在做的是尝试INSERT在kennels_dogs 表中使用新值DELETES旧记录之前的记录。
例如,假设 id=14 的 Dog 在 id=12 的 Kennel 中。我们想将 Dog 移动到 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 只能在一个地方时间。)
谁有解决这个问题的绝妙方法?
【问题讨论】: