以正确的方式删除实体和关系(JPA)
我有一个实体 Task 和它的 dao:TaskDao。任务实体具有到类别的多对一映射。当我删除任务时,我还需要从类别中的集合中删除该任务:
// remove() method in TaskDao
public void remove (Task p_task) {
// p_task is Detached, p_task.getCategory() is Detached
p_task = em.merge(p_task);
// p_task is Attached, p_task.getCategory() is Attached
em.remove(p_task);
// p_task is Detached, p_task.getCategory() is Attached
p_task.getCategory().removeTask(p_task);
}
注释指示(此时)p_task 和/或 p_task.category 是否已附加/分离。首先让我解释一下为什么我选择这样的陈述顺序。首先,我需要合并 p_task,以便附加 p_task.category,并且为了删除 p_task,它需要合并。 p_task 最后从类别集合中删除,因为 em.remove(p_task) 可能会抛出 ConstraintException,在这种情况下,不应从类别集合中删除该任务。
这是正确的做法吗?另外,令我惊讶的是,在 em.remove(p_task) 之后,p_task.category 仍然被附加。
编辑:我应该提供实体类中的一些代码。
public class Task implements Serializable {
@JoinColumn(name = "category_id", referencedColumnName = "id")
@ManyToOne(cascade = CascadeType.MERGE, optional = false)
private Category category;
}
public class Category implements Serializable {
@OneToMany(cascade = CascadeType.MERGE, mappedBy = "category")
private List<Task> taskCollection;
public void addTask (Task p_task) {
if (taskCollection == null) {
taskCollection = new ArrayList<>();
}
if (!taskCollection.contains(p_task)) {
taskCollection.add(p_task);
}
}
public void removeTask (Task p_task) {
taskCollection.remove(p_task);
}
}
在以下代码中,p_task 被从category.taskCollection 中删除,同时事务被回滚:
// remove() method in TaskDao
public void remove (Task p_task) {
p_task = em.merge(p_task);
p_task.getCategory().removeTask(p_task); // will not be rolled back if em.remove(p_task) throws an exception
em.remove(p_task);
}
I have an entity Task and a dao for it: TaskDao. A Task entity has a ManyToOne mapping to Category. When I delete a Task, I also need to remove the Task from the collection in Category:
// remove() method in TaskDao
public void remove (Task p_task) {
// p_task is Detached, p_task.getCategory() is Detached
p_task = em.merge(p_task);
// p_task is Attached, p_task.getCategory() is Attached
em.remove(p_task);
// p_task is Detached, p_task.getCategory() is Attached
p_task.getCategory().removeTask(p_task);
}
The comments indicate (at that point) if the p_task and/or p_task.category are Attached/Detached. First let me explain why I choose this order of statements. First I need to merge the p_task, so that p_task.category gets attached and also in order to remove the p_task it need the be merged. The p_task is removed from the category collection at the end, because em.remove(p_task) can throw an ConstraintException, it that case the task should not be removed from the category collection.
Is this the right approah? Also, I was surprised that after em.remove(p_task), p_task.category is still attached.
Edit: I should give some code from the entity classes.
public class Task implements Serializable {
@JoinColumn(name = "category_id", referencedColumnName = "id")
@ManyToOne(cascade = CascadeType.MERGE, optional = false)
private Category category;
}
public class Category implements Serializable {
@OneToMany(cascade = CascadeType.MERGE, mappedBy = "category")
private List<Task> taskCollection;
public void addTask (Task p_task) {
if (taskCollection == null) {
taskCollection = new ArrayList<>();
}
if (!taskCollection.contains(p_task)) {
taskCollection.add(p_task);
}
}
public void removeTask (Task p_task) {
taskCollection.remove(p_task);
}
}
In the following code the p_task is removed from category.taskCollection, while the transaction is rolled back:
// remove() method in TaskDao
public void remove (Task p_task) {
p_task = em.merge(p_task);
p_task.getCategory().removeTask(p_task); // will not be rolled back if em.remove(p_task) throws an exception
em.remove(p_task);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
没关系,据我所知。不过,您有一些不正确的假设:
It's OK, AFAIK. You have some incorrect assumptions, though:
这是正确的做法。您必须从集合中删除任务才能确保集合的功能。
也许在合并之前检查 p_task 是否确实分离,以及任务是否 c
Its the right aproach. You have to remove the task from the set to ensure the sets functionality.
Maybe check if p_task is realy detached before merging it and if the tasks c