RESOLVED - issue SWF-92: Add Flow Managed Persistence Context Support for Hibernate and JPA
http://opensource.atlassian.com/projects/spring/browse/SWF-92
This commit is contained in:
@@ -2,7 +2,7 @@ SPRING WEB FLOW (SWF) CHANGELOG
|
|||||||
===============================
|
===============================
|
||||||
http://www.springframework.org/webflow
|
http://www.springframework.org/webflow
|
||||||
|
|
||||||
Changes in version 2.0-m1 (16.08.2007)
|
Changes in version 2.0 M1 (16.08.2007)
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
Package org.springframework.binding
|
Package org.springframework.binding
|
||||||
@@ -64,8 +64,8 @@ Package org.springframework.webflow.executor
|
|||||||
* JSF can now use a FlowSystemCleanupFilter to ensure that no matter what happens in JSF, the request context
|
* JSF can now use a FlowSystemCleanupFilter to ensure that no matter what happens in JSF, the request context
|
||||||
is cleaned up properly (SWF-306).
|
is cleaned up properly (SWF-306).
|
||||||
|
|
||||||
Package org.springframework.webflow.support
|
Package org.springframework.webflow.persistence
|
||||||
* Added native support for Hibernate's session-per-conversation pattern (SWF-92).
|
* Added support for Flow Managed Persistence Contexts with Hibernate and JPA (SWF-92).
|
||||||
|
|
||||||
Package org.springframework.webflow.test
|
Package org.springframework.webflow.test
|
||||||
* Added the ability to apply multiple listeners to a test case (SWF-334).
|
* Added the ability to apply multiple listeners to a test case (SWF-334).
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.webflow.support.persistence;
|
package org.springframework.webflow.persistence;
|
||||||
|
|
||||||
import org.hibernate.FlushMode;
|
import org.hibernate.FlushMode;
|
||||||
import org.hibernate.Interceptor;
|
import org.hibernate.Interceptor;
|
||||||
@@ -79,10 +79,10 @@ public class HibernateFlowExecutionListener extends FlowExecutionListenerAdapter
|
|||||||
|
|
||||||
private static final String HIBERNATE_SESSION_ATTRIBUTE = "session";
|
private static final String HIBERNATE_SESSION_ATTRIBUTE = "session";
|
||||||
|
|
||||||
private TransactionTemplate transactionTemplate;
|
|
||||||
|
|
||||||
private SessionFactory sessionFactory;
|
private SessionFactory sessionFactory;
|
||||||
|
|
||||||
|
private TransactionTemplate transactionTemplate;
|
||||||
|
|
||||||
private Interceptor entityInterceptor;
|
private Interceptor entityInterceptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,19 +107,19 @@ public class HibernateFlowExecutionListener extends FlowExecutionListenerAdapter
|
|||||||
if (isPersistenceContext(session.getDefinition())) {
|
if (isPersistenceContext(session.getDefinition())) {
|
||||||
Session hibernateSession = createSession(context);
|
Session hibernateSession = createSession(context);
|
||||||
session.getScope().put(HIBERNATE_SESSION_ATTRIBUTE, hibernateSession);
|
session.getScope().put(HIBERNATE_SESSION_ATTRIBUTE, hibernateSession);
|
||||||
bind(hibernateSession, context);
|
bind(hibernateSession);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resumed(RequestContext context) {
|
public void resumed(RequestContext context) {
|
||||||
if (isPersistenceContext(context.getActiveFlow())) {
|
if (isPersistenceContext(context.getActiveFlow())) {
|
||||||
bind(getHibernateSession(context), context);
|
bind(getHibernateSession(context));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void paused(RequestContext context, ViewSelection selectedView) {
|
public void paused(RequestContext context, ViewSelection selectedView) {
|
||||||
if (isPersistenceContext(context.getActiveFlow())) {
|
if (isPersistenceContext(context.getActiveFlow())) {
|
||||||
unbind(getHibernateSession(context), context);
|
unbind(getHibernateSession(context));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,14 +137,14 @@ public class HibernateFlowExecutionListener extends FlowExecutionListenerAdapter
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
unbind(hibernateSession, context);
|
unbind(hibernateSession);
|
||||||
hibernateSession.close();
|
hibernateSession.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exceptionThrown(RequestContext context, FlowExecutionException exception) {
|
public void exceptionThrown(RequestContext context, FlowExecutionException exception) {
|
||||||
if (isPersistenceContext(context.getActiveFlow())) {
|
if (isPersistenceContext(context.getActiveFlow())) {
|
||||||
unbind(getHibernateSession(context), context);
|
unbind(getHibernateSession(context));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,11 +165,11 @@ public class HibernateFlowExecutionListener extends FlowExecutionListenerAdapter
|
|||||||
return (Session) context.getFlowScope().get(HIBERNATE_SESSION_ATTRIBUTE);
|
return (Session) context.getFlowScope().get(HIBERNATE_SESSION_ATTRIBUTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bind(Session session, RequestContext context) {
|
private void bind(Session session) {
|
||||||
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
|
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unbind(Session session, RequestContext context) {
|
private void unbind(Session session) {
|
||||||
if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
|
if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
|
||||||
TransactionSynchronizationManager.unbindResource(sessionFactory);
|
TransactionSynchronizationManager.unbindResource(sessionFactory);
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.webflow.support.persistence;
|
package org.springframework.webflow.persistence;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.EntityManagerFactory;
|
import javax.persistence.EntityManagerFactory;
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.webflow.support.persistence;
|
package org.springframework.webflow.persistence;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@@ -54,7 +54,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
|||||||
|
|
||||||
private HibernateTemplate hibernateTemplate;
|
private HibernateTemplate hibernateTemplate;
|
||||||
|
|
||||||
private HibernateFlowExecutionListener listener;
|
private HibernateFlowExecutionListener hibernateListener;
|
||||||
|
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
DataSource dataSource = getDataSource();
|
DataSource dataSource = getDataSource();
|
||||||
@@ -64,25 +64,25 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
|||||||
hibernateTemplate = new HibernateTemplate(sessionFactory);
|
hibernateTemplate = new HibernateTemplate(sessionFactory);
|
||||||
hibernateTemplate.setCheckWriteOperations(false);
|
hibernateTemplate.setCheckWriteOperations(false);
|
||||||
HibernateTransactionManager tm = new HibernateTransactionManager(sessionFactory);
|
HibernateTransactionManager tm = new HibernateTransactionManager(sessionFactory);
|
||||||
listener = new HibernateFlowExecutionListener(sessionFactory, tm);
|
hibernateListener = new HibernateFlowExecutionListener(sessionFactory, tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSameSession() {
|
public void testSameSession() {
|
||||||
MockRequestContext context = new MockRequestContext();
|
MockRequestContext context = new MockRequestContext();
|
||||||
MockFlowSession flowSession = new MockFlowSession();
|
MockFlowSession flowSession = new MockFlowSession();
|
||||||
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
||||||
listener.sessionCreated(context, flowSession);
|
hibernateListener.sessionCreated(context, flowSession);
|
||||||
context.setActiveSession(flowSession);
|
context.setActiveSession(flowSession);
|
||||||
assertSessionBound();
|
assertSessionBound();
|
||||||
|
|
||||||
// Session created and bound to conversation
|
// Session created and bound to conversation
|
||||||
final Session hibSession = (Session) flowSession.getScope().get("session");
|
final Session hibSession = (Session) flowSession.getScope().get("session");
|
||||||
assertNotNull("Should have been populated", hibSession);
|
assertNotNull("Should have been populated", hibSession);
|
||||||
listener.paused(context, ViewSelection.NULL_VIEW);
|
hibernateListener.paused(context, ViewSelection.NULL_VIEW);
|
||||||
assertSessionNotBound();
|
assertSessionNotBound();
|
||||||
|
|
||||||
// Session bound to thread local variable
|
// Session bound to thread local variable
|
||||||
listener.resumed(context);
|
hibernateListener.resumed(context);
|
||||||
assertSessionBound();
|
assertSessionBound();
|
||||||
|
|
||||||
hibernateTemplate.execute(new HibernateCallback() {
|
hibernateTemplate.execute(new HibernateCallback() {
|
||||||
@@ -91,14 +91,14 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
listener.paused(context, ViewSelection.NULL_VIEW);
|
hibernateListener.paused(context, ViewSelection.NULL_VIEW);
|
||||||
assertSessionNotBound();
|
assertSessionNotBound();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testFlowNotAPersistenceContext() {
|
public void testFlowNotAPersistenceContext() {
|
||||||
MockRequestContext context = new MockRequestContext();
|
MockRequestContext context = new MockRequestContext();
|
||||||
MockFlowSession flowSession = new MockFlowSession();
|
MockFlowSession flowSession = new MockFlowSession();
|
||||||
listener.sessionCreated(context, flowSession);
|
hibernateListener.sessionCreated(context, flowSession);
|
||||||
assertSessionNotBound();
|
assertSessionNotBound();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
|||||||
MockRequestContext context = new MockRequestContext();
|
MockRequestContext context = new MockRequestContext();
|
||||||
MockFlowSession flowSession = new MockFlowSession();
|
MockFlowSession flowSession = new MockFlowSession();
|
||||||
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
||||||
listener.sessionCreated(context, flowSession);
|
hibernateListener.sessionCreated(context, flowSession);
|
||||||
context.setActiveSession(flowSession);
|
context.setActiveSession(flowSession);
|
||||||
assertSessionBound();
|
assertSessionBound();
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
|||||||
endState.getAttributeMap().put("commit", Boolean.TRUE);
|
endState.getAttributeMap().put("commit", Boolean.TRUE);
|
||||||
flowSession.setState(endState);
|
flowSession.setState(endState);
|
||||||
|
|
||||||
listener.sessionEnded(context, flowSession, null);
|
hibernateListener.sessionEnded(context, flowSession, null);
|
||||||
assertEquals("Table should only have two rows", 2, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
assertEquals("Table should only have two rows", 2, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
||||||
assertSessionNotBound();
|
assertSessionNotBound();
|
||||||
assertFalse(flowSession.getScope().contains("hibernate.session"));
|
assertFalse(flowSession.getScope().contains("hibernate.session"));
|
||||||
@@ -130,17 +130,17 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
|||||||
MockRequestContext context = new MockRequestContext();
|
MockRequestContext context = new MockRequestContext();
|
||||||
MockFlowSession flowSession = new MockFlowSession();
|
MockFlowSession flowSession = new MockFlowSession();
|
||||||
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
||||||
listener.sessionCreated(context, flowSession);
|
hibernateListener.sessionCreated(context, flowSession);
|
||||||
context.setActiveSession(flowSession);
|
context.setActiveSession(flowSession);
|
||||||
assertSessionBound();
|
assertSessionBound();
|
||||||
|
|
||||||
TestBean bean1 = new TestBean("Keith Donald");
|
TestBean bean1 = new TestBean("Keith Donald");
|
||||||
hibernateTemplate.save(bean1);
|
hibernateTemplate.save(bean1);
|
||||||
assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
||||||
listener.paused(context, ViewSelection.NULL_VIEW);
|
hibernateListener.paused(context, ViewSelection.NULL_VIEW);
|
||||||
assertSessionNotBound();
|
assertSessionNotBound();
|
||||||
|
|
||||||
listener.resumed(context);
|
hibernateListener.resumed(context);
|
||||||
TestBean bean2 = new TestBean("Keith Donald");
|
TestBean bean2 = new TestBean("Keith Donald");
|
||||||
hibernateTemplate.save(bean2);
|
hibernateTemplate.save(bean2);
|
||||||
assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
||||||
@@ -150,7 +150,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
|||||||
endState.getAttributeMap().put("commit", Boolean.TRUE);
|
endState.getAttributeMap().put("commit", Boolean.TRUE);
|
||||||
flowSession.setState(endState);
|
flowSession.setState(endState);
|
||||||
|
|
||||||
listener.sessionEnded(context, flowSession, null);
|
hibernateListener.sessionEnded(context, flowSession, null);
|
||||||
assertEquals("Table should only have three rows", 3, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
assertEquals("Table should only have three rows", 3, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
||||||
assertFalse(flowSession.getScope().contains("hibernate.session"));
|
assertFalse(flowSession.getScope().contains("hibernate.session"));
|
||||||
|
|
||||||
@@ -164,7 +164,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
|||||||
MockRequestContext context = new MockRequestContext();
|
MockRequestContext context = new MockRequestContext();
|
||||||
MockFlowSession flowSession = new MockFlowSession();
|
MockFlowSession flowSession = new MockFlowSession();
|
||||||
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
||||||
listener.sessionCreated(context, flowSession);
|
hibernateListener.sessionCreated(context, flowSession);
|
||||||
context.setActiveSession(flowSession);
|
context.setActiveSession(flowSession);
|
||||||
assertSessionBound();
|
assertSessionBound();
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
|||||||
EndState endState = new EndState(flowSession.getDefinitionInternal(), "cancel");
|
EndState endState = new EndState(flowSession.getDefinitionInternal(), "cancel");
|
||||||
endState.getAttributeMap().put("commit", Boolean.FALSE);
|
endState.getAttributeMap().put("commit", Boolean.FALSE);
|
||||||
flowSession.setState(endState);
|
flowSession.setState(endState);
|
||||||
listener.sessionEnded(context, flowSession, null);
|
hibernateListener.sessionEnded(context, flowSession, null);
|
||||||
assertEquals("Table should only have two rows", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
assertEquals("Table should only have two rows", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
||||||
assertSessionNotBound();
|
assertSessionNotBound();
|
||||||
assertFalse(flowSession.getScope().contains("hibernate.session"));
|
assertFalse(flowSession.getScope().contains("hibernate.session"));
|
||||||
@@ -186,14 +186,14 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
|||||||
MockRequestContext context = new MockRequestContext();
|
MockRequestContext context = new MockRequestContext();
|
||||||
MockFlowSession flowSession = new MockFlowSession();
|
MockFlowSession flowSession = new MockFlowSession();
|
||||||
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
||||||
listener.sessionCreated(context, flowSession);
|
hibernateListener.sessionCreated(context, flowSession);
|
||||||
context.setActiveSession(flowSession);
|
context.setActiveSession(flowSession);
|
||||||
assertSessionBound();
|
assertSessionBound();
|
||||||
|
|
||||||
EndState endState = new EndState(flowSession.getDefinitionInternal(), "cancel");
|
EndState endState = new EndState(flowSession.getDefinitionInternal(), "cancel");
|
||||||
flowSession.setState(endState);
|
flowSession.setState(endState);
|
||||||
|
|
||||||
listener.sessionEnded(context, flowSession, null);
|
hibernateListener.sessionEnded(context, flowSession, null);
|
||||||
assertEquals("Table should only have three rows", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
assertEquals("Table should only have three rows", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
||||||
assertFalse(flowSession.getScope().contains("hibernate.session"));
|
assertFalse(flowSession.getScope().contains("hibernate.session"));
|
||||||
|
|
||||||
@@ -206,14 +206,14 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
|||||||
MockRequestContext context = new MockRequestContext();
|
MockRequestContext context = new MockRequestContext();
|
||||||
MockFlowSession flowSession = new MockFlowSession();
|
MockFlowSession flowSession = new MockFlowSession();
|
||||||
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
||||||
listener.sessionCreated(context, flowSession);
|
hibernateListener.sessionCreated(context, flowSession);
|
||||||
context.setActiveSession(flowSession);
|
context.setActiveSession(flowSession);
|
||||||
assertSessionBound();
|
assertSessionBound();
|
||||||
|
|
||||||
TestBean bean1 = new TestBean("Keith Donald");
|
TestBean bean1 = new TestBean("Keith Donald");
|
||||||
hibernateTemplate.save(bean1);
|
hibernateTemplate.save(bean1);
|
||||||
assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
||||||
listener.exceptionThrown(context, new FlowExecutionException("bla", "bla", "bla"));
|
hibernateListener.exceptionThrown(context, new FlowExecutionException("bla", "bla", "bla"));
|
||||||
assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
||||||
assertSessionNotBound();
|
assertSessionNotBound();
|
||||||
|
|
||||||
@@ -225,7 +225,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
|||||||
MockFlowSession flowSession = new MockFlowSession();
|
MockFlowSession flowSession = new MockFlowSession();
|
||||||
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
||||||
assertSessionNotBound();
|
assertSessionNotBound();
|
||||||
listener.exceptionThrown(context, new FlowExecutionException("foo", "bar", "test"));
|
hibernateListener.exceptionThrown(context, new FlowExecutionException("foo", "bar", "test"));
|
||||||
assertSessionNotBound();
|
assertSessionNotBound();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,13 +233,13 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
|||||||
MockRequestContext context = new MockRequestContext();
|
MockRequestContext context = new MockRequestContext();
|
||||||
MockFlowSession flowSession = new MockFlowSession();
|
MockFlowSession flowSession = new MockFlowSession();
|
||||||
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
flowSession.getDefinitionInternal().getAttributeMap().put("persistenceContext", "true");
|
||||||
listener.sessionCreated(context, flowSession);
|
hibernateListener.sessionCreated(context, flowSession);
|
||||||
context.setActiveSession(flowSession);
|
context.setActiveSession(flowSession);
|
||||||
assertSessionBound();
|
assertSessionBound();
|
||||||
|
|
||||||
TestBean bean = (TestBean) hibernateTemplate.get(TestBean.class, Long.valueOf(0));
|
TestBean bean = (TestBean) hibernateTemplate.get(TestBean.class, Long.valueOf(0));
|
||||||
assertFalse("addresses should not be initialized", Hibernate.isInitialized(bean.getAddresses()));
|
assertFalse("addresses should not be initialized", Hibernate.isInitialized(bean.getAddresses()));
|
||||||
listener.paused(context, ViewSelection.NULL_VIEW);
|
hibernateListener.paused(context, ViewSelection.NULL_VIEW);
|
||||||
assertFalse("addresses should not be initialized", Hibernate.isInitialized(bean.getAddresses()));
|
assertFalse("addresses should not be initialized", Hibernate.isInitialized(bean.getAddresses()));
|
||||||
Hibernate.initialize(bean.getAddresses());
|
Hibernate.initialize(bean.getAddresses());
|
||||||
assertTrue("addresses should be initialized", Hibernate.isInitialized(bean.getAddresses()));
|
assertTrue("addresses should be initialized", Hibernate.isInitialized(bean.getAddresses()));
|
||||||
@@ -287,8 +287,8 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
|||||||
LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
|
LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
|
||||||
factory.setDataSource(dataSource);
|
factory.setDataSource(dataSource);
|
||||||
factory.setMappingLocations(new Resource[] {
|
factory.setMappingLocations(new Resource[] {
|
||||||
new ClassPathResource("org/springframework/webflow/support/persistence/TestBean.hbm.xml"),
|
new ClassPathResource("org/springframework/webflow/persistence/TestBean.hbm.xml"),
|
||||||
new ClassPathResource("org/springframework/webflow/support/persistence/TestAddress.hbm.xml") });
|
new ClassPathResource("org/springframework/webflow/persistence/TestAddress.hbm.xml") });
|
||||||
factory.afterPropertiesSet();
|
factory.afterPropertiesSet();
|
||||||
return (SessionFactory) factory.getObject();
|
return (SessionFactory) factory.getObject();
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.springframework.webflow.support.persistence;
|
package org.springframework.webflow.persistence;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@@ -17,6 +17,7 @@ import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
|
|||||||
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
import org.springframework.webflow.engine.EndState;
|
import org.springframework.webflow.engine.EndState;
|
||||||
|
import org.springframework.webflow.execution.FlowExecutionException;
|
||||||
import org.springframework.webflow.execution.ViewSelection;
|
import org.springframework.webflow.execution.ViewSelection;
|
||||||
import org.springframework.webflow.test.MockFlowSession;
|
import org.springframework.webflow.test.MockFlowSession;
|
||||||
import org.springframework.webflow.test.MockRequestContext;
|
import org.springframework.webflow.test.MockRequestContext;
|
||||||
@@ -106,7 +107,76 @@ public class JpaFlowExecutionListenerTests extends TestCase {
|
|||||||
|
|
||||||
assertSessionNotBound();
|
assertSessionNotBound();
|
||||||
assertFalse(flowSession.getScope().contains("hibernate.session"));
|
assertFalse(flowSession.getScope().contains("hibernate.session"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCancelEndState() {
|
||||||
|
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);
|
||||||
|
context.setActiveSession(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(), "cancel");
|
||||||
|
endState.getAttributeMap().put("commit", Boolean.FALSE);
|
||||||
|
flowSession.setState(endState);
|
||||||
|
jpaListener.sessionEnded(context, flowSession, null);
|
||||||
|
assertEquals("Table should only have two rows", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
||||||
|
assertSessionNotBound();
|
||||||
|
assertFalse(flowSession.getScope().contains("hibernate.session"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNoCommitAttributeSetOnEndState() {
|
||||||
|
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);
|
||||||
|
context.setActiveSession(flowSession);
|
||||||
|
assertSessionBound();
|
||||||
|
|
||||||
|
EndState endState = new EndState(flowSession.getDefinitionInternal(), "cancel");
|
||||||
|
flowSession.setState(endState);
|
||||||
|
|
||||||
|
jpaListener.sessionEnded(context, flowSession, null);
|
||||||
|
assertEquals("Table should only have three rows", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
||||||
|
assertFalse(flowSession.getScope().contains("hibernate.session"));
|
||||||
|
|
||||||
|
assertSessionNotBound();
|
||||||
|
assertFalse(flowSession.getScope().contains("hibernate.session"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testExceptionThrown() {
|
||||||
|
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);
|
||||||
|
context.setActiveSession(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"));
|
||||||
|
jpaListener.exceptionThrown(context, new FlowExecutionException("bla", "bla", "bla"));
|
||||||
|
assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
|
||||||
|
assertSessionNotBound();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
jpaListener.exceptionThrown(context, new FlowExecutionException("foo", "bar", "test"));
|
||||||
|
assertSessionNotBound();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testLazilyInitalizedCollection() {
|
public void testLazilyInitalizedCollection() {
|
||||||
@@ -166,7 +236,7 @@ public class JpaFlowExecutionListenerTests extends TestCase {
|
|||||||
private EntityManagerFactory getEntityManagerFactory(DataSource dataSource) throws Exception {
|
private EntityManagerFactory getEntityManagerFactory(DataSource dataSource) throws Exception {
|
||||||
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
|
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
|
||||||
factory.setDataSource(dataSource);
|
factory.setDataSource(dataSource);
|
||||||
factory.setPersistenceXmlLocation("classpath:org/springframework/webflow/support/persistence/persistence.xml");
|
factory.setPersistenceXmlLocation("classpath:org/springframework/webflow/persistence/persistence.xml");
|
||||||
HibernateJpaVendorAdapter hibernate = new HibernateJpaVendorAdapter();
|
HibernateJpaVendorAdapter hibernate = new HibernateJpaVendorAdapter();
|
||||||
factory.setJpaVendorAdapter(hibernate);
|
factory.setJpaVendorAdapter(hibernate);
|
||||||
factory.afterPropertiesSet();
|
factory.afterPropertiesSet();
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||||
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
||||||
|
|
||||||
<hibernate-mapping package="org.springframework.webflow.support.persistence" default-lazy="false">
|
<hibernate-mapping package="org.springframework.webflow.persistence" default-lazy="false">
|
||||||
<class name="TestAddress" table="T_ADDRESS">
|
<class name="TestAddress" table="T_ADDRESS">
|
||||||
<id name="entityId" column="ID">
|
<id name="entityId" column="ID">
|
||||||
<generator class="increment" />
|
<generator class="increment" />
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.springframework.webflow.support.persistence;
|
package org.springframework.webflow.persistence;
|
||||||
|
|
||||||
public class TestAddress {
|
public class TestAddress {
|
||||||
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||||
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
||||||
|
|
||||||
<hibernate-mapping package="org.springframework.webflow.support.persistence" default-lazy="false">
|
<hibernate-mapping package="org.springframework.webflow.persistence" default-lazy="false">
|
||||||
<class name="TestBean" table="T_BEAN">
|
<class name="TestBean" table="T_BEAN">
|
||||||
<id name="entityId" column="ID">
|
<id name="entityId" column="ID">
|
||||||
<generator class="increment" />
|
<generator class="increment" />
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.springframework.webflow.support.persistence;
|
package org.springframework.webflow.persistence;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
|
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
|
||||||
version="1.0">
|
version="1.0">
|
||||||
|
|
||||||
<package>org.springframework.webflow.support.persistence</package>
|
<package>org.springframework.webflow.persistence</package>
|
||||||
|
|
||||||
|
|
||||||
<entity class="TestBean">
|
<entity class="TestBean">
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
<persistence-unit name="webflow" transaction-type="RESOURCE_LOCAL">
|
<persistence-unit name="webflow" transaction-type="RESOURCE_LOCAL">
|
||||||
|
|
||||||
<!-- Explicitly define mapping file path,-->
|
<!-- Explicitly define mapping file path,-->
|
||||||
<mapping-file>org/springframework/webflow/support/persistence/orm.xml</mapping-file>
|
<mapping-file>org/springframework/webflow/persistence/orm.xml</mapping-file>
|
||||||
|
|
||||||
<!-- Prevent annotation scanning. In this app we are purely driven by orm.xml -->
|
<!-- Prevent annotation scanning. In this app we are purely driven by orm.xml -->
|
||||||
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
<exclude-unlisted-classes>true</exclude-unlisted-classes>
|
||||||
Reference in New Issue
Block a user