The POC [1] assumes that we only need a single OperationContext for each type of operation. OperationContextManager has a Map of OperationContext by OperationContextType. Each OperationContext object is lazily created on the first occurence of the corresponding type of operation.
Currently, when an operation is initiated (e.g., by Session.merge( entity )), OperationContextManager [2] does the following: - calls ManageableOperationContext#beforeOperation, which puts the OperationContext "in progress"; - executes the operation, which performs cascades according to mappings; - calls ManageableOperationContext#afterOperation, which puts the OperationContext in an invalid state that is "not in progress". When an operation cascades to other entities, the same OperationContext is used. Obviously, OperationContextManager needs to know if an operation is "top-level" (meaning that the operation is on the original entity, and not cascaded). In the POC, if the relevant OperationContext is not in progress at the time that an opeation is initiated, then OperationContextManager assumes that the operation is top-level. If the OperationContext is "in progress", then OperationContextManager assumes that this is a cascaded operation. I am not sure this is always correct. Can anyone think of a case where this could break down? In the POC, the following EventSource methods that contain an argument for the operation cache has been deprecated and is no longer used because the contents of that argument has been moved into an OperationContext: public void merge(String entityName, Object object, Map copiedAlready) public void persist(String entityName, Object object, Map createdAlready) public void persistOnFlush(String entityName, Object object, Map copiedAlready) public void refresh(String entityName, Object object, Map refreshedAlready) public void delete(String entityName, Object child, boolean isCascadeDeleteEnabled, Set transientEntities) Before the POC, it was the above methods that indicated that it was not top-level. If it turns out that having a single OperationContext is not valid, then there needs to be some other way to determine if the operation was top-level. I had originally planned to use PersistenceContext#getCascadeLevel == 0 to indicate an operation was at the top-level, but I found that won't work for some operations. For example, the cascade level for a top-level delete can be > 1 when deleting orphans due to merge or save-or-update operations. Another example is that cascade level is not 0 on top-level save-or-update while flushing. I have some ideas to work around this, but I didn't want to get too far down that path if it wasn't an issue. Thanks, Gail [1] https://github.com/gbadner/hibernate-core/blob/3d0e2378cb998788b3205afb1e15c443c5ba77e8/hibernate-core/src/main/java/org/hibernate/engine/operationContext/internal/OperationContextManager.java [2] https://github.com/gbadner/hibernate-core/blob/3d0e2378cb998788b3205afb1e15c443c5ba77e8/hibernate-core/src/main/java/org/hibernate/engine/operationContext/internal/OperationContextManager.java#L132 On Fri, Feb 5, 2016 at 8:17 PM, Gail Badner <gbad...@redhat.com> wrote: > I've created a gist with an overview of the design: > https://gist.github.com/gbadner/f0e635e8fba7b84af233 . I will add a new > section tomorrow about possible shortcomings. > > Here is my POC: > https://github.com/hibernate/hibernate-orm/compare/master...gbadner:HHH-10478-OperationContext > . Although no tests fail, the approach may be too simple to model what is > necessary. > > At this point the POC is squashed down to 1 commit: > https://github.com/hibernate/hibernate-orm/commit/3d0e2378cb998788b3205afb1e15c443c5ba77e8 > > Have a look and feel free to comment. > > Thanks, > Gail > _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev