trouble persisting flow execution in DB
The first evident way is to inherit from one of existing repositories, overriding methods, storing and restoring execution. FlowExecution successfully stores as blob and restores too, but exception occurs when accessing flow scope (mapping flow output params). May be overriding 2 methods is not enough?
Code, schema and stack trace look as following:
public class MyFlowExecutionRepository extends DefaultFlowExecutionRepository {
private MyFlowExecutionRepository(FlowExecutionRepositoryS ervices arg0) {
super(arg0);
}
public void putFlowExecution(FlowExecutionKey key, FlowExecution flowExecution){
Connection con = ....;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(asImpl(flowExecution));
// serialize the employee object into a byte array
byte[] flowAsBytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(flowAsBytes);
// Insert into DB
PreparedStatement pstmt = con
.prepareStatement(quot;INSERT INTO flow_repository(flow_key, flow) VALUES(?, ?)quot;);
pstmt.setString(1, key.toString());
pstmt.setBinaryStream(2, bais, flowAsBytes.length);
pstmt.executeUpdate();
pstmt.close();
}
public FlowExecution getFlowExecution(FlowExecutionKey key){
FlowExecution flow = null;
Statement stmt;
ResultSet rs;
Connection con = ...;
stmt = con.createStatement();
rs = stmt
.executeQuery(quot;SELECT flow FROM flow_repository WHERE flow_key = 'quot;
+ key.toString() + quot;'quot;);
while (rs.next()) {
Blob blb = rs.getBlob(quot;flowquot;);
InputStream baip = blb.getBinaryStream();
ObjectInputStream ois = new ObjectInputStream(baip);
// re-create the object
flow = rehydrate((FlowExecution) ois.readObject(), key);
}
return flow;
}
public static MyFlowExecutionRepository getInstance(FlowLocator locator){
if(instance == null){
instance = new MyFlowExecutionRepository(new FlowExecutionRepositoryServices(locator));
}
return instance;
}
private static MyFlowExecutionRepository instance = null;
}
lt;flow start-state=quot;displayClientFormquot;gt; lt;view-state id=quot;displayClientFormquot; view=quot;IdentifyClient.jspquot;gt; lt;transition on=quot;submitquot; to=quot;storeClientquot;gt; lt;action bean=quot;clientFormActionquot; method=quot;bindAndValidatequot;/gt; lt;/transitiongt; lt;/view-stategt; lt;action-state id=quot;storeClientquot;gt; lt;action bean=quot;clientFormActionquot; method=quot;storeClientquot;/gt; lt;transition to=quot;finishquot;/gt; lt;/action-stategt; lt;end-state id=quot;finishquot;gt; lt;output-mappergt; lt;mapping source=quot;${flowScope.clientId}quot; target=quot;clientIdquot;/gt; lt;/output-mappergt; lt;/end-stategt;
lt;/flowgt;
java.lang.NullPointerException
org..webflow.execution.impl.Request ControlContextImpl.getModel(RequestControlContextI mpl.java:153)
org..webflow.support.ApplicationVie wSelector.createApplicationView(ApplicationViewSel ector.java:123)
org..webflow.support.ApplicationVie wSelector.makeRefreshSelection(ApplicationViewSele ctor.java:104)
org..webflow.support.ApplicationVie wSelector.makeSelection(ApplicationViewSelector.ja va:95)
org..webflow.ViewState.doEnter(View State.java:89)
org..webflow.State.enter(State.java :194)
org..webflow.Transition.execute(Tra nsition.java:220)
org..webflow.TransitionableState.on Event(TransitionableState.java:102)
org..webflow.Flow.onEvent(Flow.java :603)
org..webflow.execution.impl.Request ControlContextImpl.signalEvent(RequestControlConte xtImpl.java:199)
org..webflow.ActionState.doEnter(Ac tionState.java:180)
org..webflow.State.enter(State.java :194)
org..webflow.Flow.start(Flow.java:5 88)
org..webflow.execution.impl.Request ControlContextImpl.start(RequestControlContextImpl .java:187)
org..webflow.SubflowState.doEnter(S ubflowState.java:116)
org..webflow.State.enter(State.java :194)
org..webflow.Transition.execute(Tra nsition.java:220)
org..webflow.TransitionableState.on Event(TransitionableState.java:102)
as i suppose, the problem is that getConversationScope() call inside getModel() returns null. But why it return null?
If i remove output param mapping, flow ends successfully.
Help please, if anybeody have idea =)
problem solved.
the key point was ConversationScope of FlowExecution is transient and is null after rehydration. But if you use input-output mapping, Web Flow accesses it and throws NullPointerException. |