OK, just looking in more detail at this now.

First, I hadn't noticed in my first brief scan that you were actually using
the IsisContext.getTransactionManager().executeWithinTransaction method.
 I'm not sure that's a particularly wise thing to do; it isn't part of our
programming model API.

In fact, I was thinking of removing this whole closure design.  A change I
made recently for the RO viewer was to introduce a new
IsisTransactionFilterForRestfulObjects, so that every interaction is
invoked within a single transaction.  This mirrors the design of the Wicket
viewer.  So, our only two formally released viewers now both take
responsibility for setting up a transaction.  That being the case, there's
no need for the persistence manager / transaction manager to lazily create
a transaction that deep down in the stack.

But I presume there was a reason that you put your call to
AbstractXMSDomainObjectRepositoryAndFactory#.doFindByProp(...) in this
closure.  Can you tell me explain further for me?

~~~
Second, the root of your issue is that Isis isn't enforcing the validateXxx
rule on the newly created object.  Should it?  Well, maybe, but it would be
a subtle but important change as to where such validation occurs.

At the moment we only ever apply such validation at the UI layer, mediating
between the viewer layer and the domain object model/layer.  To get a call
to persist() to validate means that we invoke the validation also between
domain object layer and the persistence layer.

While this sounds sensible, one issue is that Isis doesn't always know
a-priori which objects are going to get flushed to the database.  That is,
DataNucleus keeps track of whether each object becomes dirty in the course
of an interaction, and will perform the relevant INSERT/UPDATE for us.
 Isis installs a listener in order to keep itself in sync with such changes
(such logic is centralized in the FrameworkSynchronizer class).

It seems to me, therefore, that if we said that Isis would always perform
validation, then we would need to do it additionally within this
FrameworkSynchronizer.  We would also probably want to perform it at the
point of the call to "persist(..)", so that we fail as early as we can.

Or, we might say that Isis will only do the validation in the
"persist(...)" method, but makes no guarantees that any other objects that
might be modified in the interaction are updated.

Or, we might say that Isis will never do this validation, and we leave it
to the programmer to request it on specific objects.   This can be done
through the WrapperFactory.   Although the following doesn't seem to be
documented, it's possible to trigger validation on a wrapped object by
providing a dummy "save()" method, eg:

     public Risk addQuantitativeRiskToAsset(...) {
                ....

                getWrapperFactory().wrap(risk).save();
                return risk;
        }

Doing this will should cause the object to be validated.

I'm not sure which of these three options I prefer.  Obviously the first is
a pretty big change, the last is (possibly) no change at all other than a
documentation change.

~~~
So, further discussion needed here as to the correct route to take...

Dan




On 5 August 2013 06:39, Dan Haywood <[email protected]> wrote:

> Hi Oscar,
> thanks for doing this analysis.  I haven't delved to it in detail, but it
> seems to me that you are probably right that we need to make some changes
> down in IsisTransactionManager.  I wouldn't worry about breaking semantic
> versioning; this isn't part of any formally published Isis API.
>
> As a first pass, could you create a Jira ticket for the above. If you
> think you know what the patch needs to be, then go ahead, but I'll take a
> detailed look as well, either this evening or tomorrow.
>
> Thx
> Dan
>
>
>
> On 3 August 2013 11:10, GESCONSULTOR - Óscar Bou 
> <[email protected]>wrote:
>
>>
>> I'm executing this from inside a BDD integration test.
>>
>>
>> I have a Domain Object that inherits from this class, which contains a
>> required "name" property:
>>
>> public abstract class AbstractMultiTenantEntity extends
>>                 AbstractMultiTenantObject implements MultiTenantEntity {
>>
>>         /**
>>          * Name of this Entity.
>>          */
>>         private String name;
>>
>>         @Column(allowsNull = "false")
>>         @Override
>>         @MemberOrder(sequence = "0.1")
>>         public String getName() {
>>                 return this.name;
>>         }
>>
>>         @Override
>>         public void setName(final String name) {
>>                 this.name = name;
>>         }
>>
>>         public String validateName(final String name) {
>>                 if (name == null) {
>>                         return "Name cannot be an empty string";
>>                 } else {
>>                         return null;
>>                 }
>>         }
>>
>>         ...
>> }
>>
>>
>>
>> The Domain Object class is declared simply as:
>>
>> public class Risk extends AbstractMultiTenantEntity {
>>
>>         ...
>>
>> }
>>
>>
>> I have a factory method like this one:
>>
>>         public Risk addQuantitativeRiskToAsset(...) {
>>
>>                 ....
>>
>>                 // Here the "name" field is null.
>>                 this.persist(risk);
>>                 return risk;
>>         }
>>
>>
>>
>> The point is that, due to a "programming error", I was not initializing
>> the "name" field (it was null). But this could happen also on other use
>> cases.
>>
>> But the main problem is that, when the this.persist(risk) method is
>> executed, it does not validate it and "detect" that the name property is
>> null, and does not raise any validation exception.
>>
>>
>> As the "database persist" is "cached", the only line appearing at the log
>> is:
>>
>>
>> 10:44:16,317  [DataNucleusSimplePersistAlgorithm main       INFO ]
>>  persist PojoAdapter@6ac42aea
>> [T~~:!com.xms.framework.risk.domain.model.Risk:461a09cf-c483-4779-ae58-a1840baf6a9c,specification=Risk,version=null,pojo-toString=com.xms.framework.risk.domain.model.Risk@6ee01906
>> ,pojo-hash=#6ee01906]
>>
>>
>> But on the first "flush()", when the persistence manager tries to insert
>> the record the following exception is showed in the log:
>>
>>
>> -------------------------
>>
>> 11:12:30,643  [DataNucleusSimplePersistAlgorithm main       INFO ]
>>  persist PojoAdapter@6d70c116
>> [T~~:!com.xms.framework.risk.domain.model.Risk:bff8097b-72d9-40e1-b6de-aab8f5743194,specification=Risk,version=null,pojo-toString=com.xms.framework.risk.domain.model.Risk@85f4d6e2
>> ,pojo-hash=#ffffffff85f4d6e2]
>> 11:12:30,894  [audit                main       INFO ]  2.
>> PreparedStatement.new PreparedStatement returned
>> 11:12:30,894  [audit                main       INFO ]  2.
>> Connection.prepareStatement(INSERT INTO RISK
>> (ID,"NAME",AUTOMATICNAMING,LIKELIHOOD,CODE,EVENT_EVENT_ID_OID,IMPACT,UPDATEDBYUSER,DESCRIPTION,CATEGORY_RISKCATEGORY_ID_OID,ASSET_ENTITY_ID_OID,EVENTDESCRIPTION,CONSEQUENCESDESCRIPTION,RISKREGISTER_RISKREGISTER_ID_OID,EVENTSOURCEDESCRIPTION,OWNER_BUSINESSACTOR_ID_OID,IMPACTLEVEL_IMPACTLEVEL_ID_OID,CREATEDBYUSER,TENANTID,EVENTSOURCE_EVENTSOURCE_ID_OID,LIKELIHOODLEVEL_LIKELIHOODLEVEL_ID_OID,DATECREATED,DATEUPDATED,RISKSLEADEDBYIT_VULNERABILITY_ID_OID,RISKSMODIFIED_CONTROL_ID_OID)
>> VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?), 1) returned
>> net.sf.log4jdbc.PreparedStatementSpy@afe1bc5
>> 11:12:30,894  [audit                main       INFO ]  2.
>> PreparedStatement.clearBatch() returned
>> 11:12:30,894  [audit                main       INFO ]  2.
>> PreparedStatement.setTimestamp(23, 2013-08-03 11:12:30.643,
>> java.util.GregorianCalendar[time=1375521135947,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/Madrid",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=165,lastRule=java.util.SimpleTimeZone[id=Europe/Madrid,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2013,MONTH=7,WEEK_OF_YEAR=31,WEEK_OF_MONTH=1,DAY_OF_MONTH=3,DAY_OF_YEAR=215,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=11,HOUR_OF_DAY=11,MINUTE=12,SECOND=15,MILLISECOND=947,ZONE_OFFSET=3600000,DST_OFFSET=3600000])
>> returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setTimestamp(22, 2013-08-03 11:12:30.643,
>> java.util.GregorianCalendar[time=1375521135947,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Europe/Madrid",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=165,lastRule=java.util.SimpleTimeZone[id=Europe/Madrid,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2013,MONTH=7,WEEK_OF_YEAR=31,WEEK_OF_MONTH=1,DAY_OF_MONTH=3,DAY_OF_YEAR=215,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=11,HOUR_OF_DAY=11,MINUTE=12,SECOND=15,MILLISECOND=947,ZONE_OFFSET=3600000,DST_OFFSET=3600000])
>> returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setNull(21, -5) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setNull(20, -5) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setString(19, "TENANT") returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setString(18, "tester") returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setNull(17, -5) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setNull(16, -5) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setNull(15, 12) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setLong(14, 2) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setNull(13, 12) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setNull(12, 12) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setLong(11, 15) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setNull(10, -5) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setNull(9, 12) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setString(8, "tester") returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setBigDecimal(7, 1000.0) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setLong(6, 0) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setNull(5, 12) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setBigDecimal(4, 0.5) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setBoolean(3, true) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setNull(2, 12) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setString(1, "2BB81475-3DB5-49B6-A2C2-CEECEA5B1A4B")
>> returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setNull(24, -5) returned
>> 11:12:30,895  [audit                main       INFO ]  2.
>> PreparedStatement.setNull(25, -5) returned
>> 11:12:30,895  [Native               main       DEBUG]  INSERT INTO RISK
>> (ID,"NAME",AUTOMATICNAMING,LIKELIHOOD,CODE,EVENT_EVENT_ID_OID,IMPACT,UPDATEDBYUSER,DESCRIPTION,CATEGORY_RISKCATEGORY_ID_OID,ASSET_ENTITY_ID_OID,EVENTDESCRIPTION,CONSEQUENCESDESCRIPTION,RISKREGISTER_RISKREGISTER_ID_OID,EVENTSOURCEDESCRIPTION,OWNER_BUSINESSACTOR_ID_OID,IMPACTLEVEL_IMPACTLEVEL_ID_OID,CREATEDBYUSER,TENANTID,EVENTSOURCE_EVENTSOURCE_ID_OID,LIKELIHOODLEVEL_LIKELIHOODLEVEL_ID_OID,DATECREATED,DATEUPDATED,RISKSLEADEDBYIT_VULNERABILITY_ID_OID,RISKSMODIFIED_CONTROL_ID_OID)
>> VALUES
>> (<'2BB81475-3DB5-49B6-A2C2-CEECEA5B1A4B'>,<null>,<true>,<0.5>,<null>,<0>,<1000.0>,<'tester'>,<null>,<null>,<15>,<null>,<null>,<2>,<null>,<null>,<null>,<'tester'>,<'TENANT'>,<null>,<null>,<2013-08-03
>> 11:12:30.643>,<2013-08-03 11:12:30.643>,<null>,<null>)
>> 11:12:30,895  [Native               main       DEBUG]  INSERT INTO RISK
>> (ID,"NAME",AUTOMATICNAMING,LIKELIHOOD,CODE,EVENT_EVENT_ID_OID,IMPACT,UPDATEDBYUSER,DESCRIPTION,CATEGORY_RISKCATEGORY_ID_OID,ASSET_ENTITY_ID_OID,EVENTDESCRIPTION,CONSEQUENCESDESCRIPTION,RISKREGISTER_RISKREGISTER_ID_OID,EVENTSOURCEDESCRIPTION,OWNER_BUSINESSACTOR_ID_OID,IMPACTLEVEL_IMPACTLEVEL_ID_OID,CREATEDBYUSER,TENANTID,EVENTSOURCE_EVENTSOURCE_ID_OID,LIKELIHOODLEVEL_LIKELIHOODLEVEL_ID_OID,DATECREATED,DATEUPDATED,RISKSLEADEDBYIT_VULNERABILITY_ID_OID,RISKSMODIFIED_CONTROL_ID_OID)
>> VALUES
>> (<'2BB81475-3DB5-49B6-A2C2-CEECEA5B1A4B'>,<null>,<true>,<0.5>,<null>,<0>,<1000.0>,<'tester'>,<null>,<null>,<15>,<null>,<null>,<2>,<null>,<null>,<null>,<'tester'>,<'TENANT'>,<null>,<null>,<2013-08-03
>> 11:12:30.643>,<2013-08-03 11:12:30.643>,<null>,<null>)
>> 11:12:30,895  [Native               main       DEBUG]  INSERT INTO RISK
>> (ID,"NAME",AUTOMATICNAMING,LIKELIHOOD,CODE,EVENT_EVENT_ID_OID,IMPACT,UPDATEDBYUSER,DESCRIPTION,CATEGORY_RISKCATEGORY_ID_OID,ASSET_ENTITY_ID_OID,EVENTDESCRIPTION,CONSEQUENCESDESCRIPTION,RISKREGISTER_RISKREGISTER_ID_OID,EVENTSOURCEDESCRIPTION,OWNER_BUSINESSACTOR_ID_OID,IMPACTLEVEL_IMPACTLEVEL_ID_OID,CREATEDBYUSER,TENANTID,EVENTSOURCE_EVENTSOURCE_ID_OID,LIKELIHOODLEVEL_LIKELIHOODLEVEL_ID_OID,DATECREATED,DATEUPDATED,RISKSLEADEDBYIT_VULNERABILITY_ID_OID,RISKSMODIFIED_CONTROL_ID_OID)
>> VALUES
>> (<'2BB81475-3DB5-49B6-A2C2-CEECEA5B1A4B'>,<null>,<true>,<0.5>,<null>,<0>,<1000.0>,<'tester'>,<null>,<null>,<15>,<null>,<null>,<2>,<null>,<null>,<null>,<'tester'>,<'TENANT'>,<null>,<null>,<2013-08-03
>> 11:12:30.643>,<2013-08-03 11:12:30.643>,<null>,<null>)
>> 11:12:30,895  [sqlonly              main       INFO ]  INSERT INTO RISK
>> (ID,"NAME",AUTOMATICNAMING,LIKELIHOOD,CODE,EVENT_EVENT_ID_OID,IMPACT,UPDATEDBYUSER,DESCRIPTION,CATEGORY_RISKCATEGORY_ID_OID,ASSET_ENTITY_ID_OID,EVENTDESCRIPTION,CONSEQUENCESDESCRIPTION,RISKREGISTER_RISKREGISTER_ID_OID,EVENTSOURCEDESCRIPTION,OWNER_BUSINESSACTOR_ID_OID,IMPACTLEVEL_IMPACTLEVEL_ID_OID,CREATEDBYUSER,TENANTID,EVENTSOURCE_EVENTSOURCE_ID_OID,LIKELIHOODLEVEL_LIKELIHOODLEVEL_ID_OID,DATECREATED,DATEUPDATED,RISKSLEADEDBYIT_VULNERABILITY_ID_OID,RISKSMODIFIED_CONTROL_ID_OID)
>> VALUES
>> ('2BB81475-3DB5-49B6-A2C2-CEECEA5B1A4B',NULL,1,0.5,NULL,0,1000.0,'tester',NULL,NULL,15,NULL,NULL,2,NULL,NULL,NULL,'tester','TENANT',NULL,NULL,'08/03/2013
>> 11:12:30.643','08/03/2013 11:12:30.643',NULL,NULL)
>> 11:12:30,898  [audit                main       ERROR]  2.
>> PreparedStatement.executeUpdate() INSERT INTO RISK
>> (ID,"NAME",AUTOMATICNAMING,LIKELIHOOD,CODE,EVENT_EVENT_ID_OID,IMPACT,UPDATEDBYUSER,DESCRIPTION,CATEGORY_RISKCATEGORY_ID_OID,ASSET_ENTITY_ID_OID,EVENTDESCRIPTION,CONSEQUENCESDESCRIPTION,RISKREGISTER_RISKREGISTER_ID_OID,EVENTSOURCEDESCRIPTION,OWNER_BUSINESSACTOR_ID_OID,IMPACTLEVEL_IMPACTLEVEL_ID_OID,CREATEDBYUSER,TENANTID,EVENTSOURCE_EVENTSOURCE_ID_OID,LIKELIHOODLEVEL_LIKELIHOODLEVEL_ID_OID,DATECREATED,DATEUPDATED,RISKSLEADEDBYIT_VULNERABILITY_ID_OID,RISKSMODIFIED_CONTROL_ID_OID)
>> VALUES
>> ('2BB81475-3DB5-49B6-A2C2-CEECEA5B1A4B',NULL,1,0.5,NULL,0,1000.0,'tester',NULL,NULL,15,NULL,NULL,2,NULL,NULL,NULL,'tester','TENANT',NULL,NULL,'08/03/2013
>> 11:12:30.643','08/03/2013 11:12:30.643',NULL,NULL)
>> java.sql.SQLIntegrityConstraintViolationException: violación del
>> restricción de integridad: restricción ('check') NOT NULL; SYS_CT_11646
>> table: RISK column: "NAME"
>>         at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
>>         at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
>>         at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown
>> Source)
>>         at org.hsqldb.jdbc.JDBCPreparedStatement.executeUpdate(Unknown
>> Source)
>>         at
>> net.sf.log4jdbc.PreparedStatementSpy.executeUpdate(PreparedStatementSpy.java:1022)
>>         at
>> org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
>>         at
>> org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
>>         at
>> org.datanucleus.store.rdbms.ParamLoggingPreparedStatement.executeUpdate(ParamLoggingPreparedStatement.java:399)
>>         at
>> org.datanucleus.store.rdbms.SQLController.executeStatementUpdate(SQLController.java:439)
>>         at
>> org.datanucleus.store.rdbms.request.InsertRequest.execute(InsertRequest.java:409)
>>         at
>> org.datanucleus.store.rdbms.RDBMSPersistenceHandler.insertTable(RDBMSPersistenceHandler.java:167)
>>         at
>> org.datanucleus.store.rdbms.RDBMSPersistenceHandler.insertObject(RDBMSPersistenceHandler.java:143)
>>         at
>> org.datanucleus.state.JDOStateManager.internalMakePersistent(JDOStateManager.java:3774)
>>         at
>> org.datanucleus.state.JDOStateManager.makePersistent(JDOStateManager.java:3750)
>>         at
>> org.datanucleus.ExecutionContextImpl.persistObjectInternal(ExecutionContextImpl.java:2125)
>>         at
>> org.datanucleus.ExecutionContextImpl.persistObjectWork(ExecutionContextImpl.java:1973)
>>         at
>> org.datanucleus.ExecutionContextImpl.persistObject(ExecutionContextImpl.java:1821)
>>         at
>> org.datanucleus.api.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:727)
>>         at
>> org.datanucleus.api.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceManager.java:752)
>>         at
>> org.apache.isis.objectstore.jdo.datanucleus.persistence.commands.DataNucleusCreateObjectCommand.execute(DataNucleusCreateObjectCommand.java:53)
>>         at
>> org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore.executeCommands(DataNucleusObjectStore.java:360)
>>         at
>> org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore.execute(DataNucleusObjectStore.java:354)
>>         at
>> org.apache.isis.core.runtime.system.transaction.IsisTransaction.doFlush(IsisTransaction.java:367)
>>         at
>> org.apache.isis.core.runtime.system.transaction.IsisTransaction.flush(IsisTransaction.java:333)
>>         at
>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.flushTransaction(IsisTransactionManager.java:301)
>>         at
>> org.apache.isis.core.runtime.persistence.internal.RuntimeContextFromSession$7.flush(RuntimeContextFromSession.java:216)
>>         at
>> org.apache.isis.core.metamodel.services.container.DomainObjectContainerDefault.flush(DomainObjectContainerDefault.java:202)
>>         at
>> com.xms.framework.risk.domain.model.RiskRegister.addQuantitativeRiskToAsset(RiskRegister.java:391)
>>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>         at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>         at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>         at java.lang.reflect.Method.invoke(Method.java:597)
>>         at
>> org.apache.isis.core.progmodel.facets.actions.invoke.ActionInvocationFacetViaMethod.invoke(ActionInvocationFacetViaMethod.java:94)
>>         at
>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:55)
>>         at
>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:52)
>>         at
>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.executeWithinTransaction(IsisTransactionManager.java:220)
>>         at
>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction.invoke(ActionInvocationFacetWrapTransaction.java:52)
>>         at
>> org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl.execute(ObjectActionImpl.java:412)
>>         at
>> org.apache.isis.core.wrapper.internal.DomainObjectInvocationHandler.handleActionMethod(DomainObjectInvocationHandler.java:509)
>>         at
>> org.apache.isis.core.wrapper.internal.DomainObjectInvocationHandler.invoke(DomainObjectInvocationHandler.java:236)
>>         at
>> org.apache.isis.core.wrapper.internal.InvocationHandlerMethodInterceptor.intercept(InvocationHandlerMethodInterceptor.java:37)
>>         at
>> com.xms.framework.risk.domain.model.RiskRegister$$EnhancerByCGLIB$$c25c4db1.addQuantitativeRiskToAsset(<generated>)
>>         at
>> com.xms.framework.risk.integration.glue.risk.RiskRegisterGlue.when_add_quantitative_risk_to_this_risk_register_with_asset_and_threat_event_and_likelihood_and_impact(RiskRegisterGlue.java:211)
>>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>         at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>         at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>         at java.lang.reflect.Method.invoke(Method.java:597)
>>         at cucumber.runtime.Utils$1.call(Utils.java:44)
>>         at cucumber.runtime.Timeout.timeout(Timeout.java:12)
>>         at cucumber.runtime.Utils.invoke(Utils.java:40)
>>         at
>> cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.java:35)
>>         at
>> cucumber.runtime.StepDefinitionMatch.runStep(StepDefinitionMatch.java:38)
>>         at cucumber.runtime.Runtime.runStep(Runtime.java:271)
>>         at
>> cucumber.runtime.model.StepContainer.runStep(StepContainer.java:44)
>>         at
>> cucumber.runtime.model.StepContainer.runSteps(StepContainer.java:39)
>>         at
>> cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:40)
>>         at
>> cucumber.runtime.junit.ExecutionUnitRunner.run(ExecutionUnitRunner.java:83)
>>         at
>> cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:63)
>>         at
>> cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:18)
>>         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.runners.ParentRunner.run(ParentRunner.java:309)
>>         at cucumber.runtime.junit.FeatureRunner.run(FeatureRunner.java:70)
>>         at cucumber.api.junit.Cucumber.runChild(Cucumber.java:77)
>>         at cucumber.api.junit.Cucumber.runChild(Cucumber.java:37)
>>         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.runners.ParentRunner.run(ParentRunner.java:309)
>>         at cucumber.api.junit.Cucumber.run(Cucumber.java:82)
>>         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)
>> Caused by: org.hsqldb.HsqlException: violación del restricción de
>> integridad: restricción ('check') NOT NULL; SYS_CT_11646 table: RISK
>> column: "NAME"
>>         at org.hsqldb.error.Error.error(Unknown Source)
>>         at org.hsqldb.Table.enforceRowConstraints(Unknown Source)
>>         at org.hsqldb.Table.insertSingleRow(Unknown Source)
>>         at org.hsqldb.StatementDML.insertRowSet(Unknown Source)
>>         at org.hsqldb.StatementInsert.getResult(Unknown Source)
>>         at org.hsqldb.StatementDMQL.execute(Unknown Source)
>>         at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
>>         at org.hsqldb.Session.execute(Unknown Source)
>>         ... 79 more
>> 11:12:30,902  [sqlonly              main       ERROR]  2.
>> PreparedStatement.executeUpdate() INSERT INTO RISK
>> (ID,"NAME",AUTOMATICNAMING,LIKELIHOOD,CODE,EVENT_EVENT_ID_OID,IMPACT,UPDATEDBYUSER,DESCRIPTION,CATEGORY_RISKCATEGORY_ID_OID,ASSET_ENTITY_ID_OID,EVENTDESCRIPTION,CONSEQUENCESDESCRIPTION,RISKREGISTER_RISKREGISTER_ID_OID,EVENTSOURCEDESCRIPTION,OWNER_BUSINESSACTOR_ID_OID,IMPACTLEVEL_IMPACTLEVEL_ID_OID,CREATEDBYUSER,TENANTID,EVENTSOURCE_EVENTSOURCE_ID_OID,LIKELIHOODLEVEL_LIKELIHOODLEVEL_ID_OID,DATECREATED,DATEUPDATED,RISKSLEADEDBYIT_VULNERABILITY_ID_OID,RISKSMODIFIED_CONTROL_ID_OID)
>> VALUES
>> ('2BB81475-3DB5-49B6-A2C2-CEECEA5B1A4B',NULL,1,0.5,NULL,0,1000.0,'tester',NULL,NULL,15,NULL,NULL,2,NULL,NULL,NULL,'tester','TENANT',NULL,NULL,'08/03/2013
>> 11:12:30.643','08/03/2013 11:12:30.643',NULL,NULL)
>> java.sql.SQLIntegrityConstraintViolationException: violación del
>> restricción de integridad: restricción ('check') NOT NULL; SYS_CT_11646
>> table: RISK column: "NAME"
>>         at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
>>         at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
>>         at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown
>> Source)
>>         at org.hsqldb.jdbc.JDBCPreparedStatement.executeUpdate(Unknown
>> Source)
>>         at
>> net.sf.log4jdbc.PreparedStatementSpy.executeUpdate(PreparedStatementSpy.java:1022)
>>         at
>> org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
>>         at
>> org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
>>         at
>> org.datanucleus.store.rdbms.ParamLoggingPreparedStatement.executeUpdate(ParamLoggingPreparedStatement.java:399)
>>         at
>> org.datanucleus.store.rdbms.SQLController.executeStatementUpdate(SQLController.java:439)
>>         at
>> org.datanucleus.store.rdbms.request.InsertRequest.execute(InsertRequest.java:409)
>>         at
>> org.datanucleus.store.rdbms.RDBMSPersistenceHandler.insertTable(RDBMSPersistenceHandler.java:167)
>>         at
>> org.datanucleus.store.rdbms.RDBMSPersistenceHandler.insertObject(RDBMSPersistenceHandler.java:143)
>>         at
>> org.datanucleus.state.JDOStateManager.internalMakePersistent(JDOStateManager.java:3774)
>>         at
>> org.datanucleus.state.JDOStateManager.makePersistent(JDOStateManager.java:3750)
>>         at
>> org.datanucleus.ExecutionContextImpl.persistObjectInternal(ExecutionContextImpl.java:2125)
>>         at
>> org.datanucleus.ExecutionContextImpl.persistObjectWork(ExecutionContextImpl.java:1973)
>>         at
>> org.datanucleus.ExecutionContextImpl.persistObject(ExecutionContextImpl.java:1821)
>>         at
>> org.datanucleus.api.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:727)
>>         at
>> org.datanucleus.api.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceManager.java:752)
>>         at
>> org.apache.isis.objectstore.jdo.datanucleus.persistence.commands.DataNucleusCreateObjectCommand.execute(DataNucleusCreateObjectCommand.java:53)
>>         at
>> org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore.executeCommands(DataNucleusObjectStore.java:360)
>>         at
>> org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore.execute(DataNucleusObjectStore.java:354)
>>         at
>> org.apache.isis.core.runtime.system.transaction.IsisTransaction.doFlush(IsisTransaction.java:367)
>>         at
>> org.apache.isis.core.runtime.system.transaction.IsisTransaction.flush(IsisTransaction.java:333)
>>         at
>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.flushTransaction(IsisTransactionManager.java:301)
>>         at
>> org.apache.isis.core.runtime.persistence.internal.RuntimeContextFromSession$7.flush(RuntimeContextFromSession.java:216)
>>         at
>> org.apache.isis.core.metamodel.services.container.DomainObjectContainerDefault.flush(DomainObjectContainerDefault.java:202)
>>         at
>> com.xms.framework.risk.domain.model.RiskRegister.addQuantitativeRiskToAsset(RiskRegister.java:391)
>>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>         at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>         at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>         at java.lang.reflect.Method.invoke(Method.java:597)
>>         at
>> org.apache.isis.core.progmodel.facets.actions.invoke.ActionInvocationFacetViaMethod.invoke(ActionInvocationFacetViaMethod.java:94)
>>         at
>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:55)
>>         at
>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:52)
>>         at
>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.executeWithinTransaction(IsisTransactionManager.java:220)
>>         at
>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction.invoke(ActionInvocationFacetWrapTransaction.java:52)
>>         at
>> org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl.execute(ObjectActionImpl.java:412)
>>         at
>> org.apache.isis.core.wrapper.internal.DomainObjectInvocationHandler.handleActionMethod(DomainObjectInvocationHandler.java:509)
>>         at
>> org.apache.isis.core.wrapper.internal.DomainObjectInvocationHandler.invoke(DomainObjectInvocationHandler.java:236)
>>         at
>> org.apache.isis.core.wrapper.internal.InvocationHandlerMethodInterceptor.intercept(InvocationHandlerMethodInterceptor.java:37)
>>         at
>> com.xms.framework.risk.domain.model.RiskRegister$$EnhancerByCGLIB$$c25c4db1.addQuantitativeRiskToAsset(<generated>)
>>         at
>> com.xms.framework.risk.integration.glue.risk.RiskRegisterGlue.when_add_quantitative_risk_to_this_risk_register_with_asset_and_threat_event_and_likelihood_and_impact(RiskRegisterGlue.java:211)
>>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>         at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>         at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>         at java.lang.reflect.Method.invoke(Method.java:597)
>>         at cucumber.runtime.Utils$1.call(Utils.java:44)
>>         at cucumber.runtime.Timeout.timeout(Timeout.java:12)
>>         at cucumber.runtime.Utils.invoke(Utils.java:40)
>>         at
>> cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.java:35)
>>         at
>> cucumber.runtime.StepDefinitionMatch.runStep(StepDefinitionMatch.java:38)
>>         at cucumber.runtime.Runtime.runStep(Runtime.java:271)
>>         at
>> cucumber.runtime.model.StepContainer.runStep(StepContainer.java:44)
>>         at
>> cucumber.runtime.model.StepContainer.runSteps(StepContainer.java:39)
>>         at
>> cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:40)
>>         at
>> cucumber.runtime.junit.ExecutionUnitRunner.run(ExecutionUnitRunner.java:83)
>>         at
>> cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:63)
>>         at
>> cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:18)
>>         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.runners.ParentRunner.run(ParentRunner.java:309)
>>         at cucumber.runtime.junit.FeatureRunner.run(FeatureRunner.java:70)
>>         at cucumber.api.junit.Cucumber.runChild(Cucumber.java:77)
>>         at cucumber.api.junit.Cucumber.runChild(Cucumber.java:37)
>>         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.runners.ParentRunner.run(ParentRunner.java:309)
>>         at cucumber.api.junit.Cucumber.run(Cucumber.java:82)
>>         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)
>> Caused by: org.hsqldb.HsqlException: violación del restricción de
>> integridad: restricción ('check') NOT NULL; SYS_CT_11646 table: RISK
>> column: "NAME"
>>         at org.hsqldb.error.Error.error(Unknown Source)
>>         at org.hsqldb.Table.enforceRowConstraints(Unknown Source)
>>         at org.hsqldb.Table.insertSingleRow(Unknown Source)
>>         at org.hsqldb.StatementDML.insertRowSet(Unknown Source)
>>         at org.hsqldb.StatementInsert.getResult(Unknown Source)
>>         at org.hsqldb.StatementDMQL.execute(Unknown Source)
>>         at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
>>         at org.hsqldb.Session.execute(Unknown Source)
>>         ... 79 more
>> 11:12:30,902  [sqltiming            main       ERROR]  2.
>> PreparedStatement.executeUpdate() FAILED! INSERT INTO RISK
>> (ID,"NAME",AUTOMATICNAMING,LIKELIHOOD,CODE,EVENT_EVENT_ID_OID,IMPACT,UPDATEDBYUSER,DESCRIPTION,CATEGORY_RISKCATEGORY_ID_OID,ASSET_ENTITY_ID_OID,EVENTDESCRIPTION,CONSEQUENCESDESCRIPTION,RISKREGISTER_RISKREGISTER_ID_OID,EVENTSOURCEDESCRIPTION,OWNER_BUSINESSACTOR_ID_OID,IMPACTLEVEL_IMPACTLEVEL_ID_OID,CREATEDBYUSER,TENANTID,EVENTSOURCE_EVENTSOURCE_ID_OID,LIKELIHOODLEVEL_LIKELIHOODLEVEL_ID_OID,DATECREATED,DATEUPDATED,RISKSLEADEDBYIT_VULNERABILITY_ID_OID,RISKSMODIFIED_CONTROL_ID_OID)
>> VALUES
>> ('2BB81475-3DB5-49B6-A2C2-CEECEA5B1A4B',NULL,1,0.5,NULL,0,1000.0,'tester',NULL,NULL,15,NULL,NULL,2,NULL,NULL,NULL,'tester','TENANT',NULL,NULL,'08/03/2013
>> 11:12:30.643','08/03/2013 11:12:30.643',NULL,NULL) {FAILED after 2 msec}
>> java.sql.SQLIntegrityConstraintViolationException: violación del
>> restricción de integridad: restricción ('check') NOT NULL; SYS_CT_11646
>> table: RISK column: "NAME"
>>         at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
>>         at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
>>         at org.hsqldb.jdbc.JDBCPreparedStatement.fetchResult(Unknown
>> Source)
>>         at org.hsqldb.jdbc.JDBCPreparedStatement.executeUpdate(Unknown
>> Source)
>>         at
>> net.sf.log4jdbc.PreparedStatementSpy.executeUpdate(PreparedStatementSpy.java:1022)
>>         at
>> org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
>>         at
>> org.datanucleus.store.rdbms.datasource.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
>>         at
>> org.datanucleus.store.rdbms.ParamLoggingPreparedStatement.executeUpdate(ParamLoggingPreparedStatement.java:399)
>>         at
>> org.datanucleus.store.rdbms.SQLController.executeStatementUpdate(SQLController.java:439)
>>         at
>> org.datanucleus.store.rdbms.request.InsertRequest.execute(InsertRequest.java:409)
>>         at
>> org.datanucleus.store.rdbms.RDBMSPersistenceHandler.insertTable(RDBMSPersistenceHandler.java:167)
>>         at
>> org.datanucleus.store.rdbms.RDBMSPersistenceHandler.insertObject(RDBMSPersistenceHandler.java:143)
>>         at
>> org.datanucleus.state.JDOStateManager.internalMakePersistent(JDOStateManager.java:3774)
>>         at
>> org.datanucleus.state.JDOStateManager.makePersistent(JDOStateManager.java:3750)
>>         at
>> org.datanucleus.ExecutionContextImpl.persistObjectInternal(ExecutionContextImpl.java:2125)
>>         at
>> org.datanucleus.ExecutionContextImpl.persistObjectWork(ExecutionContextImpl.java:1973)
>>         at
>> org.datanucleus.ExecutionContextImpl.persistObject(ExecutionContextImpl.java:1821)
>>         at
>> org.datanucleus.api.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:727)
>>         at
>> org.datanucleus.api.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceManager.java:752)
>>         at
>> org.apache.isis.objectstore.jdo.datanucleus.persistence.commands.DataNucleusCreateObjectCommand.execute(DataNucleusCreateObjectCommand.java:53)
>>         at
>> org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore.executeCommands(DataNucleusObjectStore.java:360)
>>         at
>> org.apache.isis.objectstore.jdo.datanucleus.DataNucleusObjectStore.execute(DataNucleusObjectStore.java:354)
>>         at
>> org.apache.isis.core.runtime.system.transaction.IsisTransaction.doFlush(IsisTransaction.java:367)
>>         at
>> org.apache.isis.core.runtime.system.transaction.IsisTransaction.flush(IsisTransaction.java:333)
>>         at
>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.flushTransaction(IsisTransactionManager.java:301)
>>         at
>> org.apache.isis.core.runtime.persistence.internal.RuntimeContextFromSession$7.flush(RuntimeContextFromSession.java:216)
>>         at
>> org.apache.isis.core.metamodel.services.container.DomainObjectContainerDefault.flush(DomainObjectContainerDefault.java:202)
>>         at
>> com.xms.framework.risk.domain.model.RiskRegister.addQuantitativeRiskToAsset(RiskRegister.java:391)
>>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>         at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>         at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>         at java.lang.reflect.Method.invoke(Method.java:597)
>>         at
>> org.apache.isis.core.progmodel.facets.actions.invoke.ActionInvocationFacetViaMethod.invoke(ActionInvocationFacetViaMethod.java:94)
>>         at
>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:55)
>>         at
>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction$1.execute(ActionInvocationFacetWrapTransaction.java:52)
>>         at
>> org.apache.isis.core.runtime.system.transaction.IsisTransactionManager.executeWithinTransaction(IsisTransactionManager.java:220)
>>         at
>> org.apache.isis.core.runtime.transaction.facets.ActionInvocationFacetWrapTransaction.invoke(ActionInvocationFacetWrapTransaction.java:52)
>>         at
>> org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionImpl.execute(ObjectActionImpl.java:412)
>>         at
>> org.apache.isis.core.wrapper.internal.DomainObjectInvocationHandler.handleActionMethod(DomainObjectInvocationHandler.java:509)
>>         at
>> org.apache.isis.core.wrapper.internal.DomainObjectInvocationHandler.invoke(DomainObjectInvocationHandler.java:236)
>>         at
>> org.apache.isis.core.wrapper.internal.InvocationHandlerMethodInterceptor.intercept(InvocationHandlerMethodInterceptor.java:37)
>>         at
>> com.xms.framework.risk.domain.model.RiskRegister$$EnhancerByCGLIB$$c25c4db1.addQuantitativeRiskToAsset(<generated>)
>>         at
>> com.xms.framework.risk.integration.glue.risk.RiskRegisterGlue.when_add_quantitative_risk_to_this_risk_register_with_asset_and_threat_event_and_likelihood_and_impact(RiskRegisterGlue.java:211)
>>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>         at
>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>         at
>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>         at java.lang.reflect.Method.invoke(Method.java:597)
>>         at cucumber.runtime.Utils$1.call(Utils.java:44)
>>         at cucumber.runtime.Timeout.timeout(Timeout.java:12)
>>         at cucumber.runtime.Utils.invoke(Utils.java:40)
>>         at
>> cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.java:35)
>>         at
>> cucumber.runtime.StepDefinitionMatch.runStep(StepDefinitionMatch.java:38)
>>         at cucumber.runtime.Runtime.runStep(Runtime.java:271)
>>         at
>> cucumber.runtime.model.StepContainer.runStep(StepContainer.java:44)
>>         at
>> cucumber.runtime.model.StepContainer.runSteps(StepContainer.java:39)
>>         at
>> cucumber.runtime.model.CucumberScenario.run(CucumberScenario.java:40)
>>         at
>> cucumber.runtime.junit.ExecutionUnitRunner.run(ExecutionUnitRunner.java:83)
>>         at
>> cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:63)
>>         at
>> cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:18)
>>         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.runners.ParentRunner.run(ParentRunner.java:309)
>>         at cucumber.runtime.junit.FeatureRunner.run(FeatureRunner.java:70)
>>         at cucumber.api.junit.Cucumber.runChild(Cucumber.java:77)
>>         at cucumber.api.junit.Cucumber.runChild(Cucumber.java:37)
>>         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.runners.ParentRunner.run(ParentRunner.java:309)
>>         at cucumber.api.junit.Cucumber.run(Cucumber.java:82)
>>         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)
>> Caused by: org.hsqldb.HsqlException: violación del restricción de
>> integridad: restricción ('check') NOT NULL; SYS_CT_11646 table: RISK
>> column: "NAME"
>>         at org.hsqldb.error.Error.error(Unknown Source)
>>         at org.hsqldb.Table.enforceRowConstraints(Unknown Source)
>>         at org.hsqldb.Table.insertSingleRow(Unknown Source)
>>         at org.hsqldb.StatementDML.insertRowSet(Unknown Source)
>>         at org.hsqldb.StatementInsert.getResult(Unknown Source)
>>         at org.hsqldb.StatementDMQL.execute(Unknown Source)
>>         at org.hsqldb.Session.executeCompiledStatement(Unknown Source)
>>         at org.hsqldb.Session.execute(Unknown Source)
>>         ... 79 more
>> 11:12:30,903  [audit                main       INFO ]  2.
>> PreparedStatement.close() returned
>> 11:12:30,903  [Persist              main       WARN ]  Persistencia del
>> objeto "com.xms.framework.risk.domain.model.Risk@1b373a71" con SQL
>> "INSERT INTO RISK
>> (ID,"NAME",AUTOMATICNAMING,LIKELIHOOD,CODE,EVENT_EVENT_ID_OID,IMPACT,UPDATEDBYUSER,DESCRIPTION,CATEGORY_RISKCATEGORY_ID_OID,ASSET_ENTITY_ID_OID,EVENTDESCRIPTION,CONSEQUENCESDESCRIPTION,RISKREGISTER_RISKREGISTER_ID_OID,EVENTSOURCEDESCRIPTION,OWNER_BUSINESSACTOR_ID_OID,IMPACTLEVEL_IMPACTLEVEL_ID_OID,CREATEDBYUSER,TENANTID,EVENTSOURCE_EVENTSOURCE_ID_OID,LIKELIHOODLEVEL_LIKELIHOODLEVEL_ID_OID,DATECREATED,DATEUPDATED,RISKSLEADEDBYIT_VULNERABILITY_ID_OID,RISKSMODIFIED_CONTROL_ID_OID)
>> VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)" ha tirado un
>> error : violación del restricción de integridad: restricción ('check') NOT
>> NULL; SYS_CT_11646 table: RISK column: "NAME"
>> 11:12:30,903  [Persist              main       WARN ]  Persistencia del
>> objeto "com.xms.framework.risk.domain.model.Risk@1b373a71" con SQL
>> "INSERT INTO RISK
>> (ID,"NAME",AUTOMATICNAMING,LIKELIHOOD,CODE,EVENT_EVENT_ID_OID,IMPACT,UPDATEDBYUSER,DESCRIPTION,CATEGORY_RISKCATEGORY_ID_OID,ASSET_ENTITY_ID_OID,EVENTDESCRIPTION,CONSEQUENCESDESCRIPTION,RISKREGISTER_RISKREGISTER_ID_OID,EVENTSOURCEDESCRIPTION,OWNER_BUSINESSACTOR_ID_OID,IMPACTLEVEL_IMPACTLEVEL_ID_OID,CREATEDBYUSER,TENANTID,EVENTSOURCE_EVENTSOURCE_ID_OID,LIKELIHOODLEVEL_LIKELIHOODLEVEL_ID_OID,DATECREATED,DATEUPDATED,RISKSLEADEDBYIT_VULNERABILITY_ID_OID,RISKSMODIFIED_CONTROL_ID_OID)
>> VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)" ha tirado un
>> error : violación del restricción de integridad: restricción ('check') NOT
>> NULL; SYS_CT_11646 table: RISK column: "NAME"
>> 11:12:30,903  [Persist              main       WARN ]  Persistencia del
>> objeto "com.xms.framework.risk.domain.model.Risk@1b373a71" con SQL
>> "INSERT INTO RISK
>> (ID,"NAME",AUTOMATICNAMING,LIKELIHOOD,CODE,EVENT_EVENT_ID_OID,IMPACT,UPDATEDBYUSER,DESCRIPTION,CATEGORY_RISKCATEGORY_ID_OID,ASSET_ENTITY_ID_OID,EVENTDESCRIPTION,CONSEQUENCESDESCRIPTION,RISKREGISTER_RISKREGISTER_ID_OID,EVENTSOURCEDESCRIPTION,OWNER_BUSINESSACTOR_ID_OID,IMPACTLEVEL_IMPACTLEVEL_ID_OID,CREATEDBYUSER,TENANTID,EVENTSOURCE_EVENTSOURCE_ID_OID,LIKELIHOODLEVEL_LIKELIHOODLEVEL_ID_OID,DATECREATED,DATEUPDATED,RISKSLEADEDBYIT_VULNERABILITY_ID_OID,RISKSMODIFIED_CONTROL_ID_OID)
>> VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)" ha tirado un
>> error : violación del restricción de integridad: restricción ('check') NOT
>> NULL; SYS_CT_11646 table: RISK column: "NAME"
>>
>>
>> -------------------------
>>
>> Despite that, the this.persist(risk) code is executed without throwing an
>> exception.
>>
>>
>>
>> The problem with the seems to be related to the current
>> "executeWithinTransaction()" implementation:
>>
>> public class IsisTransactionManager implements SessionScopedComponent {
>>
>>    ...
>>
>>    public <Q> Q executeWithinTransaction(final
>> TransactionalClosureWithReturn<Q> closure) {
>>         final boolean initiallyInTransaction = inTransaction();
>>         if (!initiallyInTransaction) {
>>             startTransaction();
>>         }
>>         try {
>>             closure.preExecute();
>>             final Q retVal = closure.execute();
>>             closure.onSuccess();
>>             if (!initiallyInTransaction) {
>>                 endTransaction();
>>             }
>>             return retVal;
>>         } catch (final RuntimeException ex) {
>>             closure.onFailure();
>>             if (!initiallyInTransaction) {
>>                 abortTransaction();
>>             }
>>             throw ex;
>>         }
>>     }
>>
>>
>> As my current "closure" implementation does not have any code on the
>> "onFailure()" method:
>>
>>         @Programmatic
>>         public <S extends AbstractXMSDomainObject> List<S> findByProp(
>>                         final Class<S> clazz, final String whereClause,
>>                         final Integer firstResult, final Integer
>> maxResults,
>>                         final String orderClause) {
>>                 return
>> IsisContext.getTransactionManager().executeWithinTransaction(
>>                                 new
>> TransactionalClosureWithReturnAbstract<List<S>>() {
>>
>>                                         @Override
>>                                         public List<S> execute() {
>>                                                 return
>> AbstractXMSDomainObjectRepositoryAndFactory.this
>>
>> .doFindByProp(clazz, whereClause, firstResult,
>>
>>       maxResults, orderClause);
>>                                         }
>>                                 });
>>
>>         }
>>
>>
>> The "closure.onFailure()" does nothing, and the exception is shadowed. So
>> no exception is thrown by the "persist()" method.
>>
>> But for this to happen,  seems to imply that the object has not been
>> validated before sending it to the persistence manager. I understand that
>> it should be validated by Isis before sending to the database.
>>
>>
>> So basically, I have the following problems:
>>
>> 1. Domain Object not validated by Isis before being sent to the database
>> (executed within a BDD test; perhaps that's relevant).
>>
>> 2. Not sure if I could/should throw an exception on the "onFailure()"
>> closure (as the Isis transaction wouldn't be aborted).
>>
>> 3. I would expect to be able to know the Runtime Exception that has
>> originated the failure.
>>
>>
>>
>> And I would propose the following changes to current Isis implementation:
>>
>> - It would imply to change IsisTransactionManager current implementation.
>> - If no code should be broken for avoiding major version update if
>> semantic versioning is followed, a descendant of
>> TransactionalClosureWithReturn  could be defined with a new method
>> "onFailureWithReason(RuntimeException runtimeException)".
>> - Also, if an exception can be raised on any "onFailureXXX()"
>> implementation, protect the abortTransaction(); code inside a try - finally
>> block).
>> - I don't expect that any corrective action will need a transaction. If
>> that can be expected in other use cases, the "onFailure()" method could
>> return a Boolean parameter to indicate if the Isis transaction must also be
>> aborted and the current IsisTransactionManager should be modify in
>> accordance.
>>
>>
>> Thanks,
>>
>> Oscar
>>
>>
>>
>>
>

Reply via email to