Удалить сущность и отношения правильным способом (JPA) - PullRequest
1 голос
/ 30 ноября 2011

У меня есть сущность Task и дао для нее: TaskDao. Объект Task имеет сопоставление ManyToOne с категорией. Когда я удаляю задачу, мне также нужно удалить задачу из коллекции в категории:

// 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);
}

Ответы [ 2 ]

2 голосов
/ 30 ноября 2011

Все нормально, AFAIK.Однако у вас есть неверные предположения:

  1. em.remove (p_task) не вызовет исключение ConstraintException.Сброс удаления будет делать.Если выдается это исключение, единственное, что нужно сделать, - это откатить транзакцию и все равно закрыть менеджер сущностей, потому что он оставит его в несогласованном состоянии.Поэтому удаление задачи до или после удаления ее из категории не имеет большого значения.
  2. Вы удаляете задачу, но не удаляете эту категорию.Так почему же категория по-прежнему не будет прикреплена?
1 голос
/ 30 ноября 2011

Это правильный подход.Вы должны удалить задачу из набора, чтобы обеспечить функциональность наборов.

Возможно, перед слиянием проверьте, действительно ли p_task отсоединен, и если задачи c

...