views:

373

answers:

2

I'm running into a problem with Hibernate where when trying to delete a group of Entities I encounter the following error:

javax.persistence.EntityNotFoundException: deleted entity passed to persist: [com.locuslive.odyssey.entity.FreightInvoiceLine#<null>]

These are not normally so difficult to track down as they are usually caused by an entity being deleted but not being removed from a Collection that it is a member of.

In this case I have removed the entity from every list that I can think of (it's a complex datamodel). I've put JBoss logging into Trace and I can see the collections that are being cascaded. However I can't seem to find the Collection containing the entity that I'm deleting.

Does anyone have any tips for resolving this particular Exception? I'm particularly looking for ways to identify what might be the owning Collection.

Thanks.

+1  A: 

Finally found it, and it's exactly the sort of frustrating "find the list" that I had expected.

The code that was performing the delete was extending Seam's EntityHome.

public class FreightInvoiceHome extends EntityHome<FreightInvoice> {
    public void deleteLine(FreightInvoiceLine freightInvoiceLine) {
      getEntityManager().remove(freightInvoiceLine);
      freightInvoiceLine.getShipInstrLineItem().getFreightInvoiceLines().remove(freightInvoiceLine);

      /* These next two statements are effectively performing the same action on the same FreightInvoice entity
       * If I use the first one then I get the exception. If I use the second one then all is ok.
       */
      getInstance().getFreightInvoiceLines().remove(freightInvoiceLine);
      //freightInvoiceLine.getFreightInvoice().getFreightInvoiceLines().remove(freightInvoiceLine);
    }
}

I had suspected that this might have been caused by a dodgy equals() / hashcode() but after replacing both there is no difference.

Happy to change the accepted to someone else if they can explain the difference between the two.

Damo
+1  A: 

I would suggest doing the

getEntityManager().remove(freightInvoiceLine);

as the last step. I think it is a good practice, first to remove the child from any collections and then actually delete it. It will save headaches in many cases.

Petar Minchev
I can't see it making any difference as the statements are queued up and only executed on flush() or at the method boundary (if auto-flush).
Damo