Automatically close SessionFactory objects

SessionFactory objects created by
SessionFactoryBuilderSupport#buildSessionFactory are now DisposableBean
proxies that call SessionFactory#close and release any threadlocal
DataSource object.

This is the same behavior that has always occurred during LSFBean and
ASFBean destruction lifecycles (and still does). This destruction logic
has now been factored out into
SessionFactoryBuilderSupport#closeHibernateSessionFactory such that all
SFB types can reuse it easily.

Note that LSFBean and ASFBean are subclasses, respectively, of SFBuilder
and ASFBuilder and they each must disable the DisposableBean proxying in
order to avoid duplicate attempts at closing the SessionFactory. See
the implementations of wrapSessionFactoryIfNeccesary() for details.

Issue: SPR-8114
This commit is contained in:
Chris Beams
2011-04-26 10:15:30 +00:00
parent 88e2277bff
commit 5c27a04210
6 changed files with 94 additions and 28 deletions

View File

@@ -19,7 +19,9 @@ package org.springframework.orm.hibernate3;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.util.List;
@@ -34,6 +36,7 @@ import org.hibernate.classic.Session;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -130,6 +133,16 @@ 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) {
SessionFactory sessionFactory = new AnnotationConfigApplicationContext(configClass).getBean(SessionFactory.class);