Почему JPA не удаляет принадлежащие объекты, если объект-владелец теряет ссылку на них?

StackOverflow https://stackoverflow.com/questions/1133179

  •  16-09-2019
  •  | 
  •  

Вопрос

У меня есть объект JPA «Запрос», которому принадлежит список ответов (также объекты JPA).Вот как это определено в Request.java:

@OneToMany(cascade= CascadeType.ALL, mappedBy="request")
private List<Answer> answerList;

И в Answer.java:

@JoinColumn(name = "request", referencedColumnName="id")
@ManyToOne(optional = false)
private Request request;

В ходе выполнения программы в список ответов запроса могут быть добавлены или удалены ответы, а также может быть заменен фактический объект списка.Моя проблема такова:когда я объединяю запрос с базой данных, объекты ответа, которые использовал быть в списке, сохраняются в базе данных, то есть объекты ответа, на которые запрос больше не содержит ссылку (косвенно, через список), не удаляются.

Это не то поведение, которое мне нужно, поскольку если я объединяю запрос в базу данных, а затем получаю его снова, его список ответов может не совпадать.Я делаю какую-то ошибку в программировании?Существует ли аннотация или настройка, которая гарантирует, что ответы в базе данных будут именно ответами в списке запросов?

Решение состоит в том, чтобы сохранить ссылки на исходный список ответов, а затем использовать EntityManager для удаления каждого старого ответа перед объединением запроса, но похоже, что должен быть более чистый способ.

Это было полезно?

Решение

В JPA 1.0 то, что вы хотите сделать, не может быть выполнено JPA.Проще говоря, все управление отношениями должно выполняться приложением, включая удаление всех потерянных элементов из коллекций (именно это вы и пытаетесь сделать).

В JPA 2.0 они поддерживаются (хотя подробностей я не знаю), но в зависимости от вашей реализации обновление может быть непростым или невозможным.

Вы также можете использовать что-то вроде Hibernate напрямую, но при этом использовать множество аннотаций JPA 1.0 и т. д.Я также не могу предоставить подробную информацию об этом.

В моем случае я написал общий код для автоматического объединения коллекций посредством отражения.

Другие советы

Использование EclipseLink и добавление аннотации @PrivateOwned в список ответов поможет.

Недопустимо указывать дополнительные свойства в отображаемом отношении.Вместо этого вы можете использовать аннотацию @DependentElement в Request.

Если вы используете Hibernate в качестве поставщика JPA, вы можете добавить

@Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)

в списке ответов.Это будет работать в дополнение к аннотациям JPA, которые вы там уже используете.JPA 2 (большинство/все поставщики JPA в настоящее время не имеют готовой к использованию реализации) может сделать это самостоятельно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top