2

I am using Eclipselink as a JPA provider and using EntityListener to catch preRemove events from my entities. I have the following hierarchy:

    @Entity
    @Table(name = "MY_ENTITY")
    @EntityListeners(AuditListener.class)
    public class MyEntity {
    .....
    @OneToMany(mappedBy = "myEntity", cascade = CascadeType.ALL, orphanRemoval = true)
        private Set<AnotherEntity> anotherEntities;
    .....
    }

@Entity
@EntityListeners(AuditListener.class)
@Table(name="ANOTHER_ENTITY")
public class AnotherEntity {

    @MapsId("idMyEntity")
    @ManyToOne
    @JoinColumn(name = "ID_MY_ENTITY")
    private MyEntity myEntity;
}

The problem is when I remove one entry from anotherEntities Set and call update for myEntity from JPA, the method public void preUpdate(DescriptorEvent event) gets called for entity 'MyEntity' and thats allright, but as it cascades to 'AnotherEntity' entity and it gets deleted (as it should) there is no call to preRemove(DescriptorEvent event) method for AnotherEntity and I need to know when this occurs.

Is there any annotation missing here ? Do I need to call directly the remove for 'AnotherEntity' to get a callback working ? Thanks in advance.

Marcelo Ribeiro
  • 113
  • 1
  • 11
  • It sounds like you are relying on orphanRemoval to trigger PreRemove, I honestly don't know if JPA guarantees this (I think it should). Is there any reason you don't call ```remove(AnotherEntity)``` directly? If you don't need to user the persistence context afterwards you don't need to maintain bidirectional relation. Even in cases where I do use the persistence context, I prefer to call remove explicitly (and remove it from the set) so the next developer knows what is going on. OrphanRemoval is a usefull feature, but it is an extra burden for JPA to maintain. – Klaus Groenbaek Jan 11 '17 at 13:12
  • I think removing child is one of the advantages to work with JPA so it abstract the database itself. Along with AnotherEntity I have more entities in this object and it would be very complicated to remove manually each child. In the future if somebody adds another entity in this hierarchy this person would have to remember to manually call "remove". – Marcelo Ribeiro Jan 11 '17 at 14:55
  • I tend to agree that orphanRemoval is smart, but I would never use it. When you use it, your persistence context is inconsistent. If you remove an entity using ```em.remove() ``` the persistence context knows and a call to ```em.find(PK)``` will return null, this is not true if you removed an entity from a collection, because orphanRemoval does not occur until the transaction is committed (unless you have cascading remove and the parent is removed). Also I can confirm that @PreRemove is not called when an entity is removed orphanRemoval on EclipseLink 2.6.4. – Klaus Groenbaek Jan 11 '17 at 16:21

0 Answers0