Отображение аннотаций против сопоставления XML и удаления объекта

Я работаю над переносом проекта в чистое сопоставление на основе аннотаций JPA из сопоставления XML и столкнулся с проблемой при попытке удалить (удалить) и сущность, и ее дочерние элементы. Он работает с отображением XML и не работает с отображением аннотаций.

XML-отображение выглядит так:

<set name="evaluations" order-by="evalDate desc" table="Evaluation" lazy="true" inverse="true" cascade="delete">
    <key column="requestId" />
    <one-to-many class="org.stuff.model.Evaluation" />
</set>

Насколько я могу судить, отображение аннотации таково:

@OneToMany(orphanRemoval=true)
@JoinColumn(name = "requestId")
@OrderBy("evalDate DESC")
private Set<Evaluation> evaluations = new TreeSet<>();

Это однонаправленные отношения.

Код JPA для удаления объекта:

ServiceRequest sr = em.getReference(ServiceRequest.class, id);
em.remove(sr);

Где выше Evaluation является дочерним объектом ServiceRequest, Hibernate 4.3.7 - это JPA Impl, который я использую, работающий на WildFly 8.2.

Если Hibernate настроен на запрет SQL, выполнение удаления с отображением аннотации на месте Hibernate создает запрос для поиска ссылки на сущность, а затем, когда remove называется это произвести обновление, пытаясь обновить дочернюю запись в Evaluation FK возвращается к ServiceRequest, чтобы быть нулевым:

Hibernate: update Evaluation set requestId=null where requestId=?

И это взрывается, потому что есть not null ограничение на requestId,

Если я делаю ту же операцию, используя отображение XML (см. Фрагмент выше), она работает просто отлично. Все дочерние объекты удаляются вместе с родительским. а Hibernate только производит selects а также deletes, если никогда не пытается обновить что-либо.

Такое ощущение, что у меня неправильное отображение аннотации, но я не могу понять, где я ошибся. Пожалуйста помоги.

3 ответа

Решение

Конфигурация xml на самом деле говорит, что отношения между вашим ServiceRequest и Set являются двунаправленными, потому что inverse = "true".

Но ваша аннотация JPA является однонаправленной. так что это должно работать (отредактировано после комментария ОП)

@OneToMany(orphanRemoval=true,mappedBy="requestId")
@OrderBy("evalDate DESC")
private Set<Evaluation> evaluations = new TreeSet<>();

Вот mappedBy="requestId"говорит Hibernate, что это сторона владельца отношений. Так что он выдаст заявление об удалении оценки.

Я думаю, что вам нужно указать каскадную аннотацию. Остерегайтесь этой проблемы, хотя.

Спасибо @troy за какое-то направление. Добавление только каскада не сработало, но добавление insertable=flase, updateable=false сделал. Таким образом, отображение аннотации теперь выглядит так:

@OneToMany(cascade=CascadeType.REMOVE)
@JoinColumn(name = "requestId", insertable=false, updatable=false)
@OrderBy("evalDate DESC")
private Set<Evaluation> evaluations = new TreeSet<>();

Я не уверен точно, почему это работает, поэтому, если кто-то может объяснить это, я был бы очень благодарен.

Я попал сюда скорее косвенно. Сначала я добавил nullable-false к этому отображению, и когда я развернул его, Hibernate пожаловался на это и сказал мне, что мне нужно добавить insert=false update=false в requestId на Evaluation юридическое лицо. Такого рода работа Я мог удалить, как хотел, но не смог сохранить или вставить оценку. Я вроде ожидал, что это произойдет. Так что я просто устал от этого решения, и оно сработало.

Другие вопросы по тегам