以正确的方式删除实体和关系(JPA)

发布于 2024-12-18 23:04:35 字数 1842 浏览 1 评论 0原文

我有一个实体 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

自此以后,行同陌路 2024-12-25 23:04:35

没关系,据我所知。不过,您有一些不正确的假设:

  1. em.remove(p_task) 不会抛出 ConstraintException。冲洗或去除就可以了。如果抛出此异常,唯一要做的就是回滚事务并关闭实体管理器,因为这会使实体管理器处于不一致的状态。因此,在将任务从类别中删除之前或之后删除它并没有多大区别。
  2. 您删除任务,但不删除该类别。那么为什么仍不附加该类别呢?

It's OK, AFAIK. You have some incorrect assumptions, though:

  1. em.remove(p_task) will not throw a ConstraintException. The flush od the removal will do. If this exception is thrown, the only thing to do is to rollback the transaction and close the entity manager anyway, because it will leave it in an inconsistent state. So deleting the task before or after removing it from its category doesn't make much difference.
  2. You remove a task, but don't remove tha category. So why wouldn't the category still be attached?
哭泣的笑容 2024-12-25 23:04:35

这是正确的做法。您必须从集合中删除任务才能确保集合的功能。

也许在合并之前检查 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文