Cascade-update does not work with the javassist proxies when the field is annotated and annotating the getter causes a performance issue
jblaufuss opened this issue · 0 comments
We have an entity with a java.util.List
property that is annotated to cascade updates with @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
. We have observed that the update cascade stops after a few hops (e.g. nearer entities have their updates persisted, but more distant ones do not).
I did some debugging, and it appears the issue is with the handling of the javassist proxies again. If the annotation is on the field, the cascade code attempts to use field-access to get the value. However, the javassist proxies themselves never have the field populated, so this field-access always retrieves a null and the cascade-update stops prematurely.
This can be worked around by putting the annotation on the getter, which causes the cascade code to use method access, which works with the javassist proxies. However, this introduces a performance issue, as the cascade can trigger the loading of entities that were never touched by the user code (and thus could never have been updated). I feel the proxies need to have access to some kind of state to know if it's appropriate to load new data or not (e.g. the ProxyHandler
has an instance of the EntityManagerImpl
and checks it to see if it's in the middle of a cascade update, if it is, it refuses to load an unloaded entity; the behavior would be different for a cascade delete).
I believe this was happening in EntityManagerImpl.cascadeOperation(...)
, but I may be misremembering.
We found this issue in the develop
branch (we pulled it in sometimes in early 2016).
My apologies if the above is incorrect in the details: it's written from memory. I was planning on attempting to fix this, but my team is moving away from Empire, so I don't think I'll get to it.