Отображение аннотаций против сопоставления 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
юридическое лицо. Такого рода работа Я мог удалить, как хотел, но не смог сохранить или вставить оценку. Я вроде ожидал, что это произойдет. Так что я просто устал от этого решения, и оно сработало.