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, а не запускает его собственную транзакцию.