0

我被困在我试图更新@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;
}

我正在尝试使用一组新任务更新现有标准。这需要删除所有现有任务并添加新任务。这是我的做法:

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 中非常基本的东西。

提前致谢。!

4

1 回答 1

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。一般来说,选择其中一种观点并坚持下去是明智的,也更直观。选择一个观点,定义了“控制”关系的实体,通过该实体应该应用任何修改。

在您的情况下,如果您认为 aCriteria包含拥有Tasks -您会将关系视为one-to-many。确定之后,就不需要在.java类Criteria引用了。您仅使用API 控制关系(但是,在数据库中创建的表确实有一个引用其包含的列)。TaskCriteriaTaskCriteria

于 2012-05-08T01:03:48.353 回答