JPA: вопрос о слиянии объекта перед его удалением - PullRequest
11 голосов
/ 07 октября 2010

Я знаю, что должен слить сущность перед удалением, но я никогда не думал, что должен делать это внутри EJB Сначала у меня есть эти:

e = (Event) scholarBean.merge(e);
scholarBean.remove(e);

в моем управляемом бобе. Это дает мне эту ошибку

java.lang.IllegalArgumentException: Entity must be managed to call remove: com.scholar.entity.Event@998, try merging the detached and try the remove again.

Итак, я привожу эти две строки в свой сессионный компонент, и это работает. Есть идеи почему?

Managed Bean

myEJB.deleteEvent(e);

и

myEJB.java

public void deleteEvent(Event e){
    e = (Event) merge(e);
    em.remove(e);
}

Ответы [ 3 ]

17 голосов
/ 07 октября 2010

Я знаю, что должен слить сущность, прежде чем удалить ее

Не совсем. Объект, переданный для удаления, должен быть сущностью и не должен быть отделен. Это другое.

но я никогда не думал, что должен делать это внутри EJB. Сначала у меня есть эти (...)

Посмотрим, что вы делаете:

1: e = (Event) scholarBean.merge(e); 
2: scholarBean.remove(e);

Таким образом, в 1: вы вызываете EJB (очень вероятно, с контекстом персистентности в области транзакции), который объединяет сущность. Но затем метод завершается, транзакция фиксируется, контекст постоянства закрывается, и возвращаемая сущность снова отключается .

И в 2: вы передаете (все еще) отсоединенную сущность в EJB и пытаетесь remove ее, что недопустимо. И KaBOOM!

Итак, я привожу эти две строки в свой сессионный компонент, и это работает. Есть идеи почему?

Это работает, потому что вы сейчас работаете в рамках контекста постоянства, связанного с транзакцией JTA, и, таким образом, вы действительно передаете управляемую сущность remove.

7 голосов
/ 30 марта 2012

... и вы даже можете объединить их:

Вот так:

    public void deleteManCheck(ManCheck manCheck) {
    em.remove(em.merge(manCheck));
}
2 голосов
/ 31 июля 2012

У меня были те же проблемы с транзакциями, когда это использовалось в сервлете. При использовании EJB-компонента службы из MDB он работал нормально, поскольку транзакция была запущена до вызова EJB, но когда EJB-вызов поступил от сервлета, не было запущенной транзакции. Я решил это в своем веб-приложении, создав фильтр, который запускает и передает UserTransaction. Затем каждый вызов EJB-методов присоединяется к моей UserTransaction вместо запуска собственной транзакции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...