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

У меня есть сущность 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 для удаления каждого старого ответа перед объединением запроса, но, похоже, должен быть более чистый способ.

Ответы [ 4 ]

1 голос
/ 15 декабря 2009

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

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

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

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

1 голос
/ 06 мая 2010

Использование EclipseLink и помещение аннотации @PrivateOwned в answerList может помочь.

0 голосов
/ 06 мая 2010

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

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

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

0 голосов
/ 15 декабря 2009

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

...