[jboss-svn-commits] JBL Code SVN: r25146 - labs/jbossrules/trunk/drools-process/drools-process-enterprise/src/main/java/org/drools/persistence/processinstance.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Feb 6 22:26:28 EST 2009


Author: mark.proctor at jboss.com
Date: 2009-02-06 22:26:28 -0500 (Fri, 06 Feb 2009)
New Revision: 25146

Modified:
   labs/jbossrules/trunk/drools-process/drools-process-enterprise/src/main/java/org/drools/persistence/processinstance/ProcessInstanceInfo.java
Log:
JBRULES-1958 Improve JPA persistence
-Better update handling added.

Modified: labs/jbossrules/trunk/drools-process/drools-process-enterprise/src/main/java/org/drools/persistence/processinstance/ProcessInstanceInfo.java
===================================================================
--- labs/jbossrules/trunk/drools-process/drools-process-enterprise/src/main/java/org/drools/persistence/processinstance/ProcessInstanceInfo.java	2009-02-07 00:06:20 UTC (rev 25145)
+++ labs/jbossrules/trunk/drools-process/drools-process-enterprise/src/main/java/org/drools/persistence/processinstance/ProcessInstanceInfo.java	2009-02-07 03:26:28 UTC (rev 25146)
@@ -15,6 +15,10 @@
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.Lob;
+import javax.persistence.PostLoad;
+import javax.persistence.PostPersist;
+import javax.persistence.PostUpdate;
+import javax.persistence.PrePersist;
 import javax.persistence.PreUpdate;
 import javax.persistence.Transient;
 
@@ -22,134 +26,170 @@
 import org.drools.marshalling.MarshallerWriteContext;
 import org.drools.marshalling.ProcessInstanceMarshaller;
 import org.drools.marshalling.ProcessMarshallerRegistry;
-import org.drools.marshalling.RuleFlowProcessInstanceMarshaller;
 import org.drools.process.instance.impl.ProcessInstanceImpl;
-import org.drools.ruleflow.instance.RuleFlowProcessInstance;
 import org.drools.runtime.process.ProcessInstance;
-import org.drools.workflow.instance.impl.WorkflowProcessInstanceImpl;
 import org.hibernate.annotations.CollectionOfElements;
 
 @Entity
 public class ProcessInstanceInfo {
 
-	private @Id
-	@GeneratedValue(strategy = GenerationType.AUTO)
-	Long processInstanceId;
-	private String processId;
-	private Date startDate;
-	private Date lastReadDate;
-	private Date lastModificationDate;
-	private int state;
-	// TODO How do I mark a process instance info as dirty when the process
-	// instance
-	// has changed (so that byte array is regenerated and saved) ?
-	private @Lob
-	byte[] processInstanceByteArray;
-	@CollectionOfElements
-	private Set<String> eventTypes = new HashSet<String>();
-	private @Transient
-	ProcessInstance processInstance;
+    private @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    Long                processInstanceId;
+    private String      processId;
+    private Date        startDate;
+    private Date        lastReadDate;
+    private Date        lastModificationDate;
+    private int         state;
 
-	ProcessInstanceInfo() {
-	}
+    private @Lob
+    byte[]              processInstanceByteArray;
 
-	public ProcessInstanceInfo(ProcessInstance processInstance) {
-		this.processInstance = processInstance;
-		this.processId = processInstance.getProcessId();
-		startDate = new Date();
-	}
+    private @Transient
+    @Lob
+    byte[]              processInstanceByteArrayShadow;
 
-	public long getId() {
-		return processInstanceId;
-	}
+    @CollectionOfElements
+    private Set<String> eventTypes = new HashSet<String>();
 
-	public String getProcessId() {
-		return processId;
-	}
+    private @Transient
+    ProcessInstance     processInstance;
 
-	public Date getStartDate() {
-		return startDate;
-	}
+    ProcessInstanceInfo() {
+    }
 
-	public Date getLastModificationDate() {
-		return lastModificationDate;
-	}
+    public ProcessInstanceInfo(ProcessInstance processInstance) {
+        this.processInstance = processInstance;
+        this.processId = processInstance.getProcessId();
+        startDate = new Date();
+    }
 
-	public Date getLastReadDate() {
-		return lastReadDate;
-	}
+    public long getId() {
+        return processInstanceId;
+    }
 
-	public void updateLastReadDate() {
-		lastReadDate = new Date();
-	}
+    public String getProcessId() {
+        return processId;
+    }
 
-	public int getState() {
-		return state;
-	}
+    public Date getStartDate() {
+        return startDate;
+    }
 
-	public ProcessInstance getProcessInstance() {
-		if (processInstance == null) {
-			try {
-				ByteArrayInputStream bais = new ByteArrayInputStream(
-						processInstanceByteArray);
-				MarshallerReaderContext context = new MarshallerReaderContext(
-						bais, null, null, null);
-				ProcessInstanceMarshaller marshaller = getMarshallerFromContext(context);
-				processInstance = marshaller.readProcessInstance(context);
-				context.close();
-			} catch (IOException e) {
-				e.printStackTrace();
-				throw new IllegalArgumentException(
-						"IOException while loading process instance: "
-								+ e.getMessage());
-			}
-		}
-		return processInstance;
-	}
+    public Date getLastModificationDate() {
+        return lastModificationDate;
+    }
 
-	private ProcessInstanceMarshaller getMarshallerFromContext(
-			MarshallerReaderContext context) throws IOException {
-		ObjectInputStream stream = context.stream;
-		String processInstanceType = stream.readUTF();
-		return ProcessMarshallerRegistry.INSTANCE
-				.getMarshaller(processInstanceType);
-	}
+    public Date getLastReadDate() {
+        return lastReadDate;
+    }
 
-	private void saveProcessInstanceType(MarshallerWriteContext context,
-			ProcessInstance processInstance, String processInstanceType)
-			throws IOException {
-		ObjectOutputStream stream = context.stream;
-		// saves the processInstance type first
-		stream.writeUTF(processInstanceType);
-	}
+    public void updateLastReadDate() {
+        lastReadDate = new Date();
+    }
 
-	@PreUpdate
-	public void update() {
-		ByteArrayOutputStream baos = new ByteArrayOutputStream();
-		try {
-			MarshallerWriteContext context = new MarshallerWriteContext(baos,
-					null, null, null, null);
-			String processType = ((ProcessInstanceImpl) processInstance).getProcess()
-					.getType();
-			saveProcessInstanceType(context, processInstance, processType);
-			ProcessInstanceMarshaller marshaller = ProcessMarshallerRegistry.INSTANCE.getMarshaller(processType);
-			marshaller.writeProcessInstance(
-					context, processInstance);
-			context.close();
-		} catch (IOException e) {
-			throw new IllegalArgumentException(
-					"IOException while storing process instance "
-							+ processInstance.getId() + ": " + e.getMessage());
-		}
-		byte[] newByteArray = baos.toByteArray();
-		if (!Arrays.equals(newByteArray, processInstanceByteArray)) {
-			this.state = processInstance.getState();
-			this.lastModificationDate = new Date();
-			this.processInstanceByteArray = newByteArray;
-			this.eventTypes.clear();
-			for (String type : processInstance.getEventTypes()) {
-				eventTypes.add(type);
-			}
-		}
-	}
+    public int getState() {
+        return state;
+    }
+
+    public ProcessInstance getProcessInstance() {
+        return processInstance;
+    }
+
+    private ProcessInstanceMarshaller getMarshallerFromContext(MarshallerReaderContext context) throws IOException {
+        ObjectInputStream stream = context.stream;
+        String processInstanceType = stream.readUTF();
+        return ProcessMarshallerRegistry.INSTANCE.getMarshaller( processInstanceType );
+    }
+
+    private void saveProcessInstanceType(MarshallerWriteContext context,
+                                         ProcessInstance processInstance,
+                                         String processInstanceType) throws IOException {
+        ObjectOutputStream stream = context.stream;
+        // saves the processInstance type first
+        stream.writeUTF( processInstanceType );
+    }
+
+    @PostLoad
+    public void postLoad() {
+        if ( processInstance == null ) {
+            try {
+                ByteArrayInputStream bais = new ByteArrayInputStream( processInstanceByteArray );
+                MarshallerReaderContext context = new MarshallerReaderContext( bais,
+                                                                               null,
+                                                                               null,
+                                                                               null );
+                ProcessInstanceMarshaller marshaller = getMarshallerFromContext( context );
+                processInstance = marshaller.readProcessInstance( context );
+                context.close();
+            } catch ( IOException e ) {
+                e.printStackTrace();
+                throw new IllegalArgumentException( "IOException while loading process instance: " + e.getMessage() );
+            }
+        }
+        // reference it as a shadow field, this can be used to check for changes and do rollbacks without hitting the DB.
+        this.processInstanceByteArrayShadow = this.processInstanceByteArray;
+        this.processInstanceByteArray = null; // setting this to null will force an update
+    }
+
+    @PreUpdate
+    // executes before update
+    @PrePersist
+    // executes before insert
+    public void update() {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try {
+            MarshallerWriteContext context = new MarshallerWriteContext( baos,
+                                                                         null,
+                                                                         null,
+                                                                         null,
+                                                                         null );
+            String processType = ((ProcessInstanceImpl) processInstance).getProcess().getType();
+            saveProcessInstanceType( context,
+                                     processInstance,
+                                     processType );
+            ProcessInstanceMarshaller marshaller = ProcessMarshallerRegistry.INSTANCE.getMarshaller( processType );
+            marshaller.writeProcessInstance( context,
+                                             processInstance );
+            context.close();
+        } catch ( IOException e ) {
+            throw new IllegalArgumentException( "IOException while storing process instance " + processInstance.getId() + ": " + e.getMessage() );
+        }
+        byte[] newByteArray = baos.toByteArray();
+        if ( !Arrays.equals( newByteArray,
+                             processInstanceByteArrayShadow ) ) {
+            this.state = processInstance.getState();
+            this.lastModificationDate = new Date();
+            this.processInstanceByteArray = newByteArray;
+            this.processInstanceByteArrayShadow = newByteArray;
+            this.eventTypes.clear();
+            for ( String type : processInstance.getEventTypes() ) {
+                eventTypes.add( type );
+            }
+        } else {
+            // there was no change so restore for the perist process
+            this.processInstanceByteArray = this.processInstanceByteArrayShadow;
+        }
+    }
+
+    @PostUpdate
+    // executes after update
+    @PostPersist
+    // executes after insert
+    public void postUpdate() {
+        // we need to null this to force an update check
+        this.processInstanceByteArray = null;
+    }
+
+    public void rollback() {
+        // restore the processInstanceByteArray
+        this.processInstanceByteArray = this.processInstanceByteArrayShadow;
+
+        //Simulate load which forces rebuilding of the process from the shadow
+        postLoad();
+    }
+
+    public void commit() {
+        this.processInstanceByteArrayShadow = processInstanceByteArray;
+    }
 }




More information about the jboss-svn-commits mailing list