Upgrade to Hibernate 4
This change upgrades Spring Web Flow to Hibernate 4 but remains compatible with Hibernate 3. Issue: SWF-1534
This commit is contained in:
18
build.gradle
18
build.gradle
@@ -56,7 +56,7 @@ configure(subprojects.findAll {it.name != "spring-js-resources"}) { subproject -
|
|||||||
}
|
}
|
||||||
|
|
||||||
subproject.ext {
|
subproject.ext {
|
||||||
springVersion = "4.0.0.RELEASE"
|
springVersion = "4.0.1.RELEASE"
|
||||||
springSecurityVersion = "3.2.0.RELEASE"
|
springSecurityVersion = "3.2.0.RELEASE"
|
||||||
slf4jVersion = "1.6.1"
|
slf4jVersion = "1.6.1"
|
||||||
log4jVersion = "1.2.15"
|
log4jVersion = "1.2.15"
|
||||||
@@ -132,10 +132,10 @@ project("spring-js") {
|
|||||||
compile("org.springframework:spring-web:$springVersion")
|
compile("org.springframework:spring-web:$springVersion")
|
||||||
compile("org.springframework:spring-webmvc:$springVersion")
|
compile("org.springframework:spring-webmvc:$springVersion")
|
||||||
provided("javax.servlet:javax.servlet-api:3.0.1")
|
provided("javax.servlet:javax.servlet-api:3.0.1")
|
||||||
optional("org.apache.tiles:tiles-api:2.1.2")
|
optional("org.apache.tiles:tiles-api:2.2.2")
|
||||||
optional("org.apache.tiles:tiles-core:2.1.2")
|
optional("org.apache.tiles:tiles-core:2.2.2")
|
||||||
optional("org.apache.tiles:tiles-jsp:2.1.2")
|
optional("org.apache.tiles:tiles-jsp:2.2.2")
|
||||||
optional("org.apache.tiles:tiles-servlet:2.1.2")
|
optional("org.apache.tiles:tiles-servlet:2.2.2")
|
||||||
testCompile("javax.servlet:jstl:1.2")
|
testCompile("javax.servlet:jstl:1.2")
|
||||||
testCompile("log4j:log4j:$log4jVersion") {
|
testCompile("log4j:log4j:$log4jVersion") {
|
||||||
exclude group: "javax.mail", module: "mail"
|
exclude group: "javax.mail", module: "mail"
|
||||||
@@ -143,6 +143,8 @@ project("spring-js") {
|
|||||||
exclude group: "com.sun.jdmk", module: "jmxtools"
|
exclude group: "com.sun.jdmk", module: "jmxtools"
|
||||||
exclude group: "com.sun.jmx", module: "jmxri"
|
exclude group: "com.sun.jmx", module: "jmxri"
|
||||||
}
|
}
|
||||||
|
testCompile("org.slf4j:jcl-over-slf4j:$slf4jVersion")
|
||||||
|
testCompile("org.slf4j:slf4j-api:$slf4jVersion")
|
||||||
testCompile("org.springframework:spring-test:$springVersion")
|
testCompile("org.springframework:spring-test:$springVersion")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -166,7 +168,7 @@ project("spring-webflow") {
|
|||||||
provided("javax.portlet:portlet-api:2.0")
|
provided("javax.portlet:portlet-api:2.0")
|
||||||
provided("junit:junit:3.8.2")
|
provided("junit:junit:3.8.2")
|
||||||
provided("org.eclipse.persistence:javax.persistence:2.0.0")
|
provided("org.eclipse.persistence:javax.persistence:2.0.0")
|
||||||
optional("org.hibernate:hibernate-core:3.6.9.Final") {
|
optional("org.hibernate:hibernate-core:4.2.8.Final") {
|
||||||
exclude group: "org.slf4j", module: "slf4j-api"
|
exclude group: "org.slf4j", module: "slf4j-api"
|
||||||
}
|
}
|
||||||
optional("org.slf4j:slf4j-api:$slf4jVersion")
|
optional("org.slf4j:slf4j-api:$slf4jVersion")
|
||||||
@@ -175,8 +177,8 @@ project("spring-webflow") {
|
|||||||
optional("org.springframework:spring-tx:$springVersion")
|
optional("org.springframework:spring-tx:$springVersion")
|
||||||
optional("org.springframework:spring-webmvc-portlet:$springVersion")
|
optional("org.springframework:spring-webmvc-portlet:$springVersion")
|
||||||
testCompile("javax.validation:validation-api:1.0.0.GA")
|
testCompile("javax.validation:validation-api:1.0.0.GA")
|
||||||
testCompile("org.hibernate:hibernate-core:3.6.9.Final")
|
testCompile("org.hibernate:hibernate-core:4.2.8.Final")
|
||||||
testCompile("org.hibernate:hibernate-entitymanager:3.6.9.Final")
|
testCompile("org.hibernate:hibernate-entitymanager:4.2.8.Final")
|
||||||
testCompile("org.hibernate:hibernate-validator:4.3.0.Final")
|
testCompile("org.hibernate:hibernate-validator:4.3.0.Final")
|
||||||
testCompile("org.apache.tomcat:tomcat-jasper-el:7.0.27")
|
testCompile("org.apache.tomcat:tomcat-jasper-el:7.0.27")
|
||||||
testCompile("org.hsqldb:hsqldb:2.2.8")
|
testCompile("org.hsqldb:hsqldb:2.2.8")
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2012 the original author or authors.
|
* Copyright 2004-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,16 +15,21 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.webflow.persistence;
|
package org.springframework.webflow.persistence;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import org.hibernate.FlushMode;
|
import org.hibernate.FlushMode;
|
||||||
import org.hibernate.Interceptor;
|
import org.hibernate.Interceptor;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
import org.springframework.orm.hibernate3.SessionHolder;
|
import org.springframework.orm.hibernate4.SessionHolder;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.TransactionStatus;
|
import org.springframework.transaction.TransactionStatus;
|
||||||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
import org.springframework.transaction.support.TransactionTemplate;
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.util.ReflectionUtils;
|
||||||
import org.springframework.webflow.core.collection.AttributeMap;
|
import org.springframework.webflow.core.collection.AttributeMap;
|
||||||
import org.springframework.webflow.core.collection.MutableAttributeMap;
|
import org.springframework.webflow.core.collection.MutableAttributeMap;
|
||||||
import org.springframework.webflow.definition.FlowDefinition;
|
import org.springframework.webflow.definition.FlowDefinition;
|
||||||
@@ -48,7 +53,7 @@ import org.springframework.webflow.execution.RequestContext;
|
|||||||
* <li>When an existing flow ends, commit the changes made to the session in a transaction if the ending state is a
|
* <li>When an existing flow ends, commit the changes made to the session in a transaction if the ending state is a
|
||||||
* commit state. Then, unbind the context and close it.
|
* commit state. Then, unbind the context and close it.
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* The general data access pattern implemented here is:
|
* The general data access pattern implemented here is:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Create a new persistence context when a new flow execution with the 'persistenceContext' attribute starts
|
* <li>Create a new persistence context when a new flow execution with the 'persistenceContext' attribute starts
|
||||||
@@ -57,7 +62,7 @@ import org.springframework.webflow.execution.RequestContext;
|
|||||||
* <li>On successful flow completion, commit and flush those edits to the database, applying a version check if
|
* <li>On successful flow completion, commit and flush those edits to the database, applying a version check if
|
||||||
* necessary.
|
* necessary.
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Note: All data access except for the final commit will, by default, be non-transactional. However, a flow may call
|
* Note: All data access except for the final commit will, by default, be non-transactional. However, a flow may call
|
||||||
* into a transactional service layer to fetch objects during the conversation in the context of a read-only system
|
* into a transactional service layer to fetch objects during the conversation in the context of a read-only system
|
||||||
@@ -68,13 +73,23 @@ import org.springframework.webflow.execution.RequestContext;
|
|||||||
* want intermediate flushing to happen, as the nature of a flow implies a transient, isolated resource that can be
|
* want intermediate flushing to happen, as the nature of a flow implies a transient, isolated resource that can be
|
||||||
* canceled before it ends. Generally, the only time a read-write transaction should be started is upon successful
|
* canceled before it ends. Generally, the only time a read-write transaction should be started is upon successful
|
||||||
* completion of the conversation, triggered by reaching a 'commit' end state.
|
* completion of the conversation, triggered by reaching a 'commit' end state.
|
||||||
*
|
*
|
||||||
* @author Keith Donald
|
* @author Keith Donald
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Ben Hale
|
* @author Ben Hale
|
||||||
*/
|
*/
|
||||||
public class HibernateFlowExecutionListener extends FlowExecutionListenerAdapter {
|
public class HibernateFlowExecutionListener extends FlowExecutionListenerAdapter {
|
||||||
|
|
||||||
|
private static final boolean hibernate3Present = ClassUtils.isPresent("org.hibernate.connection.ConnectionProvider",
|
||||||
|
HibernateFlowExecutionListener.class.getClassLoader());
|
||||||
|
|
||||||
|
private static final Method openSessionMethod =
|
||||||
|
ReflectionUtils.findMethod(SessionFactory.class, "openSession");
|
||||||
|
|
||||||
|
private static final Method openSessionWithInterceptorMethod =
|
||||||
|
ReflectionUtils.findMethod(SessionFactory.class, "openSession", Interceptor.class);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the attribute the flow {@link Session persistence context} is indexed under.
|
* The name of the attribute the flow {@link Session persistence context} is indexed under.
|
||||||
*/
|
*/
|
||||||
@@ -183,8 +198,33 @@ public class HibernateFlowExecutionListener extends FlowExecutionListenerAdapter
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Session createSession(RequestContext context) {
|
private Session createSession(RequestContext context) {
|
||||||
Session session = (entityInterceptor != null ? sessionFactory.openSession(entityInterceptor) : sessionFactory
|
Session session;
|
||||||
.openSession());
|
if (entityInterceptor != null) {
|
||||||
|
if (hibernate3Present) {
|
||||||
|
try {
|
||||||
|
session = (Session) openSessionWithInterceptorMethod.invoke(sessionFactory, entityInterceptor);
|
||||||
|
} catch (IllegalAccessException ex) {
|
||||||
|
throw new IllegalStateException("Unable to open Hibernate 3 session", ex);
|
||||||
|
} catch (InvocationTargetException ex) {
|
||||||
|
throw new IllegalStateException("Unable to open Hibernate 3 session", ex);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
session = sessionFactory.withOptions().interceptor(entityInterceptor).openSession();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (hibernate3Present) {
|
||||||
|
try {
|
||||||
|
session = (Session) openSessionMethod.invoke(sessionFactory);
|
||||||
|
} catch (IllegalAccessException ex) {
|
||||||
|
throw new IllegalStateException("Unable to open Hibernate 3 session", ex);
|
||||||
|
} catch (InvocationTargetException ex) {
|
||||||
|
throw new IllegalStateException("Unable to open Hibernate 3 session", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
session = sessionFactory.openSession();
|
||||||
|
}
|
||||||
|
}
|
||||||
session.setFlushMode(FlushMode.MANUAL);
|
session.setFlushMode(FlushMode.MANUAL);
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
@@ -198,7 +238,9 @@ public class HibernateFlowExecutionListener extends FlowExecutionListenerAdapter
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void bind(Session session) {
|
private void bind(Session session) {
|
||||||
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
|
Object sessionHolder = (hibernate3Present ?
|
||||||
|
new org.springframework.orm.hibernate3.SessionHolder(session) : new SessionHolder(session));
|
||||||
|
TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unbind(Session session) {
|
private void unbind(Session session) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2004-2012 the original author or authors.
|
* Copyright 2004-2014 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -15,14 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.webflow.persistence;
|
package org.springframework.webflow.persistence;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.hibernate.Hibernate;
|
import org.hibernate.Hibernate;
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
@@ -31,10 +28,10 @@ import org.springframework.jdbc.core.JdbcTemplate;
|
|||||||
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
import org.springframework.jdbc.datasource.DriverManagerDataSource;
|
||||||
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
|
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
|
||||||
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
|
||||||
import org.springframework.orm.hibernate3.HibernateCallback;
|
import org.springframework.orm.hibernate4.HibernateCallback;
|
||||||
import org.springframework.orm.hibernate3.HibernateTemplate;
|
import org.springframework.orm.hibernate4.HibernateTemplate;
|
||||||
import org.springframework.orm.hibernate3.HibernateTransactionManager;
|
import org.springframework.orm.hibernate4.HibernateTransactionManager;
|
||||||
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
|
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
|
||||||
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.FlowExecutionException;
|
||||||
@@ -43,7 +40,7 @@ import org.springframework.webflow.test.MockRequestContext;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for {@link HibernateFlowExecutionListener}
|
* Tests for {@link HibernateFlowExecutionListener}
|
||||||
*
|
*
|
||||||
* @author Ben Hale
|
* @author Ben Hale
|
||||||
*/
|
*/
|
||||||
public class HibernateFlowExecutionListenerTests extends TestCase {
|
public class HibernateFlowExecutionListenerTests extends TestCase {
|
||||||
@@ -86,7 +83,7 @@ public class HibernateFlowExecutionListenerTests extends TestCase {
|
|||||||
assertSessionBound();
|
assertSessionBound();
|
||||||
|
|
||||||
hibernateTemplate.executeWithNativeSession(new HibernateCallback<Object>() {
|
hibernateTemplate.executeWithNativeSession(new HibernateCallback<Object>() {
|
||||||
public Object doInHibernate(Session session) throws HibernateException, SQLException {
|
public Object doInHibernate(Session session) {
|
||||||
assertSame("Should have been original instance", hibSession, session);
|
assertSame("Should have been original instance", hibSession, session);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import org.hibernate.Session;
|
|||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.orm.hibernate3.HibernateTransactionManager;
|
import org.springframework.orm.hibernate4.HibernateTransactionManager;
|
||||||
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
|
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
import org.springframework.webflow.execution.Action;
|
import org.springframework.webflow.execution.Action;
|
||||||
import org.springframework.webflow.execution.Event;
|
import org.springframework.webflow.execution.Event;
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import javax.sql.DataSource;
|
|||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.orm.hibernate3.HibernateTemplate;
|
import org.springframework.orm.hibernate4.HibernateTemplate;
|
||||||
import org.springframework.orm.hibernate3.HibernateTransactionManager;
|
import org.springframework.orm.hibernate4.HibernateTransactionManager;
|
||||||
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
|
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||||
import org.springframework.webflow.execution.FlowExecutionListener;
|
import org.springframework.webflow.execution.FlowExecutionListener;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user