jpa tests, hibernate bug fix
This commit is contained in:
@@ -35,8 +35,9 @@
|
||||
<classpathentry kind="lib" path="lib/test/spring-mock.jar" sourcepath="/spring/mock"/>
|
||||
<classpathentry kind="lib" path="lib/global/el-api.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/persistence-api.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/spring-jpa.jar"/>
|
||||
<classpathentry kind="lib" path="lib/test/shale-test.jar"/>
|
||||
<classpathentry kind="lib" path="lib/global/jboss-el.jar"/>
|
||||
<classpathentry kind="lib" path="lib/test/toplink-essentials.jar"/>
|
||||
<classpathentry kind="lib" path="lib/buildtime/spring-jpa.jar"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
||||
@@ -60,9 +60,7 @@
|
||||
|
||||
<dependency org="org.springframework" name="spring-dao" rev="2.0.6" conf="buildtime->default" />
|
||||
<dependency org="org.springframework" name="spring-hibernate3" rev="2.0.6" conf="buildtime->default" />
|
||||
|
||||
<dependency org="javax.persistence" name="persistence-api" rev="1.0b" conf="buildtime->default"/>
|
||||
<dependency org="toplink.essentials" name="toplink-essentials" rev="2.0-56" conf="buildtime->default" />
|
||||
<dependency org="org.springframework" name="spring-jpa" rev="2.0.6" conf="buildtime->default" />
|
||||
|
||||
<!-- test time only dependencies -->
|
||||
@@ -72,7 +70,11 @@
|
||||
<dependency org="com.cenqua.clover" name="clover" rev="1.3.12" conf="test->default" />
|
||||
<dependency org="org.springframework" name="spring-jdbc" rev="2.0.6" conf="test->default" />
|
||||
<dependency org="org.springframework" name="spring-mock" rev="2.0.6" conf="test->default" />
|
||||
<dependency org="org.springframework" name="spring-agent" rev="2.0.6" conf="test->default" />
|
||||
<dependency org="org.apache.shale" name="shale-test" rev="1.0.4" conf="test->default" />
|
||||
<dependency org="toplink.essentials" name="toplink-essentials" rev="2.0-56" conf="test->default" />
|
||||
<dependency org="toplink.essentials" name="toplink-essentials-agent" rev="2.0-56" conf="test->default" />
|
||||
|
||||
</dependencies>
|
||||
|
||||
</ivy-module>
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.webflow.support.persistence;
|
||||
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.Interceptor;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.springframework.orm.hibernate3.SessionHolder;
|
||||
@@ -72,12 +73,14 @@ import org.springframework.webflow.execution.ViewSelection;
|
||||
*/
|
||||
public class HibernateFlowExecutionListener extends FlowExecutionListenerAdapter {
|
||||
|
||||
private static final String HIBERNATE_SESSION_ATTRIBUTE = "hibernate.session";
|
||||
private static final String HIBERNATE_SESSION_ATTRIBUTE = "session";
|
||||
|
||||
private TransactionTemplate transactionTemplate;
|
||||
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
private Interceptor entityInterceptor;
|
||||
|
||||
/**
|
||||
* Create a new Session-per-Conversation listener using giving Hibernate session factory.
|
||||
* @param sessionFactory the session factory to use
|
||||
@@ -87,6 +90,14 @@ public class HibernateFlowExecutionListener extends FlowExecutionListenerAdapter
|
||||
this.transactionTemplate = new TransactionTemplate(transactionManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entity interceptor to attach to sessions opened by this listener.
|
||||
* @param entityInterceptor the entity interceptor
|
||||
*/
|
||||
public void setEntityInterceptor(Interceptor entityInterceptor) {
|
||||
this.entityInterceptor = entityInterceptor;
|
||||
}
|
||||
|
||||
public void sessionCreated(RequestContext context, FlowSession session) {
|
||||
if (session.isRoot() && session.getDefinition().getAttributes().contains("persistenceContext")) {
|
||||
Session hibernateSession = createSession(context);
|
||||
@@ -130,7 +141,8 @@ public class HibernateFlowExecutionListener extends FlowExecutionListenerAdapter
|
||||
// internal helpers
|
||||
|
||||
private Session createSession(RequestContext context) {
|
||||
Session session = sessionFactory.openSession();
|
||||
Session session = (entityInterceptor != null ? sessionFactory.openSession(entityInterceptor) : sessionFactory
|
||||
.openSession());
|
||||
session.setFlushMode(FlushMode.MANUAL);
|
||||
return session;
|
||||
}
|
||||
@@ -144,6 +156,8 @@ public class HibernateFlowExecutionListener extends FlowExecutionListenerAdapter
|
||||
}
|
||||
|
||||
private void unbind(Session session, RequestContext context) {
|
||||
TransactionSynchronizationManager.unbindResource(sessionFactory);
|
||||
if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
|
||||
TransactionSynchronizationManager.unbindResource(sessionFactory);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,7 +74,7 @@ import org.springframework.webflow.execution.ViewSelection;
|
||||
*/
|
||||
public class JpaFlowExecutionListener extends FlowExecutionListenerAdapter {
|
||||
|
||||
private static final String ENTITY_MANAGER_ATTRIBUTE = "jpa.entityManager";
|
||||
private static final String ENTITY_MANAGER_ATTRIBUTE = "entityManager";
|
||||
|
||||
private EntityManagerFactory entityManagerFactory;
|
||||
|
||||
@@ -114,8 +114,12 @@ public class JpaFlowExecutionListener extends FlowExecutionListenerAdapter {
|
||||
// this is a commit end state - start a new transaction that quickly commits
|
||||
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
|
||||
protected void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
// nothing to do - a flush will happen on commit automatically as this is a read-write
|
||||
// transaction
|
||||
// necessary for JTA to enlist the entity manager in the transaction
|
||||
try {
|
||||
em.joinTransaction();
|
||||
} catch (IllegalStateException e) {
|
||||
// won't be necessary once Spring 2.0.7 is released
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -139,6 +143,8 @@ public class JpaFlowExecutionListener extends FlowExecutionListenerAdapter {
|
||||
}
|
||||
|
||||
private void unbind(EntityManager em) {
|
||||
TransactionSynchronizationManager.unbindResource(entityManagerFactory);
|
||||
if (TransactionSynchronizationManager.hasResource(entityManagerFactory)) {
|
||||
TransactionSynchronizationManager.unbindResource(entityManagerFactory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,304 +68,311 @@ import org.springframework.webflow.test.MockFlowServiceLocator;
|
||||
* @author Ben Hale
|
||||
*/
|
||||
public class FlowExecutionImplTests extends TestCase {
|
||||
|
||||
public void testExceptionHandlingWithEvaluateAction() {
|
||||
FlowBuilder flowBuilder = new XmlFlowBuilder(new ClassPathResource("fooFlow.xml", getClass()));
|
||||
Flow flow = new FlowAssembler("fooFlow", flowBuilder).assembleFlow();
|
||||
FlowExecution flowExecution = new FlowExecutionImpl(flow);
|
||||
ViewSelection view = flowExecution.start(null, new MockExternalContext());
|
||||
assertEquals("showFooException", ((ApplicationView)view).getViewName());
|
||||
assertFalse(flowExecution.isActive());
|
||||
}
|
||||
|
||||
public void testExceptionWhileHandlingException() {
|
||||
MockFlowServiceLocator serviceLocator = new MockFlowServiceLocator();
|
||||
serviceLocator.registerBean("testAction", new ExceptionThrowingAction());
|
||||
XmlFlowBuilder flowBuilder =
|
||||
new XmlFlowBuilder(new ClassPathResource("exceptionHandlingFlow.xml", this.getClass()));
|
||||
flowBuilder.setFlowServiceLocator(serviceLocator);
|
||||
Flow flow = new FlowAssembler("flow", flowBuilder).assembleFlow();
|
||||
FlowExecution flowExecution = new FlowExecutionImpl(flow);
|
||||
ViewSelection view = flowExecution.start(null, new MockExternalContext());
|
||||
assertEquals("failed", ((ApplicationView)view).getViewName());
|
||||
assertFalse(flowExecution.isActive());
|
||||
|
||||
public void testExceptionHandlingWithGlobalTransitionExceptionHandler() {
|
||||
FlowBuilder flowBuilder = new XmlFlowBuilder(new ClassPathResource("globalTransitionExceptionHandler-flow.xml",
|
||||
getClass()));
|
||||
Flow flow = new FlowAssembler("test", flowBuilder).assembleFlow();
|
||||
FlowExecution flowExecution = new FlowExecutionImpl(flow);
|
||||
ViewSelection view = flowExecution.start(null, new MockExternalContext());
|
||||
assertEquals("showFooException", ((ApplicationView) view).getViewName());
|
||||
assertFalse(flowExecution.isActive());
|
||||
}
|
||||
|
||||
public void testExceptionHandlingWithEvaluateAction() {
|
||||
FlowBuilder flowBuilder = new XmlFlowBuilder(new ClassPathResource("fooFlow.xml", getClass()));
|
||||
Flow flow = new FlowAssembler("fooFlow", flowBuilder).assembleFlow();
|
||||
FlowExecution flowExecution = new FlowExecutionImpl(flow);
|
||||
ViewSelection view = flowExecution.start(null, new MockExternalContext());
|
||||
assertEquals("showFooException", ((ApplicationView) view).getViewName());
|
||||
assertFalse(flowExecution.isActive());
|
||||
}
|
||||
|
||||
public void testExceptionWhileHandlingException() {
|
||||
MockFlowServiceLocator serviceLocator = new MockFlowServiceLocator();
|
||||
serviceLocator.registerBean("testAction", new ExceptionThrowingAction());
|
||||
XmlFlowBuilder flowBuilder = new XmlFlowBuilder(new ClassPathResource("exceptionHandlingFlow.xml", this
|
||||
.getClass()));
|
||||
flowBuilder.setFlowServiceLocator(serviceLocator);
|
||||
Flow flow = new FlowAssembler("flow", flowBuilder).assembleFlow();
|
||||
FlowExecution flowExecution = new FlowExecutionImpl(flow);
|
||||
ViewSelection view = flowExecution.start(null, new MockExternalContext());
|
||||
assertEquals("failed", ((ApplicationView) view).getViewName());
|
||||
assertFalse(flowExecution.isActive());
|
||||
}
|
||||
|
||||
public void testFlowExecutionListener() {
|
||||
Flow flow = new Flow("myFlow");
|
||||
DefaultAttributeMapper inputMapper = new DefaultAttributeMapper();
|
||||
MappingBuilder mapping = new MappingBuilder(DefaultExpressionParserFactory.getExpressionParser());
|
||||
inputMapper.addMapping(mapping.source("name").target("flowScope.name").value());
|
||||
flow.setInputMapper(inputMapper);
|
||||
ActionState actionState = new ActionState(flow, "actionState");
|
||||
actionState.getActionList().add(new TestAction());
|
||||
actionState.getTransitionSet().add(new Transition(onEvent("success"), toState("viewState")));
|
||||
|
||||
ViewState viewState = new ViewState(flow, "viewState");
|
||||
viewState.setViewSelector(selectView("myView"));
|
||||
viewState.getTransitionSet().add(new Transition(onEvent("submit"), toState("subFlowState")));
|
||||
|
||||
Flow subFlow = new Flow("mySubFlow");
|
||||
ViewState state1 = new ViewState(subFlow, "subFlowViewState");
|
||||
state1.setViewSelector(selectView("mySubFlowViewName"));
|
||||
state1.getTransitionSet().add(new Transition(onEvent("submit"), toState("finish")));
|
||||
new EndState(subFlow, "finish");
|
||||
|
||||
SubflowState subflowState = new SubflowState(flow, "subFlowState", subFlow);
|
||||
subflowState.getTransitionSet().add(new Transition(onEvent("finish"), toState("finish")));
|
||||
|
||||
EndState endState = new EndState(flow, "finish");
|
||||
endState.getEntryActionList().add(new AbstractAction() {
|
||||
protected Event doExecute(RequestContext context) throws Exception {
|
||||
throw new IllegalStateException("Whoops!");
|
||||
}
|
||||
});
|
||||
TransitionExecutingStateExceptionHandler handler = new TransitionExecutingStateExceptionHandler();
|
||||
handler.add(Exception.class, "error");
|
||||
endState.getExceptionHandlerSet().add(handler);
|
||||
|
||||
new EndState(flow, "error");
|
||||
|
||||
MockFlowExecutionListener flowExecutionListener = new MockFlowExecutionListener();
|
||||
FlowExecutionImpl flowExecution = new FlowExecutionImpl(flow,
|
||||
new FlowExecutionListener[] { flowExecutionListener }, null);
|
||||
LocalAttributeMap input = new LocalAttributeMap();
|
||||
input.put("name", "value");
|
||||
assertTrue(!flowExecutionListener.isStarted());
|
||||
flowExecution.start(input, new MockExternalContext());
|
||||
assertTrue(flowExecutionListener.isStarted());
|
||||
assertTrue(flowExecutionListener.isPaused());
|
||||
assertTrue(!flowExecutionListener.isExecuting());
|
||||
assertEquals(1, flowExecutionListener.getEventsSignaledCount());
|
||||
assertEquals(0, flowExecutionListener.getFlowNestingLevel());
|
||||
assertEquals(2, flowExecutionListener.getTransitionCount());
|
||||
assertEquals("value", flowExecution.getActiveSession().getScope().getString("name"));
|
||||
flowExecution.signalEvent("submit", new MockExternalContext());
|
||||
assertTrue(!flowExecutionListener.isExecuting());
|
||||
assertEquals(2, flowExecutionListener.getEventsSignaledCount());
|
||||
assertEquals(1, flowExecutionListener.getFlowNestingLevel());
|
||||
assertEquals(4, flowExecutionListener.getTransitionCount());
|
||||
flowExecution.signalEvent("submit", new MockExternalContext());
|
||||
assertTrue(!flowExecutionListener.isExecuting());
|
||||
assertEquals(0, flowExecutionListener.getFlowNestingLevel());
|
||||
assertEquals(4, flowExecutionListener.getEventsSignaledCount());
|
||||
assertEquals(7, flowExecutionListener.getTransitionCount());
|
||||
assertEquals(1, flowExecutionListener.getExceptionsThrown());
|
||||
assertTrue(!flowExecution.isActive());
|
||||
}
|
||||
|
||||
public void testLoopInFlow() throws Exception {
|
||||
AbstractFlowBuilder builder = new AbstractFlowBuilder() {
|
||||
public void buildStates() throws FlowBuilderException {
|
||||
addViewState("viewState", "viewName", new Transition[] { transition(on(submit()), to("viewState")),
|
||||
transition(on(finish()), to("endState")) });
|
||||
addEndState("endState");
|
||||
}
|
||||
};
|
||||
Flow flow = new FlowAssembler("flow", builder).assembleFlow();
|
||||
FlowExecution flowExecution = new FlowExecutionImpl(flow);
|
||||
ApplicationView view = (ApplicationView) flowExecution.start(null, new MockExternalContext());
|
||||
assertNotNull(view);
|
||||
assertEquals("viewName", view.getViewName());
|
||||
for (int i = 0; i < 10; i++) {
|
||||
view = (ApplicationView) flowExecution.signalEvent("submit", new MockExternalContext());
|
||||
assertEquals("viewName", view.getViewName());
|
||||
}
|
||||
assertTrue(flowExecution.isActive());
|
||||
flowExecution.signalEvent("finish", new MockExternalContext());
|
||||
assertFalse(flowExecution.isActive());
|
||||
}
|
||||
|
||||
public void testFlowExecutionListener() {
|
||||
Flow flow = new Flow("myFlow");
|
||||
DefaultAttributeMapper inputMapper = new DefaultAttributeMapper();
|
||||
MappingBuilder mapping = new MappingBuilder(DefaultExpressionParserFactory.getExpressionParser());
|
||||
inputMapper.addMapping(mapping.source("name").target("flowScope.name").value());
|
||||
flow.setInputMapper(inputMapper);
|
||||
ActionState actionState = new ActionState(flow, "actionState");
|
||||
actionState.getActionList().add(new TestAction());
|
||||
actionState.getTransitionSet().add(new Transition(onEvent("success"), toState("viewState")));
|
||||
public void testLoopInFlowWithSubFlow() throws Exception {
|
||||
AbstractFlowBuilder childBuilder = new AbstractFlowBuilder() {
|
||||
public void buildStates() throws FlowBuilderException {
|
||||
addActionState("doOtherStuff", new AbstractAction() {
|
||||
private int executionCount = 0;
|
||||
|
||||
ViewState viewState = new ViewState(flow, "viewState");
|
||||
viewState.setViewSelector(selectView("myView"));
|
||||
viewState.getTransitionSet().add(new Transition(onEvent("submit"), toState("subFlowState")));
|
||||
|
||||
Flow subFlow = new Flow("mySubFlow");
|
||||
ViewState state1 = new ViewState(subFlow, "subFlowViewState");
|
||||
state1.setViewSelector(selectView("mySubFlowViewName"));
|
||||
state1.getTransitionSet().add(new Transition(onEvent("submit"), toState("finish")));
|
||||
new EndState(subFlow, "finish");
|
||||
|
||||
SubflowState subflowState = new SubflowState(flow, "subFlowState", subFlow);
|
||||
subflowState.getTransitionSet().add(new Transition(onEvent("finish"), toState("finish")));
|
||||
|
||||
EndState endState = new EndState(flow, "finish");
|
||||
endState.getEntryActionList().add(new AbstractAction() {
|
||||
protected Event doExecute(RequestContext context) throws Exception {
|
||||
throw new IllegalStateException("Whoops!");
|
||||
protected Event doExecute(RequestContext context) throws Exception {
|
||||
executionCount++;
|
||||
if (executionCount < 2) {
|
||||
return success();
|
||||
}
|
||||
});
|
||||
TransitionExecutingStateExceptionHandler handler = new TransitionExecutingStateExceptionHandler();
|
||||
handler.add(Exception.class, "error");
|
||||
endState.getExceptionHandlerSet().add(handler);
|
||||
return error();
|
||||
}
|
||||
},
|
||||
new Transition[] { transition(on(success()), to(finish())),
|
||||
transition(on(error()), to("stopTest")) });
|
||||
addEndState(finish());
|
||||
addEndState("stopTest");
|
||||
}
|
||||
};
|
||||
final Flow childFlow = new FlowAssembler("flow", childBuilder).assembleFlow();
|
||||
AbstractFlowBuilder parentBuilder = new AbstractFlowBuilder() {
|
||||
public void buildStates() throws FlowBuilderException {
|
||||
addActionState("doStuff", new AbstractAction() {
|
||||
protected Event doExecute(RequestContext context) throws Exception {
|
||||
return success();
|
||||
}
|
||||
}, transition(on(success()), to("startSubFlow")));
|
||||
addSubflowState("startSubFlow", childFlow, null, new Transition[] {
|
||||
transition(on(finish()), to("startSubFlow")), transition(on("stopTest"), to("stopTest")) });
|
||||
addEndState("stopTest");
|
||||
}
|
||||
};
|
||||
Flow parentFlow = new FlowAssembler("parentFlow", parentBuilder).assembleFlow();
|
||||
|
||||
new EndState(flow, "error");
|
||||
FlowExecution flowExecution = new FlowExecutionImpl(parentFlow);
|
||||
flowExecution.start(null, new MockExternalContext());
|
||||
assertFalse(flowExecution.isActive());
|
||||
}
|
||||
|
||||
MockFlowExecutionListener flowExecutionListener = new MockFlowExecutionListener();
|
||||
FlowExecutionImpl flowExecution = new FlowExecutionImpl(flow,
|
||||
new FlowExecutionListener[] { flowExecutionListener }, null);
|
||||
LocalAttributeMap input = new LocalAttributeMap();
|
||||
input.put("name", "value");
|
||||
assertTrue(!flowExecutionListener.isStarted());
|
||||
flowExecution.start(input, new MockExternalContext());
|
||||
assertTrue(flowExecutionListener.isStarted());
|
||||
assertTrue(flowExecutionListener.isPaused());
|
||||
assertTrue(!flowExecutionListener.isExecuting());
|
||||
assertEquals(1, flowExecutionListener.getEventsSignaledCount());
|
||||
assertEquals(0, flowExecutionListener.getFlowNestingLevel());
|
||||
assertEquals(2, flowExecutionListener.getTransitionCount());
|
||||
assertEquals("value", flowExecution.getActiveSession().getScope().getString("name"));
|
||||
flowExecution.signalEvent("submit", new MockExternalContext());
|
||||
assertTrue(!flowExecutionListener.isExecuting());
|
||||
assertEquals(2, flowExecutionListener.getEventsSignaledCount());
|
||||
assertEquals(1, flowExecutionListener.getFlowNestingLevel());
|
||||
assertEquals(4, flowExecutionListener.getTransitionCount());
|
||||
flowExecution.signalEvent("submit", new MockExternalContext());
|
||||
assertTrue(!flowExecutionListener.isExecuting());
|
||||
assertEquals(0, flowExecutionListener.getFlowNestingLevel());
|
||||
assertEquals(4, flowExecutionListener.getEventsSignaledCount());
|
||||
assertEquals(7, flowExecutionListener.getTransitionCount());
|
||||
assertEquals(1, flowExecutionListener.getExceptionsThrown());
|
||||
assertTrue(!flowExecution.isActive());
|
||||
public void testExtensiveFlowNavigationScenario1() {
|
||||
XmlFlowBuilder builder = new XmlFlowBuilder(new ClassPathResource("testFlow1.xml", XmlFlowBuilderTests.class),
|
||||
new TestFlowServiceLocator());
|
||||
FlowAssembler assembler = new FlowAssembler("testFlow1", builder);
|
||||
FlowExecution execution = new FlowExecutionImpl(assembler.assembleFlow());
|
||||
MockExternalContext context = new MockExternalContext();
|
||||
execution.start(null, context);
|
||||
assertEquals("viewState1", execution.getActiveSession().getState().getId());
|
||||
assertNotNull(execution.getActiveSession().getScope().get("items"));
|
||||
execution.signalEvent("event1", context);
|
||||
assertTrue(!execution.isActive());
|
||||
}
|
||||
|
||||
public void testExtensiveFlowNavigationScenario2() {
|
||||
XmlFlowBuilder builder = new XmlFlowBuilder(new ClassPathResource("testFlow1.xml", XmlFlowBuilderTests.class),
|
||||
new TestFlowServiceLocator());
|
||||
LocalAttributeMap attributes = new LocalAttributeMap();
|
||||
attributes.put("scenario2", Boolean.TRUE);
|
||||
FlowAssembler assembler = new FlowAssembler("testFlow1", attributes, builder);
|
||||
FlowExecution execution = new FlowExecutionImpl(assembler.assembleFlow());
|
||||
MockExternalContext context = new MockExternalContext();
|
||||
execution.start(null, context);
|
||||
assertEquals("viewState2", execution.getActiveSession().getState().getId());
|
||||
assertNotNull(execution.getActiveSession().getScope().get("items"));
|
||||
execution.signalEvent("event2", context);
|
||||
assertTrue(!execution.isActive());
|
||||
}
|
||||
|
||||
public void testFlashScope() {
|
||||
FlowExecution execution = new FlowExecutionImpl(new FlashScopeFlow());
|
||||
MockExternalContext context = new MockExternalContext();
|
||||
execution.start(null, context);
|
||||
execution.refresh(context);
|
||||
execution.refresh(context);
|
||||
execution.signalEvent("view", context);
|
||||
}
|
||||
|
||||
public void testExceptionFromInputMapper() {
|
||||
FlowBuilder flowBuilder = new XmlFlowBuilder(new ClassPathResource("runtime-exception.xml", getClass()));
|
||||
Flow flow = new FlowAssembler("runtime-exception", flowBuilder).assembleFlow();
|
||||
FlowExecutionImpl flowExecution = new FlowExecutionImpl(flow);
|
||||
try {
|
||||
flowExecution.start(new LocalAttributeMap(), new MockExternalContext());
|
||||
fail("Should have thrown a FlowExecutionException, not any other type");
|
||||
} catch (FlowExecutionException e) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testExceptionWithListener() {
|
||||
FlowBuilder flowBuilder = new XmlFlowBuilder(new ClassPathResource("runtime-exception.xml", getClass()));
|
||||
Flow flow = new FlowAssembler("runtime-exception", flowBuilder).assembleFlow();
|
||||
FlowExceptionListener listener = new FlowExceptionListener();
|
||||
FlowExecutionImpl flowExecution = new FlowExecutionImpl(flow);
|
||||
flowExecution.setListeners(new FlowExecutionListeners(new FlowExecutionListener[] { listener }));
|
||||
try {
|
||||
flowExecution.start(new LocalAttributeMap(), new MockExternalContext());
|
||||
fail("Should have thrown a FlowExecutionException, not any other type");
|
||||
} catch (FlowExecutionException e) {
|
||||
}
|
||||
|
||||
public void testLoopInFlow() throws Exception {
|
||||
AbstractFlowBuilder builder = new AbstractFlowBuilder() {
|
||||
public void buildStates() throws FlowBuilderException {
|
||||
addViewState("viewState", "viewName", new Transition[] { transition(on(submit()), to("viewState")),
|
||||
transition(on(finish()), to("endState")) });
|
||||
addEndState("endState");
|
||||
}
|
||||
};
|
||||
Flow flow = new FlowAssembler("flow", builder).assembleFlow();
|
||||
FlowExecution flowExecution = new FlowExecutionImpl(flow);
|
||||
ApplicationView view = (ApplicationView)flowExecution.start(null, new MockExternalContext());
|
||||
assertNotNull(view);
|
||||
assertEquals("viewName", view.getViewName());
|
||||
for (int i = 0; i < 10; i++) {
|
||||
view = (ApplicationView)flowExecution.signalEvent("submit", new MockExternalContext());
|
||||
assertEquals("viewName", view.getViewName());
|
||||
assertTrue("Listener should have been called on exception", listener.getExceptionFired());
|
||||
}
|
||||
|
||||
public void testExceptionWithHandler() {
|
||||
FlowBuilder flowBuilder = new XmlFlowBuilder(new ClassPathResource("runtime-exception.xml", getClass()));
|
||||
Flow flow = new FlowAssembler("runtime-exception", flowBuilder).assembleFlow();
|
||||
FlowExceptionHandler handler = new FlowExceptionHandler();
|
||||
flow.getExceptionHandlerSet().add(handler);
|
||||
FlowExecutionImpl flowExecution = new FlowExecutionImpl(flow);
|
||||
flowExecution.start(new LocalAttributeMap(), new MockExternalContext());
|
||||
assertTrue("Handler should have been called on exception", handler.getExceptionHandled());
|
||||
}
|
||||
|
||||
public static TransitionCriteria onEvent(String event) {
|
||||
return new EventIdTransitionCriteria(event);
|
||||
}
|
||||
|
||||
protected TargetStateResolver toState(String stateId) {
|
||||
return new DefaultTargetStateResolver(stateId);
|
||||
}
|
||||
|
||||
public static ViewSelector selectView(String viewName) {
|
||||
return new ApplicationViewSelector(new StaticExpression(viewName));
|
||||
}
|
||||
|
||||
private class FlashScopeFlow extends Flow {
|
||||
|
||||
public FlashScopeFlow() {
|
||||
super("flashScopeFlow");
|
||||
|
||||
ActionState state1 = new ActionState(this, "action");
|
||||
state1.getActionList().add(new Action() {
|
||||
public Event execute(RequestContext context) throws Exception {
|
||||
context.getFlashScope().put("flashScopedValue", "flashScopedValue");
|
||||
return new Event(this, "success");
|
||||
}
|
||||
assertTrue(flowExecution.isActive());
|
||||
flowExecution.signalEvent("finish", new MockExternalContext());
|
||||
assertFalse(flowExecution.isActive());
|
||||
}
|
||||
});
|
||||
state1.getTransitionSet().add(new Transition(toState("view")));
|
||||
|
||||
public void testLoopInFlowWithSubFlow() throws Exception {
|
||||
AbstractFlowBuilder childBuilder = new AbstractFlowBuilder() {
|
||||
public void buildStates() throws FlowBuilderException {
|
||||
addActionState("doOtherStuff", new AbstractAction() {
|
||||
private int executionCount = 0;
|
||||
|
||||
protected Event doExecute(RequestContext context) throws Exception {
|
||||
executionCount++;
|
||||
if (executionCount < 2) {
|
||||
return success();
|
||||
}
|
||||
return error();
|
||||
}
|
||||
},
|
||||
new Transition[] { transition(on(success()), to(finish())),
|
||||
transition(on(error()), to("stopTest")) });
|
||||
addEndState(finish());
|
||||
addEndState("stopTest");
|
||||
}
|
||||
};
|
||||
final Flow childFlow = new FlowAssembler("flow", childBuilder).assembleFlow();
|
||||
AbstractFlowBuilder parentBuilder = new AbstractFlowBuilder() {
|
||||
public void buildStates() throws FlowBuilderException {
|
||||
addActionState("doStuff", new AbstractAction() {
|
||||
protected Event doExecute(RequestContext context) throws Exception {
|
||||
return success();
|
||||
}
|
||||
}, transition(on(success()), to("startSubFlow")));
|
||||
addSubflowState("startSubFlow", childFlow, null, new Transition[] {
|
||||
transition(on(finish()), to("startSubFlow")), transition(on("stopTest"), to("stopTest")) });
|
||||
addEndState("stopTest");
|
||||
}
|
||||
};
|
||||
Flow parentFlow = new FlowAssembler("parentFlow", parentBuilder).assembleFlow();
|
||||
|
||||
FlowExecution flowExecution = new FlowExecutionImpl(parentFlow);
|
||||
flowExecution.start(null, new MockExternalContext());
|
||||
assertFalse(flowExecution.isActive());
|
||||
}
|
||||
|
||||
public void testExtensiveFlowNavigationScenario1() {
|
||||
XmlFlowBuilder builder = new XmlFlowBuilder(new ClassPathResource("testFlow1.xml", XmlFlowBuilderTests.class),
|
||||
new TestFlowServiceLocator());
|
||||
FlowAssembler assembler = new FlowAssembler("testFlow1", builder);
|
||||
FlowExecution execution = new FlowExecutionImpl(assembler.assembleFlow());
|
||||
MockExternalContext context = new MockExternalContext();
|
||||
execution.start(null, context);
|
||||
assertEquals("viewState1", execution.getActiveSession().getState().getId());
|
||||
assertNotNull(execution.getActiveSession().getScope().get("items"));
|
||||
execution.signalEvent("event1", context);
|
||||
assertTrue(!execution.isActive());
|
||||
}
|
||||
|
||||
public void testExtensiveFlowNavigationScenario2() {
|
||||
XmlFlowBuilder builder = new XmlFlowBuilder(new ClassPathResource("testFlow1.xml", XmlFlowBuilderTests.class),
|
||||
new TestFlowServiceLocator());
|
||||
LocalAttributeMap attributes = new LocalAttributeMap();
|
||||
attributes.put("scenario2", Boolean.TRUE);
|
||||
FlowAssembler assembler = new FlowAssembler("testFlow1", attributes, builder);
|
||||
FlowExecution execution = new FlowExecutionImpl(assembler.assembleFlow());
|
||||
MockExternalContext context = new MockExternalContext();
|
||||
execution.start(null, context);
|
||||
assertEquals("viewState2", execution.getActiveSession().getState().getId());
|
||||
assertNotNull(execution.getActiveSession().getScope().get("items"));
|
||||
execution.signalEvent("event2", context);
|
||||
assertTrue(!execution.isActive());
|
||||
}
|
||||
|
||||
public void testFlashScope() {
|
||||
FlowExecution execution = new FlowExecutionImpl(new FlashScopeFlow());
|
||||
MockExternalContext context = new MockExternalContext();
|
||||
execution.start(null, context);
|
||||
execution.refresh(context);
|
||||
execution.refresh(context);
|
||||
execution.signalEvent("view", context);
|
||||
}
|
||||
|
||||
public void testExceptionFromInputMapper() {
|
||||
FlowBuilder flowBuilder = new XmlFlowBuilder(new ClassPathResource("runtime-exception.xml",
|
||||
getClass()));
|
||||
Flow flow = new FlowAssembler("runtime-exception", flowBuilder).assembleFlow();
|
||||
FlowExecutionImpl flowExecution = new FlowExecutionImpl(flow);
|
||||
try {
|
||||
flowExecution.start(new LocalAttributeMap(), new MockExternalContext());
|
||||
fail("Should have thrown a FlowExecutionException, not any other type");
|
||||
} catch (FlowExecutionException e) {
|
||||
ViewState state2 = new ViewState(this, "view");
|
||||
state2.getEntryActionList().add(new Action() {
|
||||
public Event execute(RequestContext context) throws Exception {
|
||||
assertTrue(context.getFlashScope().contains("flashScopedValue"));
|
||||
return new Event(this, "success");
|
||||
}
|
||||
}
|
||||
|
||||
public void testExceptionWithListener() {
|
||||
FlowBuilder flowBuilder = new XmlFlowBuilder(new ClassPathResource("runtime-exception.xml",
|
||||
getClass()));
|
||||
Flow flow = new FlowAssembler("runtime-exception", flowBuilder).assembleFlow();
|
||||
FlowExceptionListener listener = new FlowExceptionListener();
|
||||
FlowExecutionImpl flowExecution = new FlowExecutionImpl(flow);
|
||||
flowExecution.setListeners(new FlowExecutionListeners(new FlowExecutionListener[] { listener }));
|
||||
try {
|
||||
flowExecution.start(new LocalAttributeMap(), new MockExternalContext());
|
||||
fail("Should have thrown a FlowExecutionException, not any other type");
|
||||
} catch (FlowExecutionException e) {
|
||||
});
|
||||
state2.getTransitionSet().add(new Transition(toState("end")));
|
||||
|
||||
EndState state3 = new EndState(this, "end");
|
||||
state3.getEntryActionList().add(new Action() {
|
||||
public Event execute(RequestContext context) throws Exception {
|
||||
assertFalse(context.getFlashScope().contains("flashScopedValue"));
|
||||
return new Event(this, "success");
|
||||
}
|
||||
|
||||
assertTrue("Listener should have been called on exception", listener.getExceptionFired());
|
||||
});
|
||||
}
|
||||
|
||||
public void testExceptionWithHandler() {
|
||||
FlowBuilder flowBuilder = new XmlFlowBuilder(new ClassPathResource("runtime-exception.xml",
|
||||
getClass()));
|
||||
Flow flow = new FlowAssembler("runtime-exception", flowBuilder).assembleFlow();
|
||||
FlowExceptionHandler handler = new FlowExceptionHandler();
|
||||
flow.getExceptionHandlerSet().add(handler);
|
||||
FlowExecutionImpl flowExecution = new FlowExecutionImpl(flow);
|
||||
flowExecution.start(new LocalAttributeMap(), new MockExternalContext());
|
||||
assertTrue("Handler should have been called on exception", handler.getExceptionHandled());
|
||||
}
|
||||
|
||||
private class FlowExceptionListener extends FlowExecutionListenerAdapter {
|
||||
|
||||
private boolean exceptionFired = false;
|
||||
|
||||
public boolean getExceptionFired() {
|
||||
return exceptionFired;
|
||||
}
|
||||
|
||||
public static TransitionCriteria onEvent(String event) {
|
||||
return new EventIdTransitionCriteria(event);
|
||||
public void exceptionThrown(RequestContext context, FlowExecutionException exception) {
|
||||
exceptionFired = true;
|
||||
}
|
||||
}
|
||||
|
||||
private class FlowExceptionHandler implements FlowExecutionExceptionHandler {
|
||||
|
||||
private boolean exceptionHandled = false;
|
||||
|
||||
public boolean getExceptionHandled() {
|
||||
return exceptionHandled;
|
||||
}
|
||||
|
||||
protected TargetStateResolver toState(String stateId) {
|
||||
return new DefaultTargetStateResolver(stateId);
|
||||
}
|
||||
|
||||
public static ViewSelector selectView(String viewName) {
|
||||
return new ApplicationViewSelector(new StaticExpression(viewName));
|
||||
public ViewSelection handle(FlowExecutionException exception, RequestControlContext context) {
|
||||
exceptionHandled = true;
|
||||
return ViewSelection.NULL_VIEW;
|
||||
}
|
||||
|
||||
private class FlashScopeFlow extends Flow {
|
||||
|
||||
public FlashScopeFlow() {
|
||||
super("flashScopeFlow");
|
||||
|
||||
ActionState state1 = new ActionState(this, "action");
|
||||
state1.getActionList().add(new Action() {
|
||||
public Event execute(RequestContext context) throws Exception {
|
||||
context.getFlashScope().put("flashScopedValue", "flashScopedValue");
|
||||
return new Event(this, "success");
|
||||
}
|
||||
});
|
||||
state1.getTransitionSet().add(new Transition(toState("view")));
|
||||
|
||||
ViewState state2 = new ViewState(this, "view");
|
||||
state2.getEntryActionList().add(new Action() {
|
||||
public Event execute(RequestContext context) throws Exception {
|
||||
assertTrue(context.getFlashScope().contains("flashScopedValue"));
|
||||
return new Event(this, "success");
|
||||
}
|
||||
});
|
||||
state2.getTransitionSet().add(new Transition(toState("end")));
|
||||
|
||||
EndState state3 = new EndState(this, "end");
|
||||
state3.getEntryActionList().add(new Action() {
|
||||
public Event execute(RequestContext context) throws Exception {
|
||||
assertFalse(context.getFlashScope().contains("flashScopedValue"));
|
||||
return new Event(this, "success");
|
||||
}
|
||||
});
|
||||
}
|
||||
public boolean handles(FlowExecutionException exception) {
|
||||
return true;
|
||||
}
|
||||
|
||||
private class FlowExceptionListener extends FlowExecutionListenerAdapter {
|
||||
|
||||
private boolean exceptionFired = false;
|
||||
|
||||
public boolean getExceptionFired() {
|
||||
return exceptionFired;
|
||||
}
|
||||
|
||||
public void exceptionThrown(RequestContext context, FlowExecutionException exception) {
|
||||
exceptionFired = true;
|
||||
}
|
||||
}
|
||||
|
||||
private class FlowExceptionHandler implements FlowExecutionExceptionHandler {
|
||||
|
||||
private boolean exceptionHandled = false;
|
||||
|
||||
public boolean getExceptionHandled() {
|
||||
return exceptionHandled;
|
||||
}
|
||||
|
||||
public ViewSelection handle(FlowExecutionException exception, RequestControlContext context) {
|
||||
exceptionHandled = true;
|
||||
return ViewSelection.NULL_VIEW;
|
||||
}
|
||||
|
||||
public boolean handles(FlowExecutionException exception) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,9 +13,9 @@
|
||||
<transition on-exception="org.springframework.webflow.engine.impl.FooException" to="fooException" />
|
||||
<transition on-exception="ognl.MethodFailedException" to="methodFailedException" />
|
||||
</action-state>
|
||||
|
||||
|
||||
<end-state id="fooException" view="showFooException" />
|
||||
|
||||
<end-state id="methodFailedException" view="showMethodFailedException" />
|
||||
|
||||
|
||||
</flow>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow xmlns="http://www.springframework.org/schema/webflow"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/webflow
|
||||
http://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">
|
||||
|
||||
<var name="flowAction" scope="flow" class="org.springframework.webflow.engine.impl.FooFlowAction" />
|
||||
|
||||
<start-state idref="action1" />
|
||||
|
||||
<action-state id="action1">
|
||||
<evaluate-action expression="flowScope.flowAction.action1()" />
|
||||
</action-state>
|
||||
|
||||
<end-state id="fooException" view="showFooException" />
|
||||
|
||||
<end-state id="methodFailedException" view="showMethodFailedException" />
|
||||
|
||||
<global-transitions>
|
||||
<transition on-exception="org.springframework.webflow.engine.impl.FooException" to="fooException" />
|
||||
</global-transitions>
|
||||
|
||||
</flow>
|
||||
@@ -74,7 +74,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
||||
assertSessionBound();
|
||||
|
||||
// Session created and bound to conversation
|
||||
final Session hibSession = (Session) context.getConversationScope().get("hibernate.session");
|
||||
final Session hibSession = (Session) context.getConversationScope().get("session");
|
||||
assertNotNull("Should have been populated", hibSession);
|
||||
listener.paused(context, ViewSelection.NULL_VIEW);
|
||||
assertSessionNotBound();
|
||||
@@ -212,6 +212,16 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
||||
|
||||
}
|
||||
|
||||
public void testExceptionThrownWithNothingBound() {
|
||||
assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
||||
MockRequestContext context = new MockRequestContext();
|
||||
MockFlowSession flowSession = new MockFlowSession();
|
||||
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
||||
assertSessionNotBound();
|
||||
listener.exceptionThrown(context, new FlowExecutionException("foo", "bar", "test"));
|
||||
assertSessionNotBound();
|
||||
}
|
||||
|
||||
private DataSource getDataSource() {
|
||||
DriverManagerDataSource dataSource = new DriverManagerDataSource();
|
||||
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
package org.springframework.webflow.support.persistence;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||
import org.springframework.orm.jpa.JpaTemplate;
|
||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
||||
import org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.webflow.engine.EndState;
|
||||
import org.springframework.webflow.test.MockFlowSession;
|
||||
import org.springframework.webflow.test.MockRequestContext;
|
||||
|
||||
public class JpaFlowExecutionListenerTests extends TestCase {
|
||||
|
||||
private EntityManagerFactory entityManagerFactory;
|
||||
|
||||
private JpaFlowExecutionListener jpaListener;
|
||||
|
||||
private JdbcTemplate jdbcTemplate;
|
||||
|
||||
private JpaTemplate jpaTemplate;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
DataSource dataSource = getDataSource();
|
||||
populateDataBase(dataSource);
|
||||
jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
entityManagerFactory = getEntityManagerFactory(dataSource);
|
||||
JpaTransactionManager tm = new JpaTransactionManager(entityManagerFactory);
|
||||
jpaListener = new JpaFlowExecutionListener(entityManagerFactory, tm);
|
||||
jpaTemplate = new JpaTemplate(entityManagerFactory);
|
||||
}
|
||||
|
||||
public void testFlowNotAPersistenceContext() {
|
||||
MockRequestContext context = new MockRequestContext();
|
||||
MockFlowSession flowSession = new MockFlowSession();
|
||||
jpaListener.sessionCreated(context, flowSession);
|
||||
assertSessionNotBound();
|
||||
}
|
||||
|
||||
public void testFlowCommitsInSingleRequest() {
|
||||
assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
||||
MockRequestContext context = new MockRequestContext();
|
||||
MockFlowSession flowSession = new MockFlowSession();
|
||||
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
||||
jpaListener.sessionCreated(context, flowSession);
|
||||
assertSessionBound();
|
||||
|
||||
TestBean bean = new TestBean(1, "Keith Donald");
|
||||
jpaTemplate.persist(bean);
|
||||
assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
||||
|
||||
EndState endState = new EndState(flowSession.getDefinitionInternal(), "success");
|
||||
endState.getAttributeMap().put("commit", Boolean.TRUE);
|
||||
flowSession.setState(endState);
|
||||
|
||||
jpaListener.sessionEnded(context, flowSession, null);
|
||||
assertEquals("Table should only have two rows", 2, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
||||
assertSessionNotBound();
|
||||
assertFalse(flowSession.getScope().contains("hibernate.session"));
|
||||
}
|
||||
|
||||
private DataSource getDataSource() {
|
||||
DriverManagerDataSource dataSource = new DriverManagerDataSource();
|
||||
dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
|
||||
dataSource.setUrl("jdbc:hsqldb:mem:jpa");
|
||||
dataSource.setUsername("sa");
|
||||
dataSource.setPassword("");
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
private void populateDataBase(DataSource dataSource) {
|
||||
Connection connection = null;
|
||||
try {
|
||||
connection = dataSource.getConnection();
|
||||
connection.createStatement().execute("drop table T_BEAN if exists;");
|
||||
connection.createStatement().execute(
|
||||
"create table T_BEAN (ID integer primary key, NAME varchar(50) not null);");
|
||||
connection.createStatement().execute("insert into T_BEAN (ID, NAME) values (0, 'Ben Hale');");
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("SQL exception occurred acquiring connection", e);
|
||||
} finally {
|
||||
if (connection != null) {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (SQLException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private EntityManagerFactory getEntityManagerFactory(DataSource dataSource) throws Exception {
|
||||
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
|
||||
factory.setDataSource(dataSource);
|
||||
factory.setPersistenceXmlLocation("classpath:org/springframework/webflow/support/persistence/persistence.xml");
|
||||
TopLinkJpaVendorAdapter toplink = new TopLinkJpaVendorAdapter();
|
||||
factory.setJpaVendorAdapter(toplink);
|
||||
factory.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
|
||||
factory.afterPropertiesSet();
|
||||
return (EntityManagerFactory) factory.getObject();
|
||||
}
|
||||
|
||||
private void assertSessionNotBound() {
|
||||
assertNull(TransactionSynchronizationManager.getResource(entityManagerFactory));
|
||||
}
|
||||
|
||||
private void assertSessionBound() {
|
||||
assertNotNull(TransactionSynchronizationManager.getResource(entityManagerFactory));
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
||||
|
||||
<hibernate-mapping package="org.springframework.webflow.support.persistence" default-access="field" default-lazy="false">
|
||||
<hibernate-mapping package="org.springframework.webflow.support.persistence" default-lazy="false">
|
||||
<class name="TestBean" table="T_BEAN">
|
||||
<id name="entityId" column="ID">
|
||||
<generator class="increment" />
|
||||
|
||||
@@ -17,14 +17,35 @@ package org.springframework.webflow.support.persistence;
|
||||
|
||||
public class TestBean {
|
||||
|
||||
private long entityId;
|
||||
private Long entityId;
|
||||
|
||||
private String name;
|
||||
|
||||
public TestBean() {
|
||||
|
||||
}
|
||||
|
||||
public TestBean(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public TestBean(long id, String name) {
|
||||
this.entityId = new Long(id);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getEntityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
public void setEntityId(Long entityId) {
|
||||
this.entityId = entityId;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<entity class="org.springframework.webflow.support.persistence.TestBean">
|
||||
<table name="T_BEAN"/>
|
||||
<attributes>
|
||||
<id name="entityId">
|
||||
<column name="ID"/>
|
||||
</id>
|
||||
<basic name="name">
|
||||
<column name="NAME"/>
|
||||
</basic>
|
||||
</attributes>
|
||||
</entity>
|
||||
|
||||
</entity-mappings>
|
||||
@@ -0,0 +1,16 @@
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
|
||||
<persistence-unit name="webflow" transaction-type="RESOURCE_LOCAL">
|
||||
|
||||
<!-- Explicitly define mapping file path,-->
|
||||
<mapping-file>org/springframework/webflow/support/persistence/orm.xml</mapping-file>
|
||||
|
||||
<!-- Prevent annotation scanning. In this app we are purely driven by orm.xml -->
|
||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||
|
||||
</persistence-unit>
|
||||
|
||||
</persistence>
|
||||
Reference in New Issue
Block a user