In order to work on data compiled in my local database, I have created a HashMap with an object as key and a String as value, containing the data that I need.
When I pass this HashMap and the key to the Drools session, I find that I cannot retrieve the required value with that key.
Here's the error that I get:
org.drools.runtime.rule.ConsequenceException: rule: Education
at org.drools.runtime.rule.impl.DefaultConsequenceExceptionHandler.handleException(DefaultConsequenceExceptionHandler.java:39)
at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:916)
at org.drools.common.DefaultAgenda.fireNextItem(DefaultAgenda.java:845)
at org.drools.common.DefaultAgenda.fireAllRules(DefaultAgenda.java:1056)
at org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:733)
at org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:699)
at org.drools.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:218)
at com.example.jeanineharb.reasoning.TriggerReceiver.onReceive(TriggerReceiver.java:117)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2609)
at android.app.ActivityThread.access$1700(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1380)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Caused by: [Error: unable to resolve method: java.util.HashMap.$k() [arglength=0]]
[Near : {... this[$k] ....}]
^
[Line: 1, Column: 6]
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getMethod(ReflectiveAccessorOptimizer.java:1094)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getMethod(ReflectiveAccessorOptimizer.java:1003)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getBeanProperty(ReflectiveAccessorOptimizer.java:693)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:360)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:163)
at org.mvel2.optimizers.dynamic.DynamicOptimizer.optimizeAccessor(DynamicOptimizer.java:81)
at org.mvel2.ast.ASTNode.optimize(ASTNode.java:159)
at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:115)
at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:38)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getCollectionProperty(ReflectiveAccessorOptimizer.java:758)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:366)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:163)
at org.mvel2.optimizers.dynamic.DynamicOptimizer.optimizeAccessor(DynamicOptimizer.java:81)
at org.mvel2.ast.ASTNode.optimize(ASTNode.java:159)
at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:115)
at org.mvel2.MVELRuntime.execute(MVELRuntime.java:85)
at org.mvel2.compiler.CompiledExpression.getDirectValue(CompiledExpression.java:123)
at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:119)
at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:113)
at org.mvel2.MVEL.executeExpression(MVEL.java:954)
at org.drools.base.extractors.MVELClassFieldReader.getValue(MVELClassFieldReader.java:153)
at org.drools.rule.Declaration.getValue(Declaration.java:219)
at org.drools.base.mvel.MVELCompilationUnit.updateFactory(MVELCompilationUnit.java:358)
at org.drools.base.mvel.MVELCompilationUnit.getFactory(MVELCompilationUnit.java:282)
at org.drools.base.mvel.MVELConsequence.evaluate(MVELConsequence.java:79)
at org.drools.common.DefaultAgenda.fireActivation(DefaultAgenda.java:906)
... 16 more
Here's the problematic rule:
rule "Education"
when
$s : Story( getQuestionContent().equals("") )
$k : Key( )
$msgMap : HashMap( $m : this[$k] != null )
then
modify ( $s ) {
setQuestionContent( $m )
};
end
Does anyone know why do I get this error?
ETA: I'm using Drools v5.2.0
Looks like this is a tad beyond the scope of the LHS expression syntax (which isn't defined precisely anywhere). Use this:
rule "Education"
when
$s : Story( questionContent == "" )
$k : Key()
$msgMap : HashMap( this[$k] != null )
then
modify ( $s ) {
setQuestionContent( $msgMap.get( $k ) )
};
end
Note that you can use == for string values.
Related
I am trying to fire the rule. However, I am getting following exception:
java.lang.RuntimeException: Unexpected global [map]
at org.drools.core.impl.StatefulKnowledgeSessionImpl.setGlobal(StatefulKnowledgeSessionImpl.java:1163)
at com.senselytics.inference.rule.RulesEngineStreamMode.init(RulesEngineStreamMode.java:72)
at com.senselytics.inference.rule.RulesEngineStreamMode.<init>(RulesEngineStreamMode.java:34)
at com.senselytics.inference.mq.MessageReceiverHandler.<init>(MessageReceiverHandler.java:15)
at com.senselytics.inference.mq.MessageReceiverHandler.getInstance(MessageReceiverHandler.java:22)
at com.senselytics.RulesEngineTest.testThreshhold(RulesEngineTest.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at junit.framework.TestCase.runTest(TestCase.java:176)
at junit.framework.TestCase.runBare(TestCase.java:141)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:252)
at junit.framework.TestSuite.run(TestSuite.java:247)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Code:
System.setProperty("drools.dialect.java.strict", "false");
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
.newKnowledgeBuilder();
Map<String, TagEvent> map = RulesEngineDAO.selectAllConfigDetails();
for (TagEvent tagEvent : map.values()) {
kbuilder.add(ResourceFactory.newReaderResource(TagEventRuleBuilder
.buildRuleFromTemplate(tagEvent)), ResourceType.DRL);
}
Collection<KnowledgePackage> pkgs = kbuilder.getKnowledgePackages();
KieBaseConfiguration kbaseConfiguration = KnowledgeBaseFactory
.newKnowledgeBaseConfiguration();
kbaseConfiguration.setOption(EventProcessingOption.STREAM);
final KnowledgeBase kbase = KnowledgeBaseFactory
.newKnowledgeBase(kbaseConfiguration);
kbase.addKnowledgePackages(pkgs);
KieSessionConfiguration sessionConf = KnowledgeBaseFactory
.newKnowledgeSessionConfiguration();
sessionConf.setOption(ClockTypeOption.get("realtime"));
ksession = kbase.newStatefulKnowledgeSession(sessionConf, null);
Map<String, TagEvent> globalMap = RulesEngineDAO.selectAllConfigDetails();
ksession.setGlobal("map", globalMap);
new Thread() {
#Override
public void run() {
ksession.fireUntilHalt();
}
}.start();
I am calling above code for making the session. Every thing is fine and am able to get the knowledge session. However, on the line
ksession.setGlobal("map", globalMap);
, above exception is thrown.
Am using the template for generation of DRL file and DRL file is getting generated also. In the template and generated DRL file:
global java.util.Map<String,TagEvent> map;
I am not really able to figure out why this error is coming up when running the code.
By using following code snippet :
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if( errors.size() > 0 )
{
for( KnowledgeBuilderError error : errors )
{
System.err.println( "Errors : "+error );
}
throw new IllegalArgumentException( "Could not parse knowledge." );
}
Now I am getting following errors:
Errors : [46,4]: [ERR 102] Line 46:4 mismatched input 'then' in rule "Count Values"
Errors : [0,0]: Parser returned a null Package
Errors : Unable to process type TagEventMetadata
Errors : Unable to process type TagEventTimeTracker
Errors : Unable to process type TagEvent
Errors : Unable to process type TagEventMetadata
Errors : Unable to process type TagEventTimeTracker
Errors : Unable to process type TagEvent
Errors : Unable to process type TagEventMetadata
Errors : Unable to process type TagEventTimeTracker
Errors : Unable to process type TagEvent
Errors : Unable to process type TagEventMetadata
Errors : Unable to process type TagEventTimeTracker
Errors : Unable to process type TagEvent
Errors : [46,4]: [ERR 102] Line 46:4 mismatched input 'then' in rule "Count Values"
Errors : [0,0]: Parser returned a null Package
Errors : Unable to process type TagEventMetadata
Errors : Unable to process type TagEventTimeTracker
Errors : Unable to process type TagEvent
DRL:
package com.senselytics.inference.rule.counter;
import java.util.HashMap;
import com.senselytics.inference.rule.*;
import com.senselytics.inference.vo.*;
import com.senselytics.inference.vo.TagEvent;
import com.senselytics.inference.vo.TagEventTimeTracker;
import com.senselytics.inference.vo.TagEventMetadata;
global java.util.Map<String,TagEvent> map;
declare TagEvent
#role( event )
#timestamp( tagTime )
#expires( 1s )
end
declare TagEventMetadata
#role( event )
end
declare TagEventTimeTracker
#role( event )
end
rule "Out Of Range Check -LOW"
dialect "java"
when
$tagEvent : TagEvent( status==Status.WITHIN_RANGE, tagValue != null,map.get($tagEvent.getTagName())!=null, tagValue<=((TagEvent)map.get($tagEvent.getTagName())).getMinThreshold())
then
System.out.println("Out Of Range Check -LOW");
modify( $tagEvent ) { setStatus( Status.OUT_OF_RANGE_LOW ) };
end;
rule "Out Of Range Check - HIGH"
dialect "java"
when
$tagEvent : TagEvent( status==Status.WITHIN_RANGE, tagValue != null, map.get($tagEvent.getTagName())!=null, tagValue >= ((TagEvent)map.get($tagEvent.getTagName())).getMaxThreshold() )
then
System.out.println("Out Of Range Check - HIGH");
modify( $tagEvent ) { setStatus( Status.OUT_OF_RANGE_HIGH ) };
end;
rule "Trigger Threshold Alert"
dialect "java"
when
$tagEvent : TagEvent( status!=null, status!=Status.WITHIN_RANGE )
then
FileWriter.writer("Out Of Range Check : "+$tagEvent);
end;
rule "Count Values"
dialect "java"
when
accumulate ( TagEvent( tagName.equals("GSA_SI11151"), status!=Status.WITHIN_RANGE )
then
FileWriter.writer("Counter Threshold Reached : " + $cnt ) ;
end
Thanks
I have one problem with the open source estatio (that is built based on apache isis)
I've export data base schema first in DDL file. After that I have imported the DDL file in PostgresSQL 9.5. The application can be started. And some of fixture can be executed. The problem I have in "Estatio Demo Fixture". The application seems to import few fixtures until the application try to import org.estatio.fixture.financial.BankAccountForAcmeNl.
Following exception occurs:
Stack trace:
org.apache.wicket.WicketRuntimeException
Method onRequest of interface org.apache.wicket.behavior.IBehaviorListener targeted at org.apache.wicket.ajax.markup.html.form.AjaxButton$1#4c421e92 on component [IndicatingAjaxButton [Component id = okButton]] threw an exception
org.apache.wicket.RequestListenerInterface#internalInvoke(RequestListenerInterface.java:268)
org.apache.wicket.RequestListenerInterface#invoke(RequestListenerInterface.java:241)
org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#invokeListener(ListenerInterfaceRequestHandler.java:248)
org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#respond(ListenerInterfaceRequestHandler.java:234)
org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor#respond(RequestCycle.java:895)
org.apache.wicket.request.RequestHandlerStack#execute(RequestHandlerStack.java:64)
org.apache.wicket.request.cycle.RequestCycle#execute(RequestCycle.java:265)
org.apache.wicket.request.cycle.RequestCycle#processRequest(RequestCycle.java:222)
org.apache.wicket.request.cycle.RequestCycle#processRequestAndDetach(RequestCycle.java:293)
org.apache.wicket.protocol.http.WicketFilter#processRequestCycle(WicketFilter.java:261)
org.apache.wicket.protocol.http.WicketFilter#processRequest(WicketFilter.java:203)
org.apache.wicket.protocol.http.WicketFilter#doFilter(WicketFilter.java:284)
org.apache.catalina.core.ApplicationFilterChain#internalDoFilter(ApplicationFilterChain.java:192)
org.apache.catalina.core.ApplicationFilterChain#doFilter(ApplicationFilterChain.java:165)
org.togglz.servlet.TogglzFilter#doFilter(TogglzFilter.java:100)
org.apache.catalina.core.ApplicationFilterChain#internalDoFilter(ApplicationFilterChain.java:192)
org.apache.catalina.core.ApplicationFilterChain#doFilter(ApplicationFilterChain.java:165)
org.apache.shiro.web.servlet.AbstractShiroFilter#executeChain(AbstractShiroFilter.java:449)
org.apache.shiro.web.servlet.AbstractShiroFilter$1#call(AbstractShiroFilter.java:365)
org.apache.shiro.subject.support.SubjectCallable#doCall(SubjectCallable.java:90)
org.apache.shiro.subject.support.SubjectCallable#call(SubjectCallable.java:83)
org.apache.shiro.subject.support.DelegatingSubject#execute(DelegatingSubject.java:383)
org.apache.shiro.web.servlet.AbstractShiroFilter#doFilterInternal(AbstractShiroFilter.java:362)
org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter(OncePerRequestFilter.java:125)
org.apache.catalina.core.ApplicationFilterChain#internalDoFilter(ApplicationFilterChain.java:192)
org.apache.catalina.core.ApplicationFilterChain#doFilter(ApplicationFilterChain.java:165)
org.apache.catalina.core.StandardWrapperValve#invoke(StandardWrapperValve.java:198)
org.apache.catalina.core.StandardContextValve#invoke(StandardContextValve.java:96)
org.apache.catalina.authenticator.AuthenticatorBase#invoke(AuthenticatorBase.java:474)
org.apache.catalina.core.StandardHostValve#invoke(StandardHostValve.java:140)
org.apache.catalina.valves.ErrorReportValve#invoke(ErrorReportValve.java:79)
org.apache.catalina.valves.AbstractAccessLogValve#invoke(AbstractAccessLogValve.java:624)
org.apache.catalina.core.StandardEngineValve#invoke(StandardEngineValve.java:87)
org.apache.catalina.connector.CoyoteAdapter#service(CoyoteAdapter.java:349)
org.apache.coyote.http11.Http11Processor#service(Http11Processor.java:783)
org.apache.coyote.AbstractProcessorLight#process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler#process(AbstractProtocol.java:798)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor#doRun(NioEndpoint.java:1434)
org.apache.tomcat.util.net.SocketProcessorBase#run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor#runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker#run(ThreadPoolExecutor.java:617)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable#run(TaskThread.java:61)
java.lang.Thread#run(Thread.java:745)
Caused by:
java.lang.reflect.InvocationTargetException
sun.reflect.NativeMethodAccessorImpl#invoke0(NativeMethodAccessorImpl.java:-2)
sun.reflect.NativeMethodAccessorImpl#invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method#invoke(Method.java:498)
org.apache.wicket.RequestListenerInterface#internalInvoke(RequestListenerInterface.java:258)
org.apache.wicket.RequestListenerInterface#invoke(RequestListenerInterface.java:241)
org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#invokeListener(ListenerInterfaceRequestHandler.java:248)
org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#respond(ListenerInterfaceRequestHandler.java:234)
org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor#respond(RequestCycle.java:895)
org.apache.wicket.request.RequestHandlerStack#execute(RequestHandlerStack.java:64)
org.apache.wicket.request.cycle.RequestCycle#execute(RequestCycle.java:265)
org.apache.wicket.request.cycle.RequestCycle#processRequest(RequestCycle.java:222)
org.apache.wicket.request.cycle.RequestCycle#processRequestAndDetach(RequestCycle.java:293)
org.apache.wicket.protocol.http.WicketFilter#processRequestCycle(WicketFilter.java:261)
org.apache.wicket.protocol.http.WicketFilter#processRequest(WicketFilter.java:203)
org.apache.wicket.protocol.http.WicketFilter#doFilter(WicketFilter.java:284)
org.apache.catalina.core.ApplicationFilterChain#internalDoFilter(ApplicationFilterChain.java:192)
org.apache.catalina.core.ApplicationFilterChain#doFilter(ApplicationFilterChain.java:165)
org.togglz.servlet.TogglzFilter#doFilter(TogglzFilter.java:100)
org.apache.catalina.core.ApplicationFilterChain#internalDoFilter(ApplicationFilterChain.java:192)
org.apache.catalina.core.ApplicationFilterChain#doFilter(ApplicationFilterChain.java:165)
org.apache.shiro.web.servlet.AbstractShiroFilter#executeChain(AbstractShiroFilter.java:449)
org.apache.shiro.web.servlet.AbstractShiroFilter$1#call(AbstractShiroFilter.java:365)
org.apache.shiro.subject.support.SubjectCallable#doCall(SubjectCallable.java:90)
org.apache.shiro.subject.support.SubjectCallable#call(SubjectCallable.java:83)
org.apache.shiro.subject.support.DelegatingSubject#execute(DelegatingSubject.java:383)
org.apache.shiro.web.servlet.AbstractShiroFilter#doFilterInternal(AbstractShiroFilter.java:362)
org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter(OncePerRequestFilter.java:125)
org.apache.catalina.core.ApplicationFilterChain#internalDoFilter(ApplicationFilterChain.java:192)
org.apache.catalina.core.ApplicationFilterChain#doFilter(ApplicationFilterChain.java:165)
org.apache.catalina.core.StandardWrapperValve#invoke(StandardWrapperValve.java:198)
org.apache.catalina.core.StandardContextValve#invoke(StandardContextValve.java:96)
org.apache.catalina.authenticator.AuthenticatorBase#invoke(AuthenticatorBase.java:474)
org.apache.catalina.core.StandardHostValve#invoke(StandardHostValve.java:140)
org.apache.catalina.valves.ErrorReportValve#invoke(ErrorReportValve.java:79)
org.apache.catalina.valves.AbstractAccessLogValve#invoke(AbstractAccessLogValve.java:624)
org.apache.catalina.core.StandardEngineValve#invoke(StandardEngineValve.java:87)
org.apache.catalina.connector.CoyoteAdapter#service(CoyoteAdapter.java:349)
org.apache.coyote.http11.Http11Processor#service(Http11Processor.java:783)
org.apache.coyote.AbstractProcessorLight#process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler#process(AbstractProtocol.java:798)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor#doRun(NioEndpoint.java:1434)
org.apache.tomcat.util.net.SocketProcessorBase#run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor#runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker#run(ThreadPoolExecutor.java:617)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable#run(TaskThread.java:61)
java.lang.Thread#run(Thread.java:745)
Caused by:
java.lang.NumberFormatException
For input string: "nextvalIncodeCommunications.CommunicationChannel_id_seq::regclass"
java.lang.NumberFormatException#forInputString(NumberFormatException.java:65)
java.lang.Long#parseLong(Long.java:589)
java.lang.Long#valueOf(Long.java:803)
org.datanucleus.store.rdbms.mapping.datastore.BigIntRDBMSMapping#setObject(BigIntRDBMSMapping.java:187)
org.datanucleus.store.rdbms.mapping.java.DatastoreIdMapping#setObject(DatastoreIdMapping.java:53)
org.datanucleus.store.rdbms.mapping.java.PersistableMapping#setObjectAsNull(PersistableMapping.java:346)
org.datanucleus.store.rdbms.mapping.java.PersistableMapping#setObject(PersistableMapping.java:317)
org.datanucleus.store.rdbms.mapping.java.PersistableMapping#setObject(PersistableMapping.java:300)
org.datanucleus.store.rdbms.sql.SQLStatementHelper#applyParametersToStatement(SQLStatementHelper.java:228)
org.datanucleus.store.rdbms.query.JDOQLQuery#performExecute(JDOQLQuery.java:609)
org.datanucleus.store.query.Query#executeQuery(Query.java:1855)
org.datanucleus.store.query.Query#executeWithMap(Query.java:1762)
org.datanucleus.api.jdo.JDOQuery#executeWithMap(JDOQuery.java:346)
org.apache.isis.objectstore.jdo.datanucleus.persistence.queries.PersistenceQueryFindUsingApplibQueryProcessor#getResults(PersistenceQueryFindUsingApplibQueryProcessor.java:117)
org.apache.isis.objectstore.jdo.datanucleus.persistence.queries.PersistenceQueryFindUsingApplibQueryProcessor#process(PersistenceQueryFindUsingApplibQueryProcessor.java:57)
org.apache.isis.objectstore.jdo.datanucleus.persistence.queries.PersistenceQueryFindUsingApplibQueryProcessor#process(PersistenceQueryFindUsingApplibQueryProcessor.java:41)
org.apache.isis.core.runtime.system.persistence.PersistenceSession#processPersistenceQuery(PersistenceSession.java:606)
org.apache.isis.core.runtime.system.persistence.PersistenceSession#access$000(PersistenceSession.java:147)
org.apache.isis.core.runtime.system.persistence.PersistenceSession$1#execute(PersistenceSession.java:567)
org.apache.isis.core.runtime.system.persistence.PersistenceSession$1#execute(PersistenceSession.java:564)
org.apache.isis.core.runtime.system.transaction.IsisTransactionManager#executeWithinTransaction(IsisTransactionManager.java:188)
org.apache.isis.core.runtime.system.transaction.IsisTransactionManager#executeWithinTransaction(IsisTransactionManager.java:178)
org.apache.isis.core.runtime.system.persistence.PersistenceSession#findInstancesInTransaction(PersistenceSession.java:563)
org.apache.isis.core.runtime.system.persistence.PersistenceSession#firstMatchingQuery(PersistenceSession.java:535)
org.apache.isis.core.runtime.services.persistsession.PersistenceSessionServiceInternalDefault#firstMatchingQuery(PersistenceSessionServiceInternalDefault.java:176)
org.apache.isis.core.metamodel.services.container.DomainObjectContainerDefault#firstMatch(DomainObjectContainerDefault.java:534)
org.incode.module.communications.dom.impl.commchannel.CommunicationChannelOwnerLinkRepository#findByCommunicationChannel(CommunicationChannelOwnerLinkRepository.java:65)
org.incode.module.communications.dom.impl.commchannel.CommunicationChannel#getOwnerLink(CommunicationChannel.java:253)
org.incode.module.communications.dom.impl.commchannel.CommunicationChannel#removeOwnerLink(CommunicationChannel.java:246)
org.incode.module.communications.dom.impl.commchannel.CommunicationChannel#setOwner(CommunicationChannel.java:241)
org.incode.module.communications.dom.impl.commchannel.CommunicationChannelRepository#newPostal(CommunicationChannelRepository.java:73)
org.estatio.fixture.party.OrganisationAbstract#createCommunicationChannels(OrganisationAbstract.java:90)
org.estatio.fixture.party.OrganisationAbstract#createOrganisation(OrganisationAbstract.java:69)
org.estatio.fixture.party.OrganisationForAcmeNl#execute(OrganisationForAcmeNl.java:30)
org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildIfNotAlready(FixtureScript.java:598)
org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildT(FixtureScript.java:576)
org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildT(FixtureScript.java:544)
org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChild(FixtureScript.java:532)
org.estatio.fixture.financial.BankAccountForAcmeNl#execute(BankAccountForAcmeNl.java:42)
org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildIfNotAlready(FixtureScript.java:598)
org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildT(FixtureScript.java:576)
org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildT(FixtureScript.java:544)
org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChild(FixtureScript.java:532)
org.estatio.fixturescripts.EstatioDemoFixture#execute(EstatioDemoFixture.java:72)
org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#executeChildIfNotAlready(FixtureScript.java:598)
org.apache.isis.applib.fixturescripts.FixtureScript$ExecutionContext#access$200(FixtureScript.java:253)
org.apache.isis.applib.fixturescripts.FixtureScript#run(FixtureScript.java:828)
org.apache.isis.applib.fixturescripts.FixtureScripts#runFixtureScript(FixtureScripts.java:391)
org.apache.isis.applib.services.fixturespec.FixtureScriptsDefault#runFixtureScript(FixtureScriptsDefault.java:108)
sun.reflect.NativeMethodAccessorImpl#invoke0(NativeMethodAccessorImpl.java:-2)
sun.reflect.NativeMethodAccessorImpl#invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method#invoke(Method.java:498)
org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract#invokeMethodElseFromCache(ActionInvocationFacetForDomainEventAbstract.java:407)
org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract$2#execute(ActionInvocationFacetForDomainEventAbstract.java:261)
org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract$2#execute(ActionInvocationFacetForDomainEventAbstract.java:222)
org.apache.isis.applib.services.iactn.Interaction#executeInternal(Interaction.java:173)
org.apache.isis.applib.services.iactn.Interaction#execute(Interaction.java:143)
org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract#doInvoke(ActionInvocationFacetForDomainEventAbstract.java:310)
org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract$1#execute(ActionInvocationFacetForDomainEventAbstract.java:164)
org.apache.isis.core.runtime.system.transaction.IsisTransactionManager#executeWithinTransaction(IsisTransactionManager.java:142)
org.apache.isis.core.runtime.system.transaction.IsisTransactionManager#executeWithinTransaction(IsisTransactionManager.java:132)
org.apache.isis.core.runtime.services.persistsession.PersistenceSessionServiceInternalDefault#executeWithinTransaction(PersistenceSessionServiceInternalDefault.java:181)
org.apache.isis.core.metamodel.facets.actions.action.invocation.ActionInvocationFacetForDomainEventAbstract#invoke(ActionInvocationFacetForDomainEventAbstract.java:160)
org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionDefault#executeInternal(ObjectActionDefault.java:400)
org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionDefault#execute(ObjectActionDefault.java:389)
org.apache.isis.core.metamodel.specloader.specimpl.ObjectActionDefault#executeWithRuleChecking(ObjectActionDefault.java:370)
org.apache.isis.viewer.wicket.model.models.ActionModel#executeAction(ActionModel.java:491)
org.apache.isis.viewer.wicket.model.models.ActionModel#load(ActionModel.java:469)
org.apache.isis.viewer.wicket.model.models.ActionModel#load(ActionModel.java:81)
org.apache.wicket.model.LoadableDetachableModel#getObject(LoadableDetachableModel.java:135)
org.apache.isis.viewer.wicket.model.models.ActionModel#execute(ActionModel.java:597)
org.apache.isis.viewer.wicket.ui.components.actions.ActionFormExecutorStrategy#obtainResultAdapter(ActionFormExecutorStrategy.java:72)
org.apache.isis.viewer.wicket.ui.panels.FormExecutorDefault#obtainResultAdapter(FormExecutorDefault.java:498)
org.apache.isis.viewer.wicket.ui.panels.FormExecutorDefault#executeAndProcessResults(FormExecutorDefault.java:129)
org.apache.isis.viewer.wicket.ui.panels.PromptFormAbstract#onOkSubmittedOf(PromptFormAbstract.java:228)
org.apache.isis.viewer.wicket.ui.panels.PromptFormAbstract#access$000(PromptFormAbstract.java:60)
org.apache.isis.viewer.wicket.ui.panels.PromptFormAbstract$1#onSubmit(PromptFormAbstract.java:122)
org.apache.wicket.ajax.markup.html.form.AjaxButton$1#onSubmit(AjaxButton.java:113)
org.apache.wicket.ajax.form.AjaxFormSubmitBehavior$AjaxFormSubmitter#onSubmit(AjaxFormSubmitBehavior.java:215)
org.apache.wicket.markup.html.form.Form#delegateSubmit(Form.java:1307)
org.apache.wicket.markup.html.form.Form#process(Form.java:976)
org.apache.isis.viewer.wicket.ui.panels.FormAbstract#process(FormAbstract.java:77)
org.apache.wicket.markup.html.form.Form#onFormSubmitted(Form.java:797)
org.apache.wicket.ajax.form.AjaxFormSubmitBehavior#onEvent(AjaxFormSubmitBehavior.java:171)
org.apache.wicket.ajax.AjaxEventBehavior#respond(AjaxEventBehavior.java:155)
org.apache.wicket.ajax.AbstractDefaultAjaxBehavior#onRequest(AbstractDefaultAjaxBehavior.java:601)
sun.reflect.NativeMethodAccessorImpl#invoke0(NativeMethodAccessorImpl.java:-2)
sun.reflect.NativeMethodAccessorImpl#invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl#invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method#invoke(Method.java:498)
org.apache.wicket.RequestListenerInterface#internalInvoke(RequestListenerInterface.java:258)
org.apache.wicket.RequestListenerInterface#invoke(RequestListenerInterface.java:241)
org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#invokeListener(ListenerInterfaceRequestHandler.java:248)
org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler#respond(ListenerInterfaceRequestHandler.java:234)
org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor#respond(RequestCycle.java:895)
org.apache.wicket.request.RequestHandlerStack#execute(RequestHandlerStack.java:64)
org.apache.wicket.request.cycle.RequestCycle#execute(RequestCycle.java:265)
org.apache.wicket.request.cycle.RequestCycle#processRequest(RequestCycle.java:222)
org.apache.wicket.request.cycle.RequestCycle#processRequestAndDetach(RequestCycle.java:293)
org.apache.wicket.protocol.http.WicketFilter#processRequestCycle(WicketFilter.java:261)
org.apache.wicket.protocol.http.WicketFilter#processRequest(WicketFilter.java:203)
org.apache.wicket.protocol.http.WicketFilter#doFilter(WicketFilter.java:284)
org.apache.catalina.core.ApplicationFilterChain#internalDoFilter(ApplicationFilterChain.java:192)
org.apache.catalina.core.ApplicationFilterChain#doFilter(ApplicationFilterChain.java:165)
org.togglz.servlet.TogglzFilter#doFilter(TogglzFilter.java:100)
org.apache.catalina.core.ApplicationFilterChain#internalDoFilter(ApplicationFilterChain.java:192)
org.apache.catalina.core.ApplicationFilterChain#doFilter(ApplicationFilterChain.java:165)
org.apache.shiro.web.servlet.AbstractShiroFilter#executeChain(AbstractShiroFilter.java:449)
org.apache.shiro.web.servlet.AbstractShiroFilter$1#call(AbstractShiroFilter.java:365)
org.apache.shiro.subject.support.SubjectCallable#doCall(SubjectCallable.java:90)
org.apache.shiro.subject.support.SubjectCallable#call(SubjectCallable.java:83)
org.apache.shiro.subject.support.DelegatingSubject#execute(DelegatingSubject.java:383)
org.apache.shiro.web.servlet.AbstractShiroFilter#doFilterInternal(AbstractShiroFilter.java:362)
org.apache.shiro.web.servlet.OncePerRequestFilter#doFilter(OncePerRequestFilter.java:125)
org.apache.catalina.core.ApplicationFilterChain#internalDoFilter(ApplicationFilterChain.java:192)
org.apache.catalina.core.ApplicationFilterChain#doFilter(ApplicationFilterChain.java:165)
org.apache.catalina.core.StandardWrapperValve#invoke(StandardWrapperValve.java:198)
org.apache.catalina.core.StandardContextValve#invoke(StandardContextValve.java:96)
org.apache.catalina.authenticator.AuthenticatorBase#invoke(AuthenticatorBase.java:474)
org.apache.catalina.core.StandardHostValve#invoke(StandardHostValve.java:140)
org.apache.catalina.valves.ErrorReportValve#invoke(ErrorReportValve.java:79)
org.apache.catalina.valves.AbstractAccessLogValve#invoke(AbstractAccessLogValve.java:624)
org.apache.catalina.core.StandardEngineValve#invoke(StandardEngineValve.java:87)
org.apache.catalina.connector.CoyoteAdapter#service(CoyoteAdapter.java:349)
org.apache.coyote.http11.Http11Processor#service(Http11Processor.java:783)
org.apache.coyote.AbstractProcessorLight#process(AbstractProcessorLight.java:66)
org.apache.coyote.AbstractProtocol$ConnectionHandler#process(AbstractProtocol.java:798)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor#doRun(NioEndpoint.java:1434)
org.apache.tomcat.util.net.SocketProcessorBase#run(SocketProcessorBase.java:49)
java.util.concurrent.ThreadPoolExecutor#runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker#run(ThreadPoolExecutor.java:617)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable#run(TaskThread.java:61)
java.lang.Thread#run(Thread.java:745)
The id of CommunicationChanel is described like following in DB: "id int4 NOT NULL DEFAULT nextval('"IncodeCommunications"."CommunicationChannel_id_seq"'::regclass)"
The Id of this table is automatically created for each insert statement. In this case that is not an insert statement but a find statement without reference Id. I mean it looks up in CommunicationChanelOwnerLink, if there is any row with id is blank.
public void setObject(PreparedStatement ps, int param, Object value)
{
try
{
if (value == null)
{
if (column != null && column.isDefaultable() && column.getDefaultValue() != null && !StringUtils.isWhitespace(column.getDefaultValue().toString()))
{
ps.setLong(param, Long.valueOf(column.getDefaultValue().toString().trim()).longValue());
}
else
this block code of BigIntRDBMSMapping says that, if the value is null (that is exactly in this case) then it will try to parse default value that was initialized by datanucleus before. In this case, default value = "nextvalIncodeCommunications.CommunicationChannel_id_seq::regclass". This value can not be convert to Long value.
Any idea what is exactly happen here?
Thanks.
use case: see my comment Apache Isis: Java Type mapping failed
root cause: see my comment Apache Isis: Java Type mapping failed
solution: no official solution exists. I've talked with Andy Jefferson from datanucleus team. But no useful answer. At the end I've patched the library by my self and wait for appropriate fix
I'm trying to use "forced types" for BOOLEANs when generating classes for our Oracle database with jOOQ 3.7.
The table looks like this:
CREATE TABLE outable_name
(
id INTEGER NOT NULL,
-- ...
some_boolean_field INTEGER DEFAULT 0 NOT NULL
);
To generate the Java classes Gradleis used. The relevant part looks like this:
database() {
name('org.jooq.util.oracle.OracleDatabase')
inputSchema(properties.getProperty('db.user'))
includes('.*')
forcedTypes() {
forcedType() {
name('BOOLEAN')
expression('some_boolean_field')
types('.*')
}
}
}
When running the gradle-task with info-output the following error is thrown:
Error while generating table record ***.*** (obfuscated)
java.lang.NullPointerException
at java.util.regex.Matcher.getTextLength(Matcher.java:1283)
at java.util.regex.Matcher.reset(Matcher.java:309)
at java.util.regex.Matcher.<init>(Matcher.java:229)
at java.util.regex.Pattern.matcher(Pattern.java:1093)
at org.jooq.util.AbstractTypedElementDefinition.mapDefinedType(AbstractTypedElementDefinition.java:174)
at org.jooq.util.AbstractTypedElementDefinition.getType(AbstractTypedElementDefinition.java:114)
at org.jooq.util.DefaultColumnDefinition.getType(DefaultColumnDefinition.java:51)
at org.jooq.util.JavaGenerator.refRowType(JavaGenerator.java:1241)
at org.jooq.util.JavaGenerator.generateRecord(JavaGenerator.java:838)
at org.jooq.util.JavaGenerator.generateRecord(JavaGenerator.java:797)
at org.jooq.util.JavaGenerator.generateRecord(JavaGenerator.java:785)
at org.jooq.util.JavaGenerator.generateRecords(JavaGenerator.java:772)
at org.jooq.util.JavaGenerator.generate(JavaGenerator.java:327)
at org.jooq.util.JavaGenerator.generate(JavaGenerator.java:267)
at org.jooq.util.GenerationTool.run(GenerationTool.java:434)
at org.jooq.util.GenerationTool.generate(GenerationTool.java:180)
at org.jooq.util.GenerationTool$generate.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at ...
Call "name" directly with invokeMethod:
database() {
name('org.jooq.util.oracle.OracleDatabase')
inputSchema(properties.getProperty('db.user'))
includes('.*')
forcedTypes() {
forcedType() {
delegate.invokeMethod('name', [
'BOOLEAN'
]
)
expression('.*\\.is_.*|.*\\.has_.*')
types('CHAR\\(1\\)')
}
}
}
Explanation in Groovy MarkupBuilder name conflict
assume part of my code is like as:-
where doc is List[Document] that contains stu_name and roll_number
sometimes stu_name and roll_name may be null.
I used Try to avoid null Pointer exception in first two lines.
but why I m getting again Null Pointer exception in "val myRow".
val name= Try {Option.apply(doc.getFieldValue("stu_name"))}.getOrElse(null)
val rollNumber ={Option.apply(doc.getFieldValue("roll_number"))}.getOrElse(null)
val myRow = (
doc.getFieldValue("ID").asInstanceOf[Int] //can't be null
name.getOrElse(null).toString, //NullPointerException
rollNumber.getOrElse(null).asInstanceOf[Int] //NullPointerException
)
.....
.....
I m getting following error:
[2016-01-14 22:40:16,896] WARN o.a.s.s.TaskSetManager [] [akka://JobServer/user/context-supervisor/demeter] - Lost task 0.0 in stage 0.0 (TID 0, 10.29.23.136): java.lang.NullPointerException
at com.test.events.Monitoring$$anonfun$geteventTableReplicateDayFunc$1.apply(Monitoring.scala:75)
at com.test.events.Monitoring$$anonfun$geteventTableReplicateDayFunc$1.apply(Monitoring.scala:57)
at com.test.events.Monitoring$$anonfun$27.apply(Monitoring.scala:104)
at com.test.events.Monitoring$$anonfun$27.apply(Monitoring.scala:104)
I tried in console following but did not see any error:
scala> val a = Try (Option.apply("atar")).getOrElse(null)
a: Option[String] = Some(atar)
scala> a.getOrElse(null)
res16: String = atar
scala> val a = Try (Option.apply(null)).getOrElse(null)
a: Option[Null] = None
scala> a.getOrElse(null)
res17: Null = null
This is all wrong. By using getOrElse(null) you are basically removing all advantages to using an Option to begin with. Plus, generating much more complexity than needed.
You need to define what you will do if the values are null. This just keeps them as Options (None on null input):
val myRow = (
doc.getFieldValue("ID").toInt, // Fails if null
Option(doc.getFieldValue("stu_name")), // `None` if null
Option(doc.getFieldValue("roll_number")).map(_.toInt) // `None` if null
)
Or use default values:
val myRow = (
doc.getFieldValue("ID").toInt,
Option(doc.getFieldValue("stu_name")).getOrElse("default"),
Option(doc.getFieldValue("roll_number")).map(_.toInt).getOrElse(0)
)
In envers (persistence.xml), I enabled the strategy for table partitioning, according to the development guide: http://docs.jboss.org/hibernate/orm/4.2/devguide/en-US/html/ch15.html#envers-partitioning
The class: ValidityAuditStrategy, throws RuntimeException when there is no audit record. This exception occurs when the Envers try to update an audit record with a date of final revision (revend_tstmp), but this audit record does not exist.
The database of my application receives data load from external applications and is not possible change these external applications to include their audit records.
I have no chance to handle this exception (I don't know how).
In method ValidityAuditStrategy#updateLastRevision:
if (l.size() == 1) {
//... doStuff - OK
} else {
throw new RuntimeException("Cannot find previous revision for entity " + auditedEntityName + " and id " + id);
}
In method ValidityAuditStrategy#perform:
if ( rowCount != 1 )
throw new RuntimeException("Cannot update previous revision for entity " + auditedEntityName + " and id " + id);
A similar issue occurred in this link: https://developer.jboss.org/thread/160195?tstart=0 but had no solution.
It's possible apply a workaround?
I use hibernate-envers-4.1.3-Final version.
Log:
2015-07-17 10:23:28,653 DEBUG [-] [org.hibernate.SQL] (http-/0.0.0.0:8080-5) update MY_ENTITY_AUD set ID_REV_FINAL=?, DATE_HOUR_REV_FINAL=? where ID_ENTITY=? and ID_REV <> ? and ID_REV_FINAL is null
2015-07-17 10:23:28,677 TRACE [-] [org.hibernate.type.descriptor.sql.BasicBinder] (http-/0.0.0.0:8080-5) binding parameter [1] as [INTEGER] - 422
2015-07-17 10:23:28,677 TRACE [-] [org.hibernate.type.descriptor.sql.BasicBinder] (http-/0.0.0.0:8080-5) binding parameter [2] as [TIMESTAMP] - Thu Jul 17 10:23:28 BRT 2015
2015-07-17 10:23:28,677 TRACE [-] [org.hibernate.type.descriptor.sql.BasicBinder] (http-/0.0.0.0:8080-5) binding parameter [3] as [INTEGER] - 12345
2015-07-17 10:23:28,678 TRACE [-] [org.hibernate.type.descriptor.sql.BasicBinder] (http-/0.0.0.0:8080-5) binding parameter [4] as [INTEGER] - 422
2015-07-17 10:23:28,803 ERROR [-] [org.hibernate.AssertionFailure] (http-/0.0.0.0:8080-5) HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): java.lang.RuntimeException: Cannot update previous revision for entity my.package.MyEntity_AUD and id 12345
2015-07-17 10:23:28,841 WARN [-] [com.arjuna.ats.arjuna] (http-/0.0.0.0:8080-5) ARJUNA012125: TwoPhaseCoordinator.beforeCompletion - failed for SynchronizationImple< 0:ffffac1c045d:-3a5600e4:55a7c120:131, org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization#5619c5a3 >: org.hibernate.AssertionFailure: Unable to perform beforeTransactionCompletion callback
at org.hibernate.engine.spi.ActionQueue$BeforeTransactionCompletionProcessQueue.beforeTransactionCompletion(ActionQueue.java:754) [hibernate-core-4.1.3-Final.jar:4.1.3-Final]
at org.hibernate.engine.spi.ActionQueue.beforeTransactionCompletion(ActionQueue.java:338) [hibernate-core-4.1.3-Final.jar:4.1.3-Final]
at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:490) [hibernate-core-4.1.3-Final.jar:4.1.3-Final]
at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorNonTrackingImpl.beforeCompletion(SynchronizationCallbackCoordinatorNonTrackingImpl.java:114) [hibernate-core-4.1.3-Final.jar:4.1.3-Final]
at org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:53) [hibernate-core-4.1.3-Final.jar:4.1.3-Final]
at com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.beforeCompletion(SynchronizationImple.java:76)
at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.beforeCompletion(TwoPhaseCoordinator.java:273)
at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:93)
at com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:162)
at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1189)
at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:126)
at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:75)
at org.jboss.as.ejb3.tx.CMTTxInterceptor.endTransaction(CMTTxInterceptor.java:92) [jboss-as-ejb3-7.4.0.Final-redhat-19.jar:7.4.0.Final-redhat-19]
...
Caused by: java.lang.RuntimeException: Cannot update previous revision for entity entity my.package.MyEntity_AUD and id 12345
at org.hibernate.envers.strategy.ValidityAuditStrategy.perform(ValidityAuditStrategy.java:210) [hibernate-core-4.1.3-Final.jar:4.1.3-Final]
at org.hibernate.envers.synchronization.work.AbstractAuditWorkUnit.perform(AbstractAuditWorkUnit.java:76) [hibernate-core-4.1.3-Final.jar:4.1.3-Final]
at org.hibernate.envers.synchronization.AuditProcess.executeInSession(AuditProcess.java:116) [hibernate-core-4.1.3-Final.jar:4.1.3-Final]
at org.hibernate.envers.synchronization.AuditProcess.doBeforeTransactionCompletion(AuditProcess.java:155) [hibernate-core-4.1.3-Final.jar:4.1.3-Final]
at org.hibernate.envers.synchronization.AuditProcessManager$1.doBeforeTransactionCompletion(AuditProcessManager.java:62) [hibernate-core-4.1.3-Final.jar:4.1.3-Final]
at org.hibernate.engine.spi.ActionQueue$BeforeTransactionCompletionProcessQueue.beforeTransactionCompletion(ActionQueue.java:748) [hibernate-core-4.1.3-Final.jar:4.1.3-Final]
... 90 more
In persistence.xml existing a property to specify a custom AuditStrategey: org.hibernate.envers.audit_strategy.
Change,
From:
<property name="org.hibernate.envers.audit_strategy" value="org.hibernate.envers.strategy.ValidityAuditStrategy"/>
To:
<property name="org.hibernate.envers.audit_strategy" value="com.app.your.pack.YourCustomValidityAuditStrategy"/>
So now you can extend ValidityAuditStrategy and override perform() to not throw a RuntimeException when there is no previous revision for the entity, like this:
public class YourCustomValidityAuditStrategy extends ValidityAuditStrategy {
private final Log logger = LogFactory.getLog(getClass());
#Override
public void perform(Session session, String entityName, AuditConfiguration auditCfg, Serializable id, Object data, Object revision) {
try {
super.perform(session, entityName, auditCfg, id, data, revision);
} catch (RuntimeException re) {
if (logger.isDebugEnabled()) {
logger.debug("IGNORE RuntimeException: Cannot update previous revision for entity.", re);
}
}
}
Overriding just the perform method and catching the RuntimeException won't help you as the code throwing the RuntimeException is enclosed in an anonymous class of type BeforeTransactionCompletionProcess and is executed later.
The ValidityAuditStrategy is not very flexible so the only solution i see is ugly but should work : you must copy the entire ValidityAuditStrategy code in a custom class and catch the RuntimeException in the BeforeTransactionCompletionProcess anonymous class. Then specify your custom class in the persistence.xml :
<property name="org.hibernate.envers.audit_strategy "value="com.app.xxx.CustomValidityAuditStrategy"/>
The perform() method should look like the following :
#Override
public void perform(
final Session session,
final String entityName,
final EnversService enversService,
final Serializable id,
final Object data,
final Object revision) {
final AuditEntitiesConfiguration audEntitiesCfg = enversService.getAuditEntitiesConfiguration();
final String auditedEntityName = audEntitiesCfg.getAuditEntityName( entityName );
final String revisionInfoEntityName = enversService.getAuditEntitiesConfiguration().getRevisionInfoEntityName();
// Save the audit data
session.save( auditedEntityName, data );
// Update the end date of the previous row.
//
// When application reuses identifiers of previously removed entities:
// The UPDATE statement will no-op if an entity with a given identifier has been
// inserted for the first time. But in case a deleted primary key value was
// reused, this guarantees correct strategy behavior: exactly one row with
// null end date exists for each identifier.
final boolean reuseEntityIdentifier = enversService.getGlobalConfiguration().isAllowIdentifierReuse();
if ( reuseEntityIdentifier || getRevisionType( enversService, data ) != RevisionType.ADD ) {
// Register transaction completion process to guarantee execution of UPDATE statement after INSERT.
( (EventSource) session ).getActionQueue().registerProcess( new BeforeTransactionCompletionProcess() {
#Override
public void doBeforeTransactionCompletion(final SessionImplementor sessionImplementor) {
final Queryable productionEntityQueryable = getQueryable( entityName, sessionImplementor );
final Queryable rootProductionEntityQueryable = getQueryable(
productionEntityQueryable.getRootEntityName(), sessionImplementor
);
final Queryable auditedEntityQueryable = getQueryable( auditedEntityName, sessionImplementor );
final Queryable rootAuditedEntityQueryable = getQueryable(
auditedEntityQueryable.getRootEntityName(), sessionImplementor
);
final String updateTableName;
/*commented code*/
...
/*comment the following piece of code*/
/*if ( rowCount != 1 && ( !reuseEntityIdentifier || ( getRevisionType( enversService, data ) != RevisionType.ADD ) ) ) {
throw new RuntimeException(
"Cannot update previous revision for entity " + auditedEntityName + " and id " + id
);
}*/
}
});
}
sessionCacheCleaner.scheduleAuditDataRemoval( session, data );
}
As i said its ugly...
Setting org.hibernate.envers.allow_identifier_reuse: true helped in my scenario.
Not exactly answers the original question, but on the outside looks the same: Cannot update previous revision for entity my.package.MyEntity_AUD and id caa4ce8e.
I am using hibernate-envers-5.4.1 and for whatever reason (probably some buggy import in the past) suddenly faced the same error.
Direct query to the database select * from myentity_aud where id='caa4ce8e' resulted in:
rev revend revtype id ...
2121736 NULL 0 caa4ce8e ...
2121737 NULL 1 caa4ce8e ...
2121738 NULL 1 caa4ce8e ...
-- as seen, revend is NULL for all records.
The issue is: envers expects only one (the latest) to be NULL, all the rest must have the "overriding" rev to be set as revend.
So, to fix this particular case, it was enough to update to:
rev revend revtype id ...
2121736 2121737 0 caa4ce8e ...
2121737 2121738 1 caa4ce8e ...
2121738 NULL 1 caa4ce8e ...
and after that everything worked like a charm.
However, if you have millions of such records, you may want to write some script which will take care of them automatically.