tags:

views:

73

answers:

1

I'm still kind of undecided which is the best practice to handle em.remove(entity) with this entity being in several collections mapped using mappedBy in JPA.

Consider an entity like a Property that references three other entities: a Descriptor, a BusinessObject and a Level entity. The mapping is defined using @ManyToOne in the Property entity and using @OneToMany(mappedBy...) in the other three objects. That inverse mapping is defined because there are some situations where I need to access those collections.

Whenever I remove a Property using em.remove(prop) this element is not automatically removed from managed entities of the other three types. If I don't care about that and the following page load (webapp) doesn't reload those entities the Property is still found and some decisions might be taken that are no longer true.

The inverse mappings may become quite large and though I don't want to use something like descriptor.getProperties().remove(prop) because it will load all those properties that might have been lazy loaded until then.

So my currently preferred way is to refresh the entity if it is managed: if (em.contains(descriptor)) em.refresh(descriptor) - which unloads a possibly loaded collection and triggers a reload upon the next access.

Is there another feasible way to handle all those mappedBy collections of already loaded entites?

+1  A: 

You're solution of checking if an entity is managed sounds excellent.

Why don't you program it on the @PreRemove and @PrePersist of the entity? This way, you only have to program it once and it keeps you’re model always consistent (without any manual collections tampering).

An other solution is to always redirect after update's and inserts, this forces you’re controller to query JPA instead of using the manipulated model objects.

Update: You also might want to check out: JPA implementation patterns

Kdeveloper
Thanks for your thoughts. Using the persistence events might be a little tricky for me because my model so far doesn't refer to an entitymanager itself and is used in a Seam context - the refresh way might not work this way. And the add() / remove() on associated collections will be too expensive for large collections.
Daniel Bleisteiner
I've accepted the solution because it approves my current implementation more or less. The idea with the persistence events is nice and useful in some cases.
Daniel Bleisteiner