Revert "Automatically close SessionFactory objects"
This reverts commit bb4f48dcb3.
Issue: SPR-8114
This commit is contained in:
parent
b82d5ae8da
commit
1a8531b401
|
|
@ -19,9 +19,7 @@ package org.springframework.orm.hibernate3;
|
||||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||||
import static org.hamcrest.Matchers.startsWith;
|
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -36,7 +34,6 @@ import org.hibernate.classic.Session;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.beans.factory.BeanCreationException;
|
import org.springframework.beans.factory.BeanCreationException;
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
@ -130,16 +127,6 @@ public class HibernateSessionFactoryConfigurationTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void builtSessionFactoryIsDisposableBeanProxy() {
|
|
||||||
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AnnotationSessionFactoryConfig.class);
|
|
||||||
SessionFactory sessionFactory = ctx.getBean(SessionFactory.class);
|
|
||||||
assertThat(sessionFactory, instanceOf(DisposableBean.class));
|
|
||||||
assertThat(sessionFactory.toString(), startsWith("DisposableBean proxy for SessionFactory"));
|
|
||||||
ctx.close();
|
|
||||||
assertTrue("SessionFactory was not closed as expected", sessionFactory.isClosed());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void saveAndRetriveEntity(Class<?> configClass) {
|
private void saveAndRetriveEntity(Class<?> configClass) {
|
||||||
SessionFactory sessionFactory = new AnnotationConfigApplicationContext(configClass).getBean(SessionFactory.class);
|
SessionFactory sessionFactory = new AnnotationConfigApplicationContext(configClass).getBean(SessionFactory.class);
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@
|
||||||
package org.springframework.orm.hibernate3;
|
package org.springframework.orm.hibernate3;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.SessionFactory;
|
|
||||||
|
|
||||||
|
import org.hibernate.SessionFactory;
|
||||||
import org.springframework.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
import org.springframework.jdbc.support.SQLExceptionTranslator;
|
import org.springframework.jdbc.support.SQLExceptionTranslator;
|
||||||
|
|
||||||
|
|
@ -110,11 +110,6 @@ public class LocalSessionFactoryBean extends SessionFactoryBuilder implements Se
|
||||||
delegate.setPersistenceExceptionTranslator(hibernateExceptionTranslator);
|
delegate.setPersistenceExceptionTranslator(hibernateExceptionTranslator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SessionFactory wrapSessionFactoryIfNecessary(SessionFactory rawSf) {
|
|
||||||
return delegate.wrapSessionFactoryIfNecessary(rawSf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated as of Spring 3.1 in favor of {@link #newSessionFactory()} which
|
* @deprecated as of Spring 3.1 in favor of {@link #newSessionFactory()} which
|
||||||
* can access the internal {@code Configuration} instance via {@link #getConfiguration()}.
|
* can access the internal {@code Configuration} instance via {@link #getConfiguration()}.
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.orm.hibernate3;
|
package org.springframework.orm.hibernate3;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
import org.hibernate.cache.RegionFactory;
|
import org.hibernate.cache.RegionFactory;
|
||||||
|
|
@ -113,7 +115,23 @@ public class SessionFactoryBeanDelegate implements SessionFactoryBeanOperations
|
||||||
}
|
}
|
||||||
|
|
||||||
public void destroy() throws HibernateException {
|
public void destroy() throws HibernateException {
|
||||||
SessionFactoryBuilderSupport.closeHibernateSessionFactory(this.builder, this.sessionFactory);
|
builder.logger.info("Closing Hibernate SessionFactory");
|
||||||
|
DataSource dataSource = builder.getDataSource();
|
||||||
|
if (dataSource != null) {
|
||||||
|
// Make given DataSource available for potential SchemaExport,
|
||||||
|
// which unfortunately reinstantiates a ConnectionProvider.
|
||||||
|
SessionFactoryBuilderSupport.configTimeDataSourceHolder.set(dataSource);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
builder.beforeSessionFactoryDestruction();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
this.sessionFactory.close();
|
||||||
|
if (dataSource != null) {
|
||||||
|
// Reset DataSource holder.
|
||||||
|
SessionFactoryBuilderSupport.configTimeDataSourceHolder.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) {
|
public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) {
|
||||||
|
|
@ -124,11 +142,6 @@ public class SessionFactoryBeanDelegate implements SessionFactoryBeanOperations
|
||||||
return hibernateExceptionTranslator.translateExceptionIfPossible(ex);
|
return hibernateExceptionTranslator.translateExceptionIfPossible(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SessionFactory wrapSessionFactoryIfNecessary(SessionFactory rawSf) {
|
|
||||||
return rawSf;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SessionFactoryBuilderSupport#preBuildSessionFactory()
|
* @see SessionFactoryBuilderSupport#preBuildSessionFactory()
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -125,12 +125,4 @@ public interface SessionFactoryBeanOperations
|
||||||
*/
|
*/
|
||||||
DataAccessException translateExceptionIfPossible(RuntimeException ex);
|
DataAccessException translateExceptionIfPossible(RuntimeException ex);
|
||||||
|
|
||||||
/**
|
|
||||||
* Override the default {@link DisposableBean} proxying behavior in
|
|
||||||
* {@link SessionFactoryBuilderSupport#wrapSessionFactoryIfNecessary(SessionFactory)}
|
|
||||||
* and return the raw {@code SessionFactory} instance, as {@link SessionFactory#close()}
|
|
||||||
* will be called during this FactoryBean's normal {@linkplain #destroy() destruction lifecycle}.
|
|
||||||
*/
|
|
||||||
SessionFactory wrapSessionFactoryIfNecessary(SessionFactory rawSf);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,7 @@ package org.springframework.orm.hibernate3;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.InvocationHandler;
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Proxy;
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
|
|
@ -34,7 +32,6 @@ import javax.transaction.TransactionManager;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.Interceptor;
|
import org.hibernate.Interceptor;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
|
|
@ -48,10 +45,7 @@ import org.hibernate.engine.SessionFactoryImplementor;
|
||||||
import org.hibernate.event.EventListeners;
|
import org.hibernate.event.EventListeners;
|
||||||
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
|
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
|
||||||
import org.hibernate.transaction.JTATransactionFactory;
|
import org.hibernate.transaction.JTATransactionFactory;
|
||||||
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
|
||||||
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.dao.DataAccessException;
|
import org.springframework.dao.DataAccessException;
|
||||||
|
|
@ -546,37 +540,16 @@ public abstract class SessionFactoryBuilderSupport<This extends SessionFactoryBu
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrap the given {@code SessionFactory} with a proxy, if demanded.
|
* Wrap the given SessionFactory with a proxy, if demanded.
|
||||||
* <p>The default implementation wraps the given {@code SessionFactory} as a Spring
|
* <p>The default implementation simply returns the given SessionFactory as-is.
|
||||||
* {@link DisposableBean} proxy in order to call {@link SessionFactory#close()} on
|
* Subclasses may override this to implement transaction awareness through
|
||||||
* {@code ApplicationContext} {@linkplain ConfigurableApplicationContext#close() shutdown}.
|
* a SessionFactory proxy, for example.
|
||||||
* <p>Subclasses may override this to implement transaction awareness through
|
* @param rawSf the raw SessionFactory as built by {@link #buildSessionFactory()}
|
||||||
* a {@code SessionFactory} proxy for example, or even to avoid creation of the
|
* @return the SessionFactory reference to expose
|
||||||
* {@code DisposableBean} proxy altogether.
|
|
||||||
* @param rawSf the raw {@code SessionFactory} as built by {@link #buildSessionFactory()}
|
|
||||||
* @return the {@code SessionFactory} reference to expose
|
|
||||||
* @see #buildSessionFactory()
|
* @see #buildSessionFactory()
|
||||||
*/
|
*/
|
||||||
protected SessionFactory wrapSessionFactoryIfNecessary(final SessionFactory rawSf) {
|
protected SessionFactory wrapSessionFactoryIfNecessary(SessionFactory rawSf) {
|
||||||
return (SessionFactory) Proxy.newProxyInstance(
|
return rawSf;
|
||||||
this.beanClassLoader,
|
|
||||||
new Class<?>[] {
|
|
||||||
SessionFactory.class,
|
|
||||||
DisposableBean.class
|
|
||||||
},
|
|
||||||
new InvocationHandler() {
|
|
||||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
|
||||||
if (ReflectionUtils.isToStringMethod(method)) {
|
|
||||||
return String.format("DisposableBean proxy for SessionFactory [%s]", rawSf.toString());
|
|
||||||
}
|
|
||||||
if (method.equals(DisposableBean.class.getMethod("destroy"))) {
|
|
||||||
closeHibernateSessionFactory(SessionFactoryBuilderSupport.this, rawSf);
|
|
||||||
rawSf.close();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return method.invoke(rawSf, args);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1424,24 +1397,4 @@ public abstract class SessionFactoryBuilderSupport<This extends SessionFactoryBu
|
||||||
return configTimeLobHandlerHolder.get();
|
return configTimeLobHandlerHolder.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void closeHibernateSessionFactory(SessionFactoryBuilderSupport<?> builder, SessionFactory sessionFactory) {
|
|
||||||
builder.logger.info("Closing Hibernate SessionFactory");
|
|
||||||
DataSource dataSource = builder.getDataSource();
|
|
||||||
if (dataSource != null) {
|
|
||||||
// Make given DataSource available for potential SchemaExport,
|
|
||||||
// which unfortunately reinstantiates a ConnectionProvider.
|
|
||||||
SessionFactoryBuilderSupport.configTimeDataSourceHolder.set(dataSource);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
builder.beforeSessionFactoryDestruction();
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
sessionFactory.close();
|
|
||||||
if (dataSource != null) {
|
|
||||||
// Reset DataSource holder.
|
|
||||||
SessionFactoryBuilderSupport.configTimeDataSourceHolder.remove();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ package org.springframework.orm.hibernate3.annotation;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
|
|
||||||
import org.springframework.context.ResourceLoaderAware;
|
import org.springframework.context.ResourceLoaderAware;
|
||||||
import org.springframework.core.io.ResourceLoader;
|
import org.springframework.core.io.ResourceLoader;
|
||||||
import org.springframework.core.io.support.ResourcePatternUtils;
|
import org.springframework.core.io.support.ResourcePatternUtils;
|
||||||
|
|
@ -135,11 +134,6 @@ public class AnnotationSessionFactoryBean extends AnnotationSessionFactoryBuilde
|
||||||
delegate.setPersistenceExceptionTranslator(hibernateExceptionTranslator);
|
delegate.setPersistenceExceptionTranslator(hibernateExceptionTranslator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SessionFactory wrapSessionFactoryIfNecessary(SessionFactory rawSf) {
|
|
||||||
return delegate.wrapSessionFactoryIfNecessary(rawSf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated as of Spring 3.1 in favor of {@link #scanPackages()} which
|
* @deprecated as of Spring 3.1 in favor of {@link #scanPackages()} which
|
||||||
* can access the internal {@code AnnotationConfiguration} instance via
|
* can access the internal {@code AnnotationConfiguration} instance via
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue