我遇到了我正在尝试更新@OneToMany映射的问题。
问题: 我有2个实体:标准和任务。标准可以包含多个任务。
class Criteria {
@OneToMany(mappedBy = "criteria", cascade = { CascadeType.PERSIST,
CascadeType.MERGE, CascadeType.REFRESH }, fetch = FetchType.LAZY)
@Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE,
org.hibernate.annotations.CascadeType.ALL,
org.hibernate.annotations.CascadeType.MERGE,
org.hibernate.annotations.CascadeType.PERSIST })
private Set<Task> tasks;
}
class Task {
@ManyToOne
@JoinColumn(name = "CRITERIA_ID", nullable=false)
private Criteria criteria;
}
我正在尝试使用新的任务集更新现有的Criteria。这需要删除所有现有任务并添加新任务。 我正在做的是:
criteriaDao.persist(criteria);
Set<Task> existingTasks=criteria.getTasks();
if(existingTasks != null) {
for (Task task : existingTasks) {
task.setCriteria(null);
}
criteria.setTasks(tasks);
//more code which sets criteria for each task - this works if i try to save new criteria with new tasks
}
Hibernate抛出异常:
Caused by: java.sql.BatchUpdateException: ORA-00001: unique constraint (CCA_DEV_5.TASK__UN) violated
抛出此异常是因为它没有删除现有任务。
如果我只删除所有任务,它可以完美地工作,并使用以下代码删除给定条件的所有任务:
criteriaDao.persist(criteria);
Set<Task> existingTasks=criteria.getTasks();
if(existingTasks != null) {
for (Task task : existingTasks) {
task.setCriteria(null);
}
}
我在添加新任务和更多内容之后尝试了使用合并的所有选项,但似乎没有任何东西适合我。我很难被困在这里,肯定会遗漏一些非常基本的Hibernate。
提前致谢。
答案 0 :(得分:0)
在Task
课程中,您根本不应该提及Criteria
。只需删除它及其注释即可。
然后,不要设置Criteria
引用的Task
,因为此引用不再存在,只需使用criteria.setTasks(newTasks)
并保存criteria
。
让我解释一下。 Criteria
和Task
之间的关系是Criteria 1 --- n Tasks
- 1到n。现在,您可以调用one-to-many
关系,然后可以将其称为many-to-one
,具体取决于您的观点。从Criteria
视角来看,它是one-to-many
,从Task
的角度来看 - 它是many-to-one
。一般来说,选择一个这些观点并且坚持是明智和直观的。选择一个观点,定义“控制”应该应用任何修改的关系的实体。
在您的情况下,如果您将Criteria
视为包含或拥有一组Task
- 您将对待这种关系为one-to-many
。在确定之后,Criteria
的java类中不需要Task
引用。您只能使用Criteria
API(在数据库中为Task
创建的表格来控制关系,但是,确实有一个列引用其包含Criteria
)。