Hi, Dan.

I've updated the pull request.

It still has an unexpected behavior when using the refactored 
EventBusServiceJdo, being that when an Exception is thrown during action 
processing (ie, on EXECUTING) the transaction is marked to be aborted but the 
execution flow continues (and seems not to abort).

Perhaps an Exception might be thrown when detected or something similar?
I had tests expecting an Exception that were previously passing and currently 
not.
But not sure when the exception might be thrown.


Thanks,

Oscar



> El 8/2/2015, a las 13:04, GESCONSULTOR - Óscar Bou <o....@gesconsultor.com> 
> escribió:
> 
> Hi, Dan.
> 
> I've just sent a pull request [1] containing an initial implementation of an 
> Axon-based EventBusService.
> 
> I've refactored some classes in order to reuse Isis logic as much as possible.
> 
> 
> Please, can you review it?
> 
> Thanks,
> 
> Oscar
> 
> 
> [1] https://github.com/apache/isis/pull/23 
> <https://github.com/apache/isis/pull/23>
> 
> 
>> El 6/2/2015, a las 19:47, Dan Haywood <d...@haywood-associates.co.uk 
>> <mailto:d...@haywood-associates.co.uk>> escribió:
>> 
>> Hi Oscar,
>> sorry not to reply on this post... just getting around to it.
>> 
>> Yes, your email makes sense to me; I hadn't known that Guava buffered 
>> events, but I can see why the fact that it does could cause this multi-level 
>> cascade issue.
>> 
>> I had a poke around its Javadoc but couldn't see any way to turn it off.
>> 
>> It ought to be possible to swap in an Axion-based event bus instead though.  
>> Write a service implementing Isis' EventBusService API, and make sure that 
>> the subscribers use Axion's own subscription API, obviously.
>> 
>> With the Guava implementation I had to install a special exception handler 
>> [8] so that a subscriber could veto or abort an transaction; an Axion 
>> implementation would need to do something similar.
>> 
>> If you do write an implementation, then it can be registered (and take 
>> precedence over the built-in guava impl) just by explicitly registering in 
>> isis.properties, like we used to do.
>> 
>> ~~~
>> As for CQRS.... Jeroen and I joke about my antipathy for it as a pattern.  
>> But actually, it's not really true... I can, truth be told, see benefits 
>> from applying some of its ideas, if only to help decouple the app (different 
>> rates of change of behaviour = commands vs structure = query).
>> 
>> So, in Isis a CQRS app one would have dumb entities, and all behaviour would 
>> be either contributed actions or event bus subscribers.   Indeed, we are 
>> gradually refactoring Estatio into this structure, so that we can (a) focus 
>> on its core domain - an invoice calculation engine - and (b) potentially 
>> reuse some of its building block modules in other apps.
>> 
>> Cheers
>> Dan
>> 
>> 
>> [8] 
>> https://github.com/apache/isis/blob/b5f73ec3dcae8015d11004915c15dd81c2945238/core/runtime/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceDefault.java#L91
>>  
>> <https://github.com/apache/isis/blob/b5f73ec3dcae8015d11004915c15dd81c2945238/core/runtime/src/main/java/org/apache/isis/core/runtime/services/eventbus/EventBusServiceDefault.java#L91>
>> 
>> 
>> On 17 January 2015 at 16:17, GESCONSULTOR - Óscar Bou 
>> <o....@gesconsultor.com <mailto:o....@gesconsultor.com>> wrote:
>> Hi all.
>> 
>> I'm "fighting" against current Event Bus implementation, as it's currently 
>> based on Guava Event Bus.
>> 
>> It has one characteristic that is not allowing me to implement, for example, 
>> cascade deleting of Domain Entities, nested in 3 levels (Entity2 references 
>> Entity1, and Entity3 references Entity2. When deleting an Entity1 instance I 
>> want to delete - or set to null, etc. - Entity2 and Entity3 also).
>> 
>> This is due to Guava EventBus current implementation, that enqueues Events 
>> posted instead of dispatching them at the very moment [1] as a programmer 
>> would expect with a sequential execution flow. 
>> 
>> That originates limitations on "nested" behaviors when you post an Event 
>> once you're processing an Event (ie, you're entered a @Subscriber).
>> For example, Events dispatched from actions that act on the EXECUTING phase: 
>> - if invoked by the user from the UI the @Subscriber's code will be executed 
>> PRIOR to the action's code.
>> - but if invoked as part of a previous Event handler (ie, when still 
>> executing a previous Event @Subscriber's code) it will be queued and will be 
>> executed AFTER the action's code. 
>> 
>> In [1] the problem is explained quite clearly, and also the solution if this 
>> one is not the desired behavior (to "delete" 3 lines, as currently it's not 
>> configurable...).
>> 
>> 
>> 
>> I'm trying to explain this over Estatio.
>> 
>> On [2], the Party entity declares a "remove" action that posts an Event.
>> 
>> On 3], the AgreementRoles service is subscribed to the Event. 
>> But imagine that we want to delete all "AgreementRole" instances instead of 
>> setting the reference to null or to another Party.
>> For that, we would declare and invoke a similar "remove" action to the one 
>> defined for Party ([2]), with an @ActionInteraction for posting an Event, 
>> and invoking it inside a "wrap" for the Event to be published.
>> 
>> If I only have Party and AgreementRole, when Party.RemoveEvent is processed 
>> on the EXECUTING phase I can delete (or set to null) the AgreementRole 
>> instances referencing it.
>> So by now, all is ok.
>> 
>> 
>> But now imagine that there's another Entity that holds a reference to the 
>> "AgreementRole" we are removing.
>> For that, I subscribe to AgreementRole.Remove Events hoping that @Subscriber 
>> to be called BEFORE an "AgreementRole" is removed, in order to "clear" (set 
>> to null) the reference to it, avoiding a referential integrity Exception. 
>> 
>> In fact, I can define a test that asserts that, when an AgreementRole is 
>> removed, the Event is posted and the reference is set to null.
>> 
>> But what happens if the "AgreementRole.remove()" action is invoked WHILE 
>> still processing the Party.RemoveEvent on the "AgreementRoles" @Subscriber?
>> 
>> That the Event will be queued, instead of being processed when posted (and 
>> the AgreementRole @Subscriber being invoke then) !!!
>> 
>> 
>> As the execution flow will return to the "Party.RemoveEvent", where the 
>> container().remove(...) method will be invoked, a JDO exception will be 
>> thrown, similar to this one:
>> 
>> javax.jdo.JDODataStoreException: Ha tirado una excepci�n al hacer flush() 
>> a la base de datos
>>      at 
>> org.datanucleus.api.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:451)
>>      at 
>> org.datanucleus.api.jdo.JDOPersistenceManager.flush(JDOPersistenceManager.java:2029)
>>      at 
>> org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore.executeCommands(DataNucleusObjectStore.java:361)
>>      at 
>> org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore.execute(DataNucleusObjectStore.java:353)
>>      at 
>> org.apache.isis.core.runtime.system.transaction.IsisTransaction.doFlush(IsisTransaction.java:502)
>>      at 
>> org.apache.isis.core.runtime.system.transaction.IsisTransaction.flush(IsisTransaction.java:451)
>>      at 
>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.flushTransaction(IsisTransactionManager.java:392)
>>      at 
>> org.apache.isis.core.runtime.persistence.internal.RuntimeContextFromSession$7.flush(RuntimeContextFromSession.java:238)
>>      at 
>> org.apache.isis.core.metamodel.services.container.DomainObjectContainerDefault.flush(DomainObjectContainerDefault.java:247)
>>      at 
>> com.xms.framework.api.domain.model.isis.AbstractIsisDomainRepositoryAndFactory.doRemove(AbstractIsisDomainRepositoryAndFactory.java:353)
>>      at 
>> com.xms.framework.api.domain.model.isis.AbstractIsisDomainRepositoryAndFactory$3.execute(AbstractIsisDomainRepositoryAndFactory.java:346)
>>      at 
>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.executeWithinTransaction(IsisTransactionManager.java:160)
>>      at 
>> com.xms.framework.api.domain.model.isis.AbstractIsisDomainRepositoryAndFactory.remove(AbstractIsisDomainRepositoryAndFactory.java:342)
>>      at 
>> com.xms.framework.api.domain.model.isis.DomainRepositoryService.deleteEntity(DomainRepositoryService.java:221)
>>      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>      at 
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>>      at 
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>      at java.lang.reflect.Method.invoke(Method.java:606)
>>      at 
>> org.apache.isis.core.metamodel.facets.actions.interaction.ActionInvocationFacetForInteractionAbstract.internalInvoke(ActionInvocationFacetForInteractionAbstract.java:314)
>>      at 
>> org.apache.isis.core.metamodel.facets.actions.interaction.ActionInvocationFacetForInteractionAbstract.invoke(ActionInvocationFacetForInteractionAbstract.java:188)
>>      at 
>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:57)
>>      at 
>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:1)
>>      at 
>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.executeWithinTransaction(IsisTransactionManager.java:205)
>>      at 
>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction.invoke(ActionInvocationFacetWrapTransaction.java:54)
>>      at 
>> org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl.execute(ObjectActionImpl.java:367)
>>      at 
>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.handleActionMethod(DomainObjectInvocationHandler.java:563)
>>      at 
>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.invoke(DomainObjectInvocationHandler.java:229)
>>      at 
>> org.apache.isis.core.wrapper.proxy.ProxyInstantiatorForJavassist$1.invoke(ProxyInstantiatorForJavassist.java:52)
>>      at 
>> com.xms.framework.api.domain.model.isis.DomainRepositoryService_$$_jvst9b5_6.deleteEntity(DomainRepositoryService_$$_jvst9b5_6.java)
>>      at 
>> com.xms.framework.api.integration.tests.isis.AbstractIsisDomainRepositoryAndFactoryTests.deleteDomainObjectWithAnnotation_referenced_isDeleted_ifEventHandlerDeletesTheReference_nested(AbstractIsisDomainRepositoryAndFactoryTests.java:108)
>>      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>      at 
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>>      at 
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>      at java.lang.reflect.Method.invoke(Method.java:606)
>>      at 
>> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
>>      at 
>> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
>>      at 
>> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
>>      at 
>> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
>>      at 
>> org.apache.isis.core.integtestsupport.IntegrationTestAbstract$IsisTransactionRule$1.evaluate(IntegrationTestAbstract.java:199)
>>      at 
>> org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2$1.evaluate(JUnitRuleMockery2.java:146)
>>      at 
>> org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
>>      at org.junit.rules.RunRules.evaluate(RunRules.java:20)
>>      at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
>>      at 
>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
>>      at 
>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
>>      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
>>      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
>>      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
>>      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
>>      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
>>      at 
>> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
>>      at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
>>      at 
>> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
>>      at 
>> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
>>      at 
>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
>>      at 
>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
>>      at 
>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
>>      at 
>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
>> NestedThrowablesStackTrace:
>> java.sql.BatchUpdateException: violación del restricción de integridad: sin 
>> acción para la clave foránea; AGREEMENTROLE_FK1 table: AGREEMENTROLE
>>      at org.hsqldb.jdbc.JDBCPreparedStatement.executeBatch(Unknown Source)
>>      at 
>> org.datanucleus.store.rdbms.datasource.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
>>      at 
>> org.datanucleus.store.rdbms.datasource.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
>>      at 
>> org.datanucleus.store.rdbms.ParamLoggingPreparedStatement.executeBatch(ParamLoggingPreparedStatement.java:372)
>>      at 
>> org.datanucleus.store.rdbms.SQLController.processConnectionStatement(SQLController.java:628)
>>      at 
>> org.datanucleus.store.rdbms.SQLController.processStatementsForConnection(SQLController.java:596)
>>      at 
>> org.datanucleus.store.rdbms.SQLController$1.transactionFlushed(SQLController.java:683)
>>      at 
>> org.datanucleus.store.connection.AbstractManagedConnection.transactionFlushed(AbstractManagedConnection.java:86)
>>      at 
>> org.datanucleus.store.connection.ConnectionManagerImpl$2.transactionFlushed(ConnectionManagerImpl.java:454)
>>      at org.datanucleus.TransactionImpl.flush(TransactionImpl.java:203)
>>      at 
>> org.datanucleus.ExecutionContextImpl.flushInternal(ExecutionContextImpl.java:4125)
>>      at 
>> org.datanucleus.ExecutionContextImpl.flush(ExecutionContextImpl.java:4070)
>>      at 
>> org.datanucleus.api.jdo.JDOPersistenceManager.flush(JDOPersistenceManager.java:2010)
>>      at 
>> org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore.executeCommands(DataNucleusObjectStore.java:361)
>>      at 
>> org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore.execute(DataNucleusObjectStore.java:353)
>>      at 
>> org.apache.isis.core.runtime.system.transaction.IsisTransaction.doFlush(IsisTransaction.java:502)
>>      at 
>> org.apache.isis.core.runtime.system.transaction.IsisTransaction.flush(IsisTransaction.java:451)
>>      at 
>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.flushTransaction(IsisTransactionManager.java:392)
>>      at 
>> org.apache.isis.core.runtime.persistence.internal.RuntimeContextFromSession$7.flush(RuntimeContextFromSession.java:238)
>>      at 
>> org.apache.isis.core.metamodel.services.container.DomainObjectContainerDefault.flush(DomainObjectContainerDefault.java:247)
>>      at 
>> com.xms.framework.api.domain.model.isis.AbstractIsisDomainRepositoryAndFactory.doRemove(AbstractIsisDomainRepositoryAndFactory.java:353)
>>      at 
>> com.xms.framework.api.domain.model.isis.AbstractIsisDomainRepositoryAndFactory$3.execute(AbstractIsisDomainRepositoryAndFactory.java:346)
>>      at 
>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.executeWithinTransaction(IsisTransactionManager.java:160)
>>      at 
>> com.xms.framework.api.domain.model.isis.AbstractIsisDomainRepositoryAndFactory.remove(AbstractIsisDomainRepositoryAndFactory.java:342)
>>      at 
>> com.xms.framework.api.domain.model.isis.DomainRepositoryService.deleteEntity(DomainRepositoryService.java:221)
>>      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>      at 
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>>      at 
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>      at java.lang.reflect.Method.invoke(Method.java:606)
>>      at 
>> org.apache.isis.core.metamodel.facets.actions.interaction.ActionInvocationFacetForInteractionAbstract.internalInvoke(ActionInvocationFacetForInteractionAbstract.java:314)
>>      at 
>> org.apache.isis.core.metamodel.facets.actions.interaction.ActionInvocationFacetForInteractionAbstract.invoke(ActionInvocationFacetForInteractionAbstract.java:188)
>>      at 
>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:57)
>>      at 
>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:1)
>>      at 
>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.executeWithinTransaction(IsisTransactionManager.java:205)
>>      at 
>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction.invoke(ActionInvocationFacetWrapTransaction.java:54)
>>      at 
>> org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl.execute(ObjectActionImpl.java:367)
>>      at 
>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.handleActionMethod(DomainObjectInvocationHandler.java:563)
>>      at 
>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.invoke(DomainObjectInvocationHandler.java:229)
>>      at 
>> org.apache.isis.core.wrapper.proxy.ProxyInstantiatorForJavassist$1.invoke(ProxyInstantiatorForJavassist.java:52)
>>      at 
>> com.xms.framework.api.domain.model.isis.DomainRepositoryService_$$_jvst9b5_6.deleteEntity(DomainRepositoryService_$$_jvst9b5_6.java)
>>      at 
>> com.xms.framework.api.integration.tests.isis.AbstractIsisDomainRepositoryAndFactoryTests.deleteDomainObjectWithAnnotation_referenced_isDeleted_ifEventHandlerDeletesTheReference_nested(AbstractIsisDomainRepositoryAndFactoryTests.java:108)
>>      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>      at 
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>>      at 
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>      at java.lang.reflect.Method.invoke(Method.java:606)
>>      at 
>> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
>>      at 
>> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
>>      at 
>> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
>>      at 
>> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
>>      at 
>> org.apache.isis.core.integtestsupport.IntegrationTestAbstract$IsisTransactionRule$1.evaluate(IntegrationTestAbstract.java:199)
>>      at 
>> org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2$1.evaluate(JUnitRuleMockery2.java:146)
>>      at 
>> org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
>>      at org.junit.rules.RunRules.evaluate(RunRules.java:20)
>>      at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
>>      at 
>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
>>      at 
>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
>>      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
>>      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
>>      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
>>      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
>>      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
>>      at 
>> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
>>      at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
>>      at 
>> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
>>      at 
>> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
>>      at 
>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
>>      at 
>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
>>      at 
>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
>>      at 
>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
>> 
>> 
>> 
>> 
>> Am I missing something here? Perhaps a better way to solve this?
>> 
>> 
>> 
>> 
>> If not, for this to be avoided, possible solutions that come to my mind are:
>> 1. To modify the current Guava's EventBus implementation to not queue Event 
>> calls.
>> 2. To change current EventBus implementation to another one that will not 
>> affect the business logic execution flow.
>> 
>> 
>> I've being a long-time user of the Axon framework's EventBus, and I'm going 
>> to try it to resolve this use case.
>> 
>> They have really amazing Event Bus implementations for "simple" scenarios as 
>> mostly ours regarding one virtual machine (see SimpleEventBus [4]) and for 
>> really advance scenarios involving Domain Events in clusters (see 
>> ClusteredEventBus [5]).
>> 
>> So using the SimpleEventBus seems the best way here ...
>> 
>> Also, I think it would be interesting for Apache Isis to integrate it, as it 
>> could be the initial alignment of Apache Isis DDD implementation with CQRS, 
>> which quite people on the DDD community consider are closely related (see 
>> references on the "Implementing DDD" book, and some links like [7], .
>> 
>> 
>> 
>> 
>> Excuse me for this long email. Events are hard to explain ... :-))
>> 
>> Many thanks in advance,
>> 
>> Oscar
>> 
>> 
>> 
>> 
>> 
>> [1] 
>> https://github.com/estatio/estatio/blob/master/estatioapp/dom/src/main/java/org/estatio/dom/party/Party.java#L177
>>  
>> <https://github.com/estatio/estatio/blob/master/estatioapp/dom/src/main/java/org/estatio/dom/party/Party.java#L177>
>> 
>> [2] 
>> https://github.com/estatio/estatio/blob/master/estatioapp/dom/src/main/java/org/estatio/dom/agreement/AgreementRoles.java#L143
>>  
>> <https://github.com/estatio/estatio/blob/master/estatioapp/dom/src/main/java/org/estatio/dom/agreement/AgreementRoles.java#L143>
>> 
>> [3] http://stackoverflow.com/questions/21947936/guava-eventbus-dispatching 
>> <http://stackoverflow.com/questions/21947936/guava-eventbus-dispatching>
>> 
>> [4] http://www.axonframework.org <http://www.axonframework.org/>
>> 
>> [5] 
>> https://github.com/AxonFramework/AxonFramework/blob/master/core/src/main/java/org/axonframework/eventhandling/SimpleEventBus.java
>>  
>> <https://github.com/AxonFramework/AxonFramework/blob/master/core/src/main/java/org/axonframework/eventhandling/SimpleEventBus.java>
>> 
>> [6] 
>> https://github.com/AxonFramework/AxonFramework/blob/master/core/src/main/java/org/axonframework/eventhandling/ClusteringEventBus.java
>>  
>> <https://github.com/AxonFramework/AxonFramework/blob/master/core/src/main/java/org/axonframework/eventhandling/ClusteringEventBus.java>
>> 
>> [7] 
>> http://www.kenneth-truyers.net/2013/12/05/introduction-to-domain-driven-design-cqrs-and-event-sourcing/
>>  
>> <http://www.kenneth-truyers.net/2013/12/05/introduction-to-domain-driven-design-cqrs-and-event-sourcing/>
>> 
>> 
>> 
>> 
>>> El 14/1/2015, a las 10:07, GESCONSULTOR - Óscar Bou <o....@gesconsultor.com 
>>> <mailto:o....@gesconsultor.com>> escribió:
>>> 
>>> Just to notice.
>>> 
>>> As I was simply trying that, when removing an Entity (Relationship), 
>>> declared on a "core" module, it would automatically remove a dependent 
>>> object (RelationshipBCMInformation) declared on another module without 
>>> creating a direct dependency on the "core" module, I also tried to use 
>>> foreign keys declaration through JDO.
>>> 
>>> So I annotated the RelationshipBCMInformation with @Element as this:
>>> 
>>> 
>>> public class RelationshipBCMInformation extends 
>>> AbstractMultiTenantUnnamedEntity {
>>> 
>>> 
>>>     // {{ Relationship (property)
>>>     private Relationship relationship;
>>> 
>>>     @Hidden
>>>     @XMSField(locales = { @XMSLocale(locale = "es", caption = "Relación") })
>>>     @Column(allowsNull = "false")
>>>     @MemberOrder(sequence = "010")
>>>     @Element(deleteAction = ForeignKeyAction.CASCADE)
>>>     public Relationship getRelationship() {
>>>         return this.relationship;
>>>     }
>>> 
>>>     public void setRelationship(final Relationship relationship) {
>>>         this.relationship = relationship;
>>>     }
>>> 
>>>     ....
>>> 
>>> } 
>>> 
>>> Seems that HSQLDB does not properly support DELETE CASCADE, but over 
>>> PostgreSQL it declares de Foreign Key and deletes de object.
>>> 
>>> But seems that Isis does not get notified about it and the following 
>>> exception is thrown when ending the Isis transaction:
>>> 
>>> Rerun 
>>> com.xms.framework.risk.integration.tests.continuity.RelationshipsBCMInformationTests.testDeleteColletionWithRelationshipAlsoDeletesRelationshipBCMInformation
>>> testDeleteColletionWithRelationshipAlsoDeletesRelationshipBCMInformation(com.xms.framework.risk.integration.tests.continuity.RelationshipsBCMInformationTests)
>>> javax.jdo.JDOUserException: No es posible leer campos de un objeto borrado
>>> FailedObject:1[OID]com.xms.framework.architecture.domain.model.Relationship
>>>     at 
>>> org.datanucleus.api.jdo.state.PersistentNewDeleted.transitionReadField(PersistentNewDeleted.java:106)
>>>     at 
>>> org.datanucleus.state.AbstractStateManager.transitionReadField(AbstractStateManager.java:650)
>>>     at 
>>> org.datanucleus.state.JDOStateManager.isLoaded(JDOStateManager.java:3194)
>>>     at 
>>> com.xms.framework.api.domain.model.isis.AbstractMultiTenantObject.getTenantId(AbstractMultiTenantObject.java)
>>>     at 
>>> com.xms.framework.api.domain.model.isis.AbstractMultiTenantObject.toString(AbstractMultiTenantObject.java:72)
>>>     at 
>>> org.apache.isis.core.runtime.system.transaction.IsisTransaction.asString(IsisTransaction.java:703)
>>>     at 
>>> org.apache.isis.core.runtime.system.transaction.IsisTransaction.access$0(IsisTransaction.java:702)
>>>     at 
>>> org.apache.isis.core.runtime.system.transaction.IsisTransaction$PreAndPostValues.setPost(IsisTransaction.java:1197)
>>>     at 
>>> org.apache.isis.core.runtime.system.transaction.IsisTransaction.updatePostValues(IsisTransaction.java:1325)
>>>     at 
>>> org.apache.isis.core.runtime.system.transaction.IsisTransaction.getChangedObjectProperties(IsisTransaction.java:1310)
>>>     at 
>>> org.apache.isis.core.runtime.system.transaction.IsisTransaction.preCommit(IsisTransaction.java:733)
>>>     at 
>>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.endTransaction(IsisTransactionManager.java:481)
>>>     at 
>>> org.apache.isis.core.integtestsupport.IsisSystemForTest.endTran(IsisSystemForTest.java:667)
>>>     at 
>>> org.apache.isis.core.integtestsupport.IntegrationTestAbstract$IsisTransactionRule$1.evaluate(IntegrationTestAbstract.java:200)
>>>     at 
>>> org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2$1.evaluate(JUnitRuleMockery2.java:146)
>>>     at 
>>> org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
>>>     at org.junit.rules.RunRules.evaluate(RunRules.java:20)
>>>     at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
>>>     at 
>>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
>>>     at 
>>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
>>>     at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
>>>     at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
>>>     at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
>>>     at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
>>>     at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
>>>     at 
>>> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
>>>     at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
>>>     at 
>>> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
>>>     at 
>>> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
>>>     at 
>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
>>>     at 
>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
>>>     at 
>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
>>>     at 
>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
>>> 
>>> 
>>> 
>>> I will try to reimplement it using Events, but perhaps this is relevant for 
>>> other use cases.
>>> 
>>> HTH,
>>> 
>>> Oscar
>>> 
>>> 
>>> 
>>> 
>>> 
>>>> El 13/1/2015, a las 19:25, GESCONSULTOR - Óscar Bou 
>>>> <o....@gesconsultor.com <mailto:o....@gesconsultor.com>> escribió:
>>>> 
>>>> Hi Dan.
>>>> 
>>>> I’ve just updated the issue description.
>>>> 
>>>> Just an “idiomatic issue”.
>>>> 
>>>> I understand that an object can be saved when initially created, and after 
>>>> updating an existing object.
>>>> 
>>>> So for me domainEventOnSave would be triggered both when saving newly 
>>>> created objects, and when updating previously created objects.
>>>> 
>>>> Would it be better naming it something like “domainEventOnCreate” ?
>>>> 
>>>> Seems JDO lifecycle callbacks are named something similar [1].
>>>> 
>>>> Regards,
>>>> 
>>>> Oscar
>>>> 
>>>> 
>>>> [1] 
>>>> http://www.datanucleus.org/products/datanucleus/jdo/lifecycle_callbacks.html
>>>>  
>>>> <http://www.datanucleus.org/products/datanucleus/jdo/lifecycle_callbacks.html>
>>>> 
>>>> 
>>>>> El 13/1/2015, a las 18:39, Dan Haywood <d...@haywood-associates.co.uk 
>>>>> <mailto:d...@haywood-associates.co.uk>> escribió:
>>>>> 
>>>>> 
>>>>> 
>>>>> On 13 January 2015 at 17:19, GESCONSULTOR - Óscar Bou 
>>>>> <o....@gesconsultor.com <mailto:o....@gesconsultor.com>> wrote:
>>>>> ok, Dan.
>>>>> 
>>>>>  But that would include something like @DomainObjectInteraction, in order 
>>>>> to customize the event (and the event handler) ?
>>>>> 
>>>>> 
>>>>> 
>>>>> Yeah, though into @DomainObject rather than a new annotation.
>>>>> 
>>>>> Why? because in ISIS-970 the existing annotations @ActionInteraction / 
>>>>> @PropertyInteraction / @CollectionInteraction are being deprecated to be 
>>>>> replaced by into @Action / @Property / @Collection, 
>>>>> 
>>>>> eg:
>>>>> @ActionInteraction(SomethingChangedEvent.class)
>>>>> 
>>>>> will become
>>>>> 
>>>>> @Action(domainEvent=SomethingChangedEvent.class)
>>>>> 
>>>>> 
>>>>> ~~~
>>>>> 
>>>>> Therefore I suggest
>>>>> 
>>>>> @DomainObject(
>>>>>     domainEventOnLoad = ...,
>>>>>     domainEventOnSave = ...,
>>>>>     domainEventOnUpdate = ...,
>>>>>     domainEventOnDelete = ...,
>>>>> )
>>>>> 
>>>>> I don't think there's any need to have a pairs of hooks (eg 
>>>>> domainEventOnSaving / domainEventOnSaved), because the domainEvent itself 
>>>>> has "phases", ie EXECUTING and EXECUTED.  So we can reuse that.
>>>>> 
>>>>> I'm not sure at this stage if the other "vetoing" phases 
>>>>> (HIDE/DISABLE/VALIDATE) all makes sense, though possibly the OnLoad event 
>>>>> could honour HIDE and DISABLE (providing a way by which a subscriber 
>>>>> could prevent an object from being either viewed or being edited).
>>>>> 
>>>>> If the above sounds ok, can you do me a favour and copy/paste some of the 
>>>>> above into the ISIS-803 ticket?
>>>>> 
>>>>> 
>>>>> Cheers
>>>>> Dan
>>>>> 
>>>>> 
>>>>> 
>>>>>  
>>>>>> El 13/1/2015, a las 15:21, Dan Haywood <d...@haywood-associates.co.uk 
>>>>>> <mailto:d...@haywood-associates.co.uk>> escribió:
>>>>>> 
>>>>>> Hi Oscar
>>>>>> 
>>>>>> Although we probably won't use this in Estatio, it is (I think) a valid 
>>>>>> use case.
>>>>>> 
>>>>>> We do in fact have a ticket for it already, ISIS-803 [1].  And the 
>>>>>> original ticket that introduced the event bus, ISIS-550 [2], although it 
>>>>>> didn't implement the feature, did mention it.
>>>>>> 
>>>>>> In a similar vein, if we implement ISIS-803 then I think the recently 
>>>>>> raised ISIS-1005 [3] is probably redundant (or at least, is part of 
>>>>>> ISIS-803).
>>>>>> 
>>>>>> In terms of priorities, I want to get my @Action / @Property / 
>>>>>> @Collection stuff finished off.  Then I'll take a look at this and see 
>>>>>> how much work it is to squeeze in for 1.8.0 or not.
>>>>>> 
>>>>>> HTH
>>>>>> Dan
>>>>>> 
>>>>>> 
>>>>>> [1] https://issues.apache.org/jira/browse/ISIS-803 
>>>>>> <https://issues.apache.org/jira/browse/ISIS-803>
>>>>>> [2] https://issues.apache.org/jira/browse/ISIS-550 
>>>>>> <https://issues.apache.org/jira/browse/ISIS-550>
>>>>>> [3] https://issues.apache.org/jira/browse/ISIS-1005 
>>>>>> <https://issues.apache.org/jira/browse/ISIS-1005>
>>>>>> 
>>>>>> 
>>>>>> ~~~~~~~~~~~~~
>>>>>> 
>>>>>> 
>>>>>> On 13 January 2015 at 14:06, GESCONSULTOR - Óscar Bou 
>>>>>> <o....@gesconsultor.com <mailto:o....@gesconsultor.com>> wrote:
>>>>>> Hi, Dan and Jeroen for your pointing me towards those examples.
>>>>>> 
>>>>>> As I'm seeing on Estatio, event publishing is made through an 
>>>>>> @ActionInteraction annotation, which requires to always delete entities 
>>>>>> by means of that action.
>>>>>> 
>>>>>> I attached the event post to the "removing" framework method for 
>>>>>> publishing the event every time an object is going to be delete, 
>>>>>> independently it's made through a custom action or through 
>>>>>> "container().remove()". 
>>>>>> That way, I can be sure the business logic is going to be executed 
>>>>>> ALWAYS despite how the other developers implement this.
>>>>>> 
>>>>>> We can re-implement all this event logic for assuring that we always 
>>>>>> delete this kind of domain objects through that action, but I thought 
>>>>>> previous solution would work better, as it's directly attached to the 
>>>>>> object's lifecycle.
>>>>>> 
>>>>>> In previous threads we talked about the option of being notified of 
>>>>>> framework's events.
>>>>>> 
>>>>>> Perhaps implementing a @DomainObjectInteraction annotation in a similar 
>>>>>> way to @ActionInteraction could have sense.
>>>>>> 
>>>>>> What do you think?
>>>>>> 
>>>>>> Thanks,
>>>>>> 
>>>>>> Oscar
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>> 
>>>>>>> El 12/1/2015, a las 20:38, Jeroen van der Wal <jer...@stromboli.it 
>>>>>>> <mailto:jer...@stromboli.it>> escribió:
>>>>>>> 
>>>>>>> 
>>>>>>> Here's a sample of invalidating the removal of a Party in case it plays
>>>>>>> role in an agreement:
>>>>>>> https://github.com/estatio/estatio/blob/master/estatioapp/dom/src/main/java/org/estatio/dom/agreement/AgreementRoles.java#L143
>>>>>>>  
>>>>>>> <https://github.com/estatio/estatio/blob/master/estatioapp/dom/src/main/java/org/estatio/dom/agreement/AgreementRoles.java#L143>
>>>>>>> 
>>>>>>> HTH
>>>>>>> 
>>>>>>> On 12 January 2015 at 19:38, Dan Haywood <d...@haywood-associates.co.uk 
>>>>>>> <mailto:d...@haywood-associates.co.uk>>
>>>>>>> wrote:
>>>>>>> 
>>>>>>>> Hi Oscar,
>>>>>>>> 
>>>>>>>> I think we can support this use case, but admittedly it isn't - yet - 
>>>>>>>> well
>>>>>>>> documented.
>>>>>>>> 
>>>>>>>> First thing to say is that the "removing" lifecycle code hook method 
>>>>>>>> that
>>>>>>>> you quote isn't actually part of your stacktrace.  As it happens, 
>>>>>>>> that's
>>>>>>>> probably a good thing...  support for them is a little bit patchy 
>>>>>>>> (there
>>>>>>>> might be bugs).
>>>>>>>> 
>>>>>>>> So, when I look at your stack trace, what's actually happening is that:
>>>>>>>> * BusinessEntity.deleteFromAssignedToBusinessProcesses(...) is 
>>>>>>>> performing a
>>>>>>>> "removeElement" on a wrapped collection, which fires an event via:
>>>>>>>> * CollectionRemoveFromFacetForInteractionAbstract, which is handled by
>>>>>>>> * RelationshipsBCMInformationEventHandler.on
>>>>>>>> 
>>>>>>>> So, what you should do in the handler is to look at the event's 
>>>>>>>> "phase".
>>>>>>>> In fact, you really must pay attention to the phase because it is 
>>>>>>>> called
>>>>>>>> multiple times:
>>>>>>>> 
>>>>>>>> switch(ev,getPhase()) {
>>>>>>>>    case HIDE:
>>>>>>>>       ...
>>>>>>>>    case DISABLE:
>>>>>>>>       ...
>>>>>>>>    case VALIDATE:
>>>>>>>>       ...
>>>>>>>>    case EXECUTING:
>>>>>>>>       ...
>>>>>>>>    case EXECUTED:
>>>>>>>>       ...
>>>>>>>> }
>>>>>>>> 
>>>>>>>> As you have probably guessed, your code wants to go into the 
>>>>>>>> "EXECUTING"
>>>>>>>> bit, which is the pre-execute callback.  I imagine at the moment it is
>>>>>>>> firing for all the cases, including the EXECUTED bit, and that's most
>>>>>>>> likely why JDO then complains at you when you try to access that 
>>>>>>>> deleted
>>>>>>>> object.
>>>>>>>> 
>>>>>>>> Hope that makes sense / works... if not, then we can go round the loop.
>>>>>>>> 
>>>>>>>> Cheers
>>>>>>>> Dan
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>>> Two things about
>>>>>>>> Rather than do this on the removing() callback, I suggest you emit an 
>>>>>>>> event
>>>>>>>> on the action that The event that
>>>>>>>> 
>>>>>>>> On 12 January 2015 at 18:24, GESCONSULTOR - Óscar Bou <
>>>>>>>> o....@gesconsultor.com <mailto:o....@gesconsultor.com>> wrote:
>>>>>>>> 
>>>>>>>>> Hi all.
>>>>>>>>> 
>>>>>>>>> I want to get notified when a domain object is going to be removed.
>>>>>>>>> 
>>>>>>>>> I have defined it as this:
>>>>>>>>> 
>>>>>>>>> public class Relationship {
>>>>>>>>> 
>>>>>>>>>   …
>>>>>>>>> 
>>>>>>>>>    public void removing() {
>>>>>>>>>        this.eventBusService.post(new RelationshipRemovingEvent(this));
>>>>>>>>>    }
>>>>>>>>>  ...
>>>>>>>>> 
>>>>>>>>> }
>>>>>>>>> 
>>>>>>>>> And an Event Handler like this:
>>>>>>>>> 
>>>>>>>>> public class RelationshipsBCMInformationEventHandler extends
>>>>>>>>> AbstractXMSService {
>>>>>>>>> 
>>>>>>>>>    // {{ RELATIONSHIPS EVENTS HANDLER
>>>>>>>>> 
>>>>>>>>>    @Subscribe
>>>>>>>>>    @Programmatic
>>>>>>>>>    public void on(final RelationshipRemovingEvent event) {
>>>>>>>>>        try {
>>>>>>>>>            final RelationshipBCMInformation 
>>>>>>>>> relationshipBCMInformation =
>>>>>>>>> 
>>>>>>>> this.wrap(this.relationshipsBCMInformation).businessContinuityInformation(event.getRelationship());
>>>>>>>>>            this.getContainer().remove(relationshipBCMInformation);
>>>>>>>>>            this.getContainer().flush();
>>>>>>>>>        } catch (final Exception e) {
>>>>>>>>>            e.printStackTrace();
>>>>>>>>>            throw new ApplicationException(e);
>>>>>>>>>        }
>>>>>>>>>    }
>>>>>>>>> 
>>>>>>>>>    // }}
>>>>>>>>> 
>>>>>>>>>    // {{ injected: RelationshipsBCMInformation
>>>>>>>>>    @Inject
>>>>>>>>>    private RelationshipsBCMInformation relationshipsBCMInformation;
>>>>>>>>> 
>>>>>>>>>    // }}
>>>>>>>>> 
>>>>>>>>>    // {{ injected: EventBusService
>>>>>>>>>    @Programmatic
>>>>>>>>>    @PostConstruct
>>>>>>>>>    public void postConstruct() {
>>>>>>>>>        this.eventBusService.register(this);
>>>>>>>>>    }
>>>>>>>>> 
>>>>>>>>>    @Programmatic
>>>>>>>>>    @PreDestroy
>>>>>>>>>    public void preDestroy() {
>>>>>>>>>        this.eventBusService.unregister(this);
>>>>>>>>>    }
>>>>>>>>> 
>>>>>>>>>    @javax.inject.Inject
>>>>>>>>>    private EventBusService eventBusService;
>>>>>>>>>    // }}
>>>>>>>>> 
>>>>>>>>> }
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> Problem is that when the code enters the “on” event handler, the
>>>>>>>> reference
>>>>>>>>> to the relationship accessed on "event.getRelationship()” is already
>>>>>>>> marked
>>>>>>>>> as deleted:
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> javax.jdo.JDOUserException: No es posible leer campos de un objeto
>>>>>>>> borrado
>>>>>>>>> 
>>>>>>>> FailedObject:0[OID]com.xms.framework.architecture.domain.model.Relationship
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.datanucleus.api.jdo.state.PersistentNewDeleted.transitionReadField(PersistentNewDeleted.java:106)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.datanucleus.state.AbstractStateManager.transitionReadField(AbstractStateManager.java:650)
>>>>>>>>>        at
>>>>>>>>> org.datanucleus.state.JDOStateManager.isLoaded(JDOStateManager.java:3194)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.xms.framework.api.domain.model.isis.AbstractXMSDomainObject.getId(AbstractXMSDomainObject.java)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.xms.framework.api.domain.model.isis.AbstractXMSDomainObject.hashCode(AbstractXMSDomainObject.java:431)
>>>>>>>>>        at java.util.Objects.hashCode(Objects.java:96)
>>>>>>>>>        at java.util.HashMap$Entry.hashCode(HashMap.java:847)
>>>>>>>>>        at java.util.AbstractMap.hashCode(AbstractMap.java:494)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.datanucleus.query.QueryUtils.getKeyForQueryResultsCache(QueryUtils.java:1306)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.datanucleus.store.query.QueryManager.getDatastoreQueryResult(QueryManager.java:470)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.datanucleus.store.rdbms.query.JDOQLQuery.performExecute(JDOQLQuery.java:605)
>>>>>>>>>        at
>>>>>>>> org.datanucleus.store.query.Query.executeQuery(Query.java:1786)
>>>>>>>>>        at
>>>>>>>>> org.datanucleus.store.query.Query.executeWithMap(Query.java:1690)
>>>>>>>>>        at
>>>>>>>>> org.datanucleus.api.jdo.JDOQuery.executeWithMap(JDOQuery.java:334)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.xms.framework.api.domain.model.isis.AbstractXMSDomainObjectRepositoryAndFactory.doFindByPropMultiTenant(AbstractXMSDomainObjectRepositoryAndFactory.java:759)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.xms.framework.api.domain.model.isis.AbstractXMSDomainObjectRepositoryAndFactory.findByPropMultiTenant(AbstractXMSDomainObjectRepositoryAndFactory.java:776)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.xms.framework.api.domain.model.isis.AbstractXMSDomainObjectRepositoryAndFactory.findByProp(AbstractXMSDomainObjectRepositoryAndFactory.java:769)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.xms.framework.api.domain.model.isis.AbstractSingletonMultiTenantObjectRepositoryAndFactory.singletonInstance(AbstractSingletonMultiTenantObjectRepositoryAndFactory.java:16)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.xms.framework.risk.domain.model.continuity.RelationshipsBCMInformation.businessContinuityInformation(RelationshipsBCMInformation.java:47)
>>>>>>>>>        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>>>>>>>        at java.lang.reflect.Method.invoke(Method.java:606)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.metamodel.facets.actions.interaction.ActionInvocationFacetForInteractionAbstract.internalInvoke(ActionInvocationFacetForInteractionAbstract.java:314)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.metamodel.facets.actions.interaction.ActionInvocationFacetForInteractionAbstract.invoke(ActionInvocationFacetForInteractionAbstract.java:188)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:57)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:1)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.executeWithinTransaction(IsisTransactionManager.java:205)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction.invoke(ActionInvocationFacetWrapTransaction.java:54)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl.execute(ObjectActionImpl.java:367)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.handleActionMethod(DomainObjectInvocationHandler.java:563)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.invoke(DomainObjectInvocationHandler.java:229)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.wrapper.proxy.ProxyInstantiatorForJavassist$1.invoke(ProxyInstantiatorForJavassist.java:52)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.xms.framework.risk.domain.model.continuity.RelationshipsBCMInformation_$$_jvstb07_2b.businessContinuityInformation(RelationshipsBCMInformation_$$_jvstb07_2b.java)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.xms.framework.risk.domain.model.continuity.RelationshipsBCMInformationEventHandler.on(RelationshipsBCMInformationEventHandler.java:23)
>>>>>>>>>        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>>>>>>>        at java.lang.reflect.Method.invoke(Method.java:606)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47)
>>>>>>>>>        at
>>>>>>>> com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)
>>>>>>>>>        at com.google.common.eventbus.EventBus.post(EventBus.java:275)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.applib.services.eventbus.EventBusService.post(EventBusService.java:202)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.metamodel.facets.InteractionHelper.postEventForCollection(InteractionHelper.java:202)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.metamodel.facets.collections.interaction.CollectionRemoveFromFacetForInteractionAbstract.remove(CollectionRemoveFromFacetForInteractionAbstract.java:103)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.runtime.transaction.facets.CollectionRemoveFromFacetWrapTransaction$1.execute(CollectionRemoveFromFacetWrapTransaction.java:55)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.executeWithinTransaction(IsisTransactionManager.java:160)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.runtime.transaction.facets.CollectionRemoveFromFacetWrapTransaction.remove(CollectionRemoveFromFacetWrapTransaction.java:52)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.metamodel.specloader.specimpl.OneToManyAssociationImpl.removeElement(OneToManyAssociationImpl.java:190)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.handleCollectionRemoveFromMethod(DomainObjectInvocationHandler.java:526)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.invoke(DomainObjectInvocationHandler.java:218)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.wrapper.proxy.ProxyInstantiatorForJavassist$1.invoke(ProxyInstantiatorForJavassist.java:52)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.xms.framework.architecture.domain.model.business.extensions.businessactor.Person_$$_jvstb07_28.removeFromAssignedToBusinessProcesses(Person_$$_jvstb07_28.java)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.xms.framework.architecture.domain.model.business.BusinessEntity.deleteFromAssignedToBusinessProcesses(BusinessEntity.java:93)
>>>>>>>>>        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>>>>>>>        at java.lang.reflect.Method.invoke(Method.java:606)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.metamodel.facets.actions.interaction.ActionInvocationFacetForInteractionAbstract.internalInvoke(ActionInvocationFacetForInteractionAbstract.java:314)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.metamodel.facets.actions.interaction.ActionInvocationFacetForInteractionAbstract.invoke(ActionInvocationFacetForInteractionAbstract.java:188)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:57)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:1)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.executeWithinTransaction(IsisTransactionManager.java:205)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction.invoke(ActionInvocationFacetWrapTransaction.java:54)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl.execute(ObjectActionImpl.java:367)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.handleActionMethod(DomainObjectInvocationHandler.java:563)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.invoke(DomainObjectInvocationHandler.java:229)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.wrapper.proxy.ProxyInstantiatorForJavassist$1.invoke(ProxyInstantiatorForJavassist.java:52)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.xms.framework.architecture.domain.model.business.extensions.businessactor.Person_$$_jvstb07_28.deleteFromAssignedToBusinessProcesses(Person_$$_jvstb07_28.java)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.xms.framework.architecture.domain.model.business.BusinessProcess.deleteFromRequiredBusinessEntities(BusinessProcess.java:476)
>>>>>>>>>        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>>>>>>>        at java.lang.reflect.Method.invoke(Method.java:606)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.metamodel.facets.actions.interaction.ActionInvocationFacetForInteractionAbstract.internalInvoke(ActionInvocationFacetForInteractionAbstract.java:314)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.metamodel.facets.actions.interaction.ActionInvocationFacetForInteractionAbstract.invoke(ActionInvocationFacetForInteractionAbstract.java:188)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:57)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:1)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.executeWithinTransaction(IsisTransactionManager.java:205)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction.invoke(ActionInvocationFacetWrapTransaction.java:54)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl.execute(ObjectActionImpl.java:367)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.handleActionMethod(DomainObjectInvocationHandler.java:563)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.wrapper.handlers.DomainObjectInvocationHandler.invoke(DomainObjectInvocationHandler.java:229)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.wrapper.proxy.ProxyInstantiatorForJavassist$1.invoke(ProxyInstantiatorForJavassist.java:52)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.xms.framework.architecture.domain.model.business.BusinessProcess_$$_jvstb07_27.deleteFromRequiredBusinessEntities(BusinessProcess_$$_jvstb07_27.java)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> com.xms.framework.risk.integration.tests.continuity.RelationshipsBCMInformationTests.testDeleteColletionWithRelationshipAlsoDeletesRelationshipBCMInformation(RelationshipsBCMInformationTests.java:72)
>>>>>>>>>        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>>>>>>>>        at java.lang.reflect.Method.invoke(Method.java:606)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.integtestsupport.IntegrationTestAbstract$IsisTransactionRule$1.evaluate(IntegrationTestAbstract.java:199)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2$1.evaluate(JUnitRuleMockery2.java:146)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:168)
>>>>>>>>>        at org.junit.rules.RunRules.evaluate(RunRules.java:20)
>>>>>>>>>        at 
>>>>>>>>> org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
>>>>>>>>>        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
>>>>>>>>>        at
>>>>>>>> org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
>>>>>>>>>        at
>>>>>>>>> org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
>>>>>>>>>        at
>>>>>>>> org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
>>>>>>>>>        at
>>>>>>>> org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
>>>>>>>>>        at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
>>>>>>>>>        at
>>>>>>>>> 
>>>>>>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> So, as it could be a quite “common” events-related use case 
>>>>>>>>> (referencing
>>>>>>>>> the same entity “before” deleting it), could the event be dispatched
>>>>>>>> BEFORE
>>>>>>>>> sending the object to DN to mark it as deleted?
>>>>>>>>> 
>>>>>>>>> Or, is there any other way to detect when an object is going to be
>>>>>>>> deleted
>>>>>>>>> (previously to being deleted, obviously) ?
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> Thanks in advance,
>>>>>>>>> 
>>>>>>>>> Oscar
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>> 
>>>>> 
>>>> 
>>> 
>> 
> 




Reply via email to