1 Reply Latest reply on Aug 20, 2008 11:21 PM by nonreva

    deleted entity passed to persist exception ???

    elkner

      Hmmm, is it not allowed to create and persist an entity and later to delete it within the same JTA?

      What I [need to] do is:
      1) read the header of a file and [re]populate/merge in tree nodes
      2) read the remaining part of the file and fill the tree nodes with content/merge new content
      3) finally remove all nodes, which have no children (i.e. no content and subnodes) - for max. reduction use deepest first strategy

      The SLSB code snippet using 4.0.3SP1 vanilla:

      @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
       public Catalog importCatalog(CatalogImportProfile profile,
       byte[] data, String clientId)
       {
       if (profile == null || data == null || data.length == 0) {
       return null;
       }
       CatalogImporter ci = new CatalogImporter(em, profile);
       ci.readAndMerge(data);
       if (profile.getId() == 0) {
       em.persist(profile);
       } else {
       em.merge(profile);
       }
       em.flush();
       if (profile.isEnabled(Option.G_DELETE_EMPTY)) {
       Query q = em.createQuery("SELECT COUNT(*) FROM Article a "
       + "WHERE a.group.id=:gid");
       List tl = em.createQuery("FROM ProductGroup g "
       + "WHERE g.parentGroup IS NULL AND g.details.catalog.id=:id")
       .setParameter("id", profile.getCatalog().getId())
       .getResultList();
       for (int i=tl.size()-1; i >= 0; i--) {
       if (isEmpty((ProductGroup) tl.get(i), q)) {
       em.remove(tl.get(i));
       }
       }
       em.flush();
       }
       return profile.getCatalog();
       }
      


      But with this one I get:
      org.hibernate.ObjectDeletedException: deleted entity passed to persist: [foo.bar.ProductGroup#]
      at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:90)
      at org.hibernate.impl.SessionImpl.firePersistOnFlush(SessionImpl.java:610)
      at org.hibernate.impl.SessionImpl.persistOnFlush(SessionImpl.java:604)
      at org.hibernate.engine.CascadingAction$9.cascade(CascadingAction.java:225)
      at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:213)
      at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:157)
      at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:108)
      at org.hibernate.engine.Cascade.cascade(Cascade.java:248)
      at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:130)
      at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:121)
      at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:65)
      at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
      at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:905)
      at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:185)
      at org.jboss.ejb3.entity.InjectedEntityManager.flush(InjectedEntityManager.java:122)
      at foo.bar.SLSB.importCatalog(SLSB.java:191)
      ...
      where SLSB.java:191 is the second em.flush();

      So is it a hibernate bug? At least in the specs I could not find, that it is forbidden to persist and delete the same entity withing the same JTA ...

        • 1. Re: deleted entity passed to persist exception ???

          With Jboss 4.2.2GA I am experiencing a similar problem.

          The gist of it is (within a single container managed transaction):
          1. I remove an item from this collection...

           @OneToMany(mappedBy = "ivrAccount", cascade = CascadeType.ALL)
           public Collection<LinkedAccountBean> linkedAccounts = new HashSet<LinkedAccountBean>();

          2. I perform a query on another bean...

           try {
           System.out.println("************ 1 **************");
           String number = accountReference.getNumber();
           System.out.println("************ 2 ************** " + number);
          
           Query q= em.createNamedQuery(
           BankAccountReference.FIND_BY_ACCOUNT_NUMBER_QUERY)
           .setParameter("number", number);
           System.out.println("************ 3a **************");
           Object o = q.getSingleResult();
           System.out.println("************ 3b **************");
           linkedAccount.accountReference = (BankAccountReference) o;
           System.out.println("************ 3c **************");
          
           } catch (NoResultException ex) {
           System.out.println("************ 4 **************");
           linkedAccount.accountReference = BankAccountReferenceHelper
           .createBankAccountReference(em, accountReference);
           } catch (EntityNotFoundException ex) {
           System.out.println("************ XXXXX **************");
           throw ex;
           }
          

          This results in an EntityNotFoundException...
          14:29:51,593 ERROR [STDERR] Caused by: javax.persistence.EntityNotFoundException: deleted entity passed to persist: [ae.
          hilal.j2ee.entity.account.LinkedAccountBean#<null>]
          14:29:51,593 ERROR [STDERR] at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityM
          anagerImpl.java:613)
          14:29:51,593 ERROR [STDERR] at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:99)
          14:29:51,593 ERROR [STDERR] at ae.hilal.j2ee.session.helper.LinkedAccountHelper.update(LinkedAccountHelper.java:40)
          14:29:51,593 ERROR [STDERR] at ae.hilal.j2ee.session.helper.LinkedAccountHelper.createLinkedAccount(LinkedAccountHel
          per.java:123)
          

          This can be seenn from the following output:
          16:40:02,156 INFO [STDOUT] ************ 1 **************
          16:40:02,156 INFO [STDOUT] ************ 2 ************** 4444444444
          16:40:02,156 INFO [STDOUT] ************ 3a **************
          16:40:02,156 INFO [STDOUT] ************ XXXXX **************


          this appears to me to be the cause of a
          14:29:51,593 ERROR [STDERR] javax.ejb.EJBTransactionRolledbackException: deleted entity passed to persist: [ae.hilal.j2e
          e.entity.account.LinkedAccountBean#<null>]
          14:29:51,593 ERROR [STDERR] at org.jboss.ejb3.tx.Ejb3TxPolicy.handleInCallerTx(Ejb3TxPolicy.java:87)
          ...


          What is ironic about this is that if I do the remove after the query it works... i.e. I collect up the objects that need to be removed and I remove them after I have done additions and updates to the collection.

          Whilst this workaround appears to solve the problem in this particular instance, there is only an indirect relationship between the object deleted and the query. Furthuermore I am not convinced that if further queries were to follow the delete (untested scenarios) that these might also lead to problemd.

          The EJB persistence specification (A.4) says that
          Replaced EntityNotFoundException with NoResultException in
          entities might be returned, and exception should be recoverable.
          , so I am also wondering why such an exception is still being propagated from a query (if my understanding of the stack trace is correct)