JPA: вопрос о объединении объекта перед его удалением
Я знаю, что мне нужно объединить объект перед его удалением, но я никогда не думал, что мне нужно это сделать в EJB. Сначала у меня есть:
e = (Event) scholarBean.merge(e);
scholarBean.remove(e);
в моем управляемом bean. Это дает мне эту ошибку
java.lang.IllegalArgumentException: Entity must be managed to call remove: [email protected], try merging the detached and try the remove again.
Итак, я привожу эти две строки внутри сеанса bean, и он работает. Любая идея почему?
Managed Bean
myEJB.deleteEvent(e);
и
myEJB.java
public void deleteEvent(Event e){
e = (Event) merge(e);
em.remove(e);
}
Ответы
Ответ 1
Я знаю, что мне нужно объединить объект перед его удалением
Не совсем. Объект, переданный для удаления, должен быть сущностью и не должен быть отсоединен. Это другое.
но я никогда не думал, что должен сделать это в EJB. Сначала у меня есть эти (...)
Посмотрите, что вы делаете:
1: e = (Event) scholarBean.merge(e);
2: scholarBean.remove(e);
Итак, в 1:
вы вызываете EJB (скорее всего, с контекстом константы транзакций), который объединяет объект. Но затем метод заканчивается, транзакция фиксируется, Контекст сохранения закрывается, снова возвращает возвращаемый объект отсоединенный.
И в 2:
вы передаете (неподвижный) отдельный объект в EJB и пытаетесь remove
его, что запрещено. И KaBOOM!
Итак, я привожу эти две строки внутри сеанса bean, и он работает. Любая идея почему?
Это работает, потому что теперь вы работаете в контексте контекста персистентности, связанного с транзакцией JTA, и таким образом вы передаете управляемый объект в remove
.
Ответ 2
... и вы можете даже объединить их:
Так же:
public void deleteManCheck(ManCheck manCheck) {
em.remove(em.merge(manCheck));
}
Ответ 3
У меня были те же транзакционные проблемы, когда это было использовано в сервлете. При использовании EJB-service- bean из MDB он работал нормально, поскольку транзакция была запущена до вызова EJB, но когда EJB-вызов пришел из сервлета, не было никакой транзакции.
Я решил это в своем webapp, создав фильтр, который запускается и компилируется UserTransaction. Затем каждый вызов EJB-методов соединяет мое UserTransaction, а не запускает его собственную транзакцию.