Hibernate Error when persist the outer ProcessInstance.
kenees Apr 8, 2009 11:03 PMHi guys
I'm using JBPM 3.3.0.GA, I have a use case that want to create a new ProcessInstance (name as A) inside an actionHandler of an outer one, the code in the action handler would like this:
@Override public void execute(ExecutionContext executionContext) throws Exception { // get operation context from workflow OperationContext context = (OperationContext) executionContext .getContextInstance().getTransientVariable( Operation.OPERATION_CONTEXT); // create discovery operation WorkflowOperation discoveryOperation = new WorkflowOperation(context); // create discovery related workflow ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(definition); ProcessInstance processInstance = new ProcessInstance(processDefinition); discoveryOperation.setProcessInstance(processInstance); new JBossCacheServiceFactory().getCacheService( CacheRegionConstants.TASK).put(context.getOperationId(), discoveryOperation); if (logger.isDebugEnabled()) { logger.debug("Discovery Operation with Workflow created successfully."); } }
For this inner processInstance I didn't do anything like call the save method to make it persisted, and this is also what i expected, because i want to put it in the cache, and the following code show how i created the outer processInstance:
public static final void createProcess(OperationContext context) { JbpmContext jbpmContext = JbpmConfingurationFactory.jbpmConfiguration .createJbpmContext(); try { ProcessDefinition retrievedPd = jbpmContext.getGraphSession() .findLatestProcessDefinition(context.getWorkflowName()); if (retrievedPd == null) { logger.error("Can not find Process Definition with name: " + context.getWorkflowName()); throw new DMException("Can not find Process Definition with name: " + context.getWorkflowName()); } ProcessInstance processInstance = new ProcessInstance(retrievedPd); processInstance.setKey(context.getTaskId()); processInstance.getContextInstance().setTransientVariable(Operation.OPERATION_CONTEXT, context); // ready to signal work flow processInstance.signal(); jbpmContext.save(processInstance); if (logger.isDebugEnabled()) { logger.debug("---------------- create processinstance -----------------"); logger.debug("---------------- complete [" + context.getTaskId() + "] -----------------"); } } finally { jbpmContext.close(); } }
You see i call the save method and try to make the outer processInstance persisted, so I expect the outer processInstance should be persisted successfully but the inner one shouldn't, because i explicitily call the save method for the outer one not for the inner one, this make sense to me and i think it's a correct logic, but when i close the jbpmContext, i got the following error:
10:36:36,392 ERROR [DbPersistenceService] hibernate commit failed org.hibernate.TransientObjectException: object references an unsaved transient instance - save the t ransient instance before flushing: org.jbpm.graph.def.Node at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:219) at org.hibernate.type.EntityType.getIdentifier(EntityType.java:397) at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:242) at org.hibernate.type.TypeFactory.findDirty(TypeFactory.java:597) at org.hibernate.persister.entity.AbstractEntityPersister.findDirty(AbstractEntityPersister. java:3128) at org.hibernate.event.def.DefaultFlushEntityEventListener.dirtyCheck(DefaultFlushEntityEven tListener.java:479) at org.hibernate.event.def.DefaultFlushEntityEventListener.isUpdateNecessary(DefaultFlushEnt ityEventListener.java:204) at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityE ventListener.java:127) at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEvent Listener.java:196) at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(Abstrac tFlushingEventListener.java:76) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java: 26) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000) at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338) at org.hibernate.transaction.JTATransaction.commit(JTATransaction.java:135) at org.jbpm.persistence.db.DbPersistenceService.commit(DbPersistenceService.java:262) at org.jbpm.persistence.db.DbPersistenceService.close(DbPersistenceService.java:218) at org.jbpm.svc.Services.close(Services.java:236) at org.jbpm.JbpmContext.close(JbpmContext.java:136)
So, please tell me, did i miss something? Thank you very very much.
P.S. I post a similar topic yesterday, but it's not as clear as this one, so i post this new one.