HI Oscar,

Just coming back to you on this pull request for providing an alternate
Axon event bus.

I know previously (offline) I said I'd look to do the work to bring this
change in for 1.8.0, but I've changed my mind, for a couple of reasons:

* it's a fairly deep change to bring in at quite a late stage
* if we did bring it in, it would make the Axon framework a new dependency
of Isis.
* we could in any case instead make the code available as a new Isis addon.

Thus, for those that want to use it, it should just be a matter of updating
the pom.xml and registering in isis.properties (anything registered there
takes precedence over the default @DomainServices).

This isn't to rule out moving to an Axon-based implementation in the future
- I know you have a lot of experience with Axon and rate it highly - but I
think starting off with an Isisaddon is a lower-risk approach.  It also
allows you to iterate and refine the implementation if required without the
overhead of doing a full ASF release.

~~~
If you're happy with that, I'll create a new Isis addon module and put the
code there.

Let me know,

Dan




On 8 February 2015 at 21:59, GESCONSULTOR - Óscar Bou <
[email protected]> wrote:

> 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 <
> [email protected]> 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 <[email protected]
> <mailto:[email protected]>> 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 <
> [email protected] <mailto:[email protected]>> 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 <
> [email protected] <mailto:[email protected]>> 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 <
> [email protected] <mailto:[email protected]>> 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 <[email protected]
> <mailto:[email protected]>> escribió:
> >>>>>
> >>>>>
> >>>>>
> >>>>> On 13 January 2015 at 17:19, GESCONSULTOR - Óscar Bou <
> [email protected] <mailto:[email protected]>> 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 <
> [email protected] <mailto:[email protected]>>
> 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 <
> [email protected] <mailto:[email protected]>> 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 <[email protected]
> <mailto:[email protected]>> 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 <
> [email protected] <mailto:[email protected]>>
> >>>>>>> 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 <
> >>>>>>>> [email protected] <mailto:[email protected]>> 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