Как сделать объект сущности управляемым, чтобы я мог удалить его? - PullRequest
1 голос
/ 16 сентября 2011

Это не работает - я всегда получаю исключение IllegalArgumentException с советом «попробуйте объединить отдельное и попробуйте удалить снова».

@PersistenceContext private EntityManager   em;
@Resource           private UserTransaction utx;
public void delete(EN entity) {
    if (entity == null) return;   // null-safe
    EN target = entity;
    try {
        if (!em.contains(entity)) {
            System.out.println("delete() entity not managed: " + entity);
            utx.begin();
            target = em.merge(entity);
            utx.commit();
            System.out.print("delete() this entity should now be managed: " + em.contains(target));
        }
        utx.begin();
        em.remove(target);
        utx.commit();
    } catch (RollbackException ex) {
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
    } catch (HeuristicMixedException ex) {
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
    } catch (HeuristicRollbackException ex) {
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
    } catch (SecurityException ex) {
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
    } catch (IllegalStateException ex) {
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
    } catch (NotSupportedException ex) {
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
    } catch (SystemException ex) {
        Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
    }
}

Выходной журнал показывает следующее:

INFO: delete() entity not managed: com.database.SomeTable[ id=2 ]  
INFO: delete() this entity should now be managed: false

Другими словами, merge () не возвращает управляемый объект.Может кто-нибудь заметить, что я сделал не так?

Второй вопрос: есть ли способ сделать это в одной транзакции, а не в двух?

Это с EclipseLink внутри GlassFish 3.1.

Ответы [ 2 ]

5 голосов
/ 16 сентября 2011

Этот фрагмент кода создает две транзакции:

if (!em.contains(entity)) {
    System.out.println("delete() entity not managed: " + entity);
    utx.begin();
    target = em.merge(entity);
    utx.commit();
    System.out.print("delete() this entity should now be managed: " + em.contains(target));
}
utx.begin();
em.remove(target);
utx.commit();

Хотя это правда, что сущность объединена в контекст постоянства, это верно только для первой транзакции, но не для обеих. Во второй транзакции контекст постоянства, связанный с транзакцией, снова найдет отсоединенный объект, переданный в качестве аргумента, в следующей строке:

em.remove(target);

с тех пор, как предыдущая utx.commit() отсоединила бы ссылку на target.

Чтобы исправить это, вы должны объединить сущность в контекст постоянства и удалить сущность в той же транзакции, прежде чем отсоединить ссылку:

if (!em.contains(entity)) {
    System.out.println("delete() entity not managed: " + entity);
    utx.begin();
    target = em.merge(entity);
    em.remove(target);
    utx.commit();
    System.out.print("delete() this entity should now be deleted: " + (!em.contains(target)) );
}
3 голосов
/ 16 сентября 2011

После фиксации ваш постоянный контекст должен исчезнуть. Таким образом, ваш println тест после коммита не удастся, потому что «целевой» объект больше не управляется.

Сделайте все свои вещи в одной транзакции, и это должно работать. Вам просто нужно начать транзакцию после начала попытки.

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