diff --git a/org.springframework.integration-tests/.classpath b/org.springframework.integration-tests/.classpath
index 26074edfbc7..d1ea9d34812 100644
--- a/org.springframework.integration-tests/.classpath
+++ b/org.springframework.integration-tests/.classpath
@@ -21,6 +21,7 @@
+
@@ -69,6 +70,7 @@
+
diff --git a/org.springframework.integration-tests/.springBeans b/org.springframework.integration-tests/.springBeans
index 55e47c55ec7..5e600dfe9f4 100644
--- a/org.springframework.integration-tests/.springBeans
+++ b/org.springframework.integration-tests/.springBeans
@@ -1,12 +1,13 @@
1
-
+
+ src/test/resources/org/springframework/orm/hibernate3/LocalSessionFactoryBeanXmlConfig-context.xml
diff --git a/org.springframework.integration-tests/integration-tests.iml b/org.springframework.integration-tests/integration-tests.iml
index 13421323256..ea3643ecf3d 100644
--- a/org.springframework.integration-tests/integration-tests.iml
+++ b/org.springframework.integration-tests/integration-tests.iml
@@ -31,6 +31,7 @@
+
@@ -446,6 +447,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.springframework.integration-tests/ivy.xml b/org.springframework.integration-tests/ivy.xml
index 455fd86e83b..6b9e9730375 100644
--- a/org.springframework.integration-tests/ivy.xml
+++ b/org.springframework.integration-tests/ivy.xml
@@ -74,7 +74,9 @@
+
+
diff --git a/org.springframework.integration-tests/src/test/java/org/springframework/orm/hibernate3/HibernateSessionFactoryConfigurationTests.java b/org.springframework.integration-tests/src/test/java/org/springframework/orm/hibernate3/HibernateSessionFactoryConfigurationTests.java
new file mode 100644
index 00000000000..8d72df5d4f4
--- /dev/null
+++ b/org.springframework.integration-tests/src/test/java/org/springframework/orm/hibernate3/HibernateSessionFactoryConfigurationTests.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright 2002-2011 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+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.junit.Assert.assertThat;
+
+import java.io.File;
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.sql.DataSource;
+
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.AnnotationConfiguration;
+import org.hibernate.classic.Session;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.springframework.beans.factory.BeanCreationException;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Feature;
+import org.springframework.context.annotation.FeatureConfiguration;
+import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.ImportResource;
+import org.springframework.dao.DataAccessException;
+import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
+import org.springframework.dao.support.PersistenceExceptionTranslator;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
+import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
+import org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBuilder;
+import org.springframework.orm.hibernate3.scannable.Foo;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.config.TxAnnotationDriven;
+
+/**
+ * Integration tests for configuring Hibernate SessionFactory types
+ * without using a FactoryBean, e.g., within a {@link Configuration} class.
+ *
+ * @author Chris Beams
+ * @since 3.1
+ */
+public class HibernateSessionFactoryConfigurationTests {
+
+ @Test
+ public void usingLocalSessionFactoryBean() {
+ saveAndRetriveEntity(LocalSessionFactoryBeanXmlConfig.class);
+ }
+
+ @Test
+ public void usingAnnotationSessionFactoryBean() {
+ saveAndRetriveEntity(AnnotationSessionFactoryBeanXmlConfig.class);
+ }
+
+ @Ignore @Test
+ public void usingNativeHibernateConfiguration() {
+ saveAndRetriveEntity(NativeHibernateConfig.class);
+ }
+
+ @Test
+ public void usingSessionFactoryBuilder_withConfigurationCallback() {
+ saveAndRetriveEntity(SessionFactoryConfig_withConfigurationCallback.class);
+ }
+
+ @Test
+ public void usingAnnotationSessionFactoryBuilder() {
+ saveAndRetriveEntity(AnnotationSessionFactoryConfig.class);
+ }
+
+ @Test
+ public void usingAnnotationSessionFactoryBuilder_withConfigurationCallback() {
+ saveAndRetriveEntity(AnnotationSessionFactoryConfig_withConfigurationCallback.class);
+ }
+
+ @Test
+ public void usingAnnotationSessionFactoryBuilder_withPackagesToScan() {
+ saveAndRetriveEntity(AnnotationSessionFactoryConfig_withPackagesToScan.class);
+ }
+
+ @Test
+ public void usingAnnotationSessionFactoryBuilder_withAnnotatedClasses() {
+ saveAndRetriveEntity(AnnotationSessionFactoryConfig_withAnnotatedClasses.class);
+ }
+
+
+ @Test(expected=DataAccessException.class)
+ public void exceptionTranslation_withLocalSessionFactoryBean() {
+ causeException(LocalSessionFactoryBeanXmlConfig.class, RepositoryConfig.class);
+ }
+
+ @Test(expected=DataAccessException.class)
+ public void exceptionTranslation_withSessionFactoryBuilder() {
+ causeException(SessionFactoryConfig_withConfigurationCallback.class,
+ RepositoryConfig.class);
+ }
+
+ @Test
+ public void usingSessionFactoryBuilder_withCustomConfigurationClass() {
+ saveAndRetriveEntity(SessionFactoryConfig_withCustomConfigurationClass.class);
+ }
+
+ @Test(expected=IllegalStateException.class)
+ public void usingSessionFactoryBuilder_withLateCustomConfigurationClass() throws Throwable {
+ try {
+ saveAndRetriveEntity(SessionFactoryConfig_withLateCustomConfigurationClass.class);
+ } catch (BeanCreationException ex) {
+ Throwable cause = ex.getRootCause();
+ assertThat(cause.getMessage().startsWith("setConfigurationClass() must be called before"), is(true));
+ throw cause;
+ }
+ }
+
+
+ private void saveAndRetriveEntity(Class> configClass) {
+ SessionFactory sessionFactory = new AnnotationConfigApplicationContext(configClass).getBean(SessionFactory.class);
+ Session session = sessionFactory.openSession();
+ Transaction tx = session.beginTransaction();
+ Foo foo = new Foo();
+ foo.setName("f1");
+ session.save(foo);
+
+ Foo f1 = (Foo) session.createQuery("from Foo where name = 'f1'").uniqueResult();
+ assertThat("No foo with name='f1' found!", f1, notNullValue());
+ assertThat(f1.getName(), is("f1"));
+
+ tx.rollback();
+ }
+
+ private void causeException(Class>... configClasses) {
+ FooRepository fooRepository = new AnnotationConfigApplicationContext(configClasses).getBean(FooRepository.class);
+ fooRepository.findAll(); // will throw
+ }
+
+
+ @Configuration
+ static class DataConfig {
+ @Bean
+ DataSource dataSource() {
+ return new EmbeddedDatabaseBuilder()
+ .setType(EmbeddedDatabaseType.HSQL)
+ .build();
+ }
+ }
+
+
+ @Configuration
+ @ImportResource("org/springframework/orm/hibernate3/LocalSessionFactoryBeanXmlConfig-context.xml")
+ static class LocalSessionFactoryBeanXmlConfig extends DataConfig {
+ }
+
+
+ interface FooRepository {
+ List findAll();
+ }
+
+ @Repository
+ public static class HibernateFooRepository implements FooRepository {
+ private final SessionFactory sessionFactory;
+ public HibernateFooRepository(SessionFactory sessionFactory) {
+ this.sessionFactory = sessionFactory;
+ }
+ @Transactional
+ @SuppressWarnings("unchecked")
+ public List findAll() {
+ return sessionFactory.getCurrentSession().createQuery("from Bogus").list();
+ }
+ }
+
+
+ @Configuration
+ @Import(TxConfig.class)
+ static class RepositoryConfig {
+ @Inject SessionFactory sessionFactory;
+
+ @Bean
+ FooRepository fooRepository() {
+ return new HibernateFooRepository(sessionFactory);
+ }
+
+ @Bean
+ PlatformTransactionManager txManager() {
+ return new HibernateTransactionManager(sessionFactory);
+ }
+
+ @Bean
+ PersistenceExceptionTranslationPostProcessor exceptionTranslationPostProcessor() {
+ return new PersistenceExceptionTranslationPostProcessor();
+ }
+
+ @Bean
+ PersistenceExceptionTranslator exceptionTranslator() {
+ return new HibernateExceptionTranslator();
+ }
+ }
+
+
+ @FeatureConfiguration
+ static class TxConfig {
+ @Feature
+ TxAnnotationDriven tx(PlatformTransactionManager txManager) {
+ return new TxAnnotationDriven(txManager);
+ }
+ }
+
+
+ @Configuration
+ @ImportResource("org/springframework/orm/hibernate3/AnnotationSessionFactoryBeanXmlConfig-context.xml")
+ static class AnnotationSessionFactoryBeanXmlConfig extends DataConfig {
+ }
+
+
+ @Configuration
+ static class NativeHibernateConfig {
+ @Bean
+ SessionFactory sessionFactory() {
+ org.hibernate.cfg.Configuration cfg = new AnnotationConfiguration();
+ return cfg.buildSessionFactory();
+ }
+ }
+
+
+ @Configuration
+ static class AnnotationSessionFactoryConfig extends DataConfig {
+ @Bean
+ SessionFactory sessionFactory() throws Exception {
+ return new AnnotationSessionFactoryBuilder(dataSource())
+ .setSchemaUpdate(true)
+ .doWithConfiguration(new HibernateConfigurationCallback() {
+ public void configure(AnnotationConfiguration configuration) {
+ configuration.addAnnotatedClass(Foo.class);
+ }
+ })
+ .buildSessionFactory();
+ }
+ }
+
+
+ @Configuration
+ static class AnnotationSessionFactoryConfig_withPackagesToScan extends DataConfig {
+ @Bean
+ SessionFactory sessionFactory() throws Exception {
+ return new AnnotationSessionFactoryBuilder(dataSource())
+ .setSchemaUpdate(true)
+ .setPackagesToScan(Foo.class.getPackage().getName())
+ .buildSessionFactory();
+ }
+ }
+
+ @Configuration
+ static class AnnotationSessionFactoryConfig_withAnnotatedClasses extends DataConfig {
+ @Bean
+ SessionFactory sessionFactory() throws Exception {
+ return new AnnotationSessionFactoryBuilder(dataSource())
+ .setSchemaUpdate(true)
+ .setAnnotatedClasses(Foo.class, Foo.class)
+ .buildSessionFactory();
+ }
+ }
+
+
+ @Configuration
+ static class AnnotationSessionFactoryConfig_withConfigurationCallback extends DataConfig {
+ @Bean
+ SessionFactory sessionFactory() throws Exception {
+ return new AnnotationSessionFactoryBuilder(dataSource())
+ .setSchemaUpdate(true)
+ .doWithConfiguration(new HibernateConfigurationCallback() {
+ public void configure(AnnotationConfiguration configuration) throws Exception {
+ configuration.addAnnotatedClass(Foo.class);
+ }
+ })
+ .buildSessionFactory();
+ }
+ }
+
+
+ @Configuration
+ static class SessionFactoryConfig_withConfigurationCallback extends DataConfig {
+ @Bean
+ SessionFactory sessionFactory() throws Exception {
+ return new SessionFactoryBuilder(dataSource())
+ .setSchemaUpdate(true)
+ .doWithConfiguration(new HibernateConfigurationCallback() {
+ public void configure(org.hibernate.cfg.Configuration configuration) throws Exception {
+ configuration.addFile(new File(this.getClass().getClassLoader().getResource("org/springframework/orm/hibernate3/scannable/FooMapping.hbm.xml").toURI()));
+ }
+ })
+ .buildSessionFactory();
+ }
+ }
+
+
+ @Configuration
+ static class SessionFactoryConfig_withCustomConfigurationClass extends DataConfig {
+ @Bean
+ SessionFactory sessionFactory() throws Exception {
+ SessionFactoryBuilder sfb = new SessionFactoryBuilder(dataSource())
+ .setSchemaUpdate(true)
+ .setConfigurationClass(CustomHibernateConfiguration.class)
+ .doWithConfiguration(new HibernateConfigurationCallback() {
+ public void configure(org.hibernate.cfg.Configuration configuration) throws Exception {
+ configuration.addFile(new File(this.getClass().getClassLoader().getResource("org/springframework/orm/hibernate3/scannable/FooMapping.hbm.xml").toURI()));
+ }
+ });
+ assertThat(sfb.getConfiguration(), instanceOf(CustomHibernateConfiguration.class));
+ return sfb.buildSessionFactory();
+ }
+ }
+
+
+ @Configuration
+ static class SessionFactoryConfig_withLateCustomConfigurationClass extends DataConfig {
+ @Bean
+ SessionFactory sessionFactory() throws Exception {
+ return new SessionFactoryBuilder(dataSource())
+ .setSchemaUpdate(true)
+ .doWithConfiguration(new HibernateConfigurationCallback() {
+ public void configure(org.hibernate.cfg.Configuration configuration) throws Exception {
+ configuration.addFile(new File(this.getClass().getClassLoader().getResource("org/springframework/orm/hibernate3/scannable/FooMapping.hbm.xml").toURI()));
+ }
+ })
+ .setConfigurationClass(CustomHibernateConfiguration.class)
+ .buildSessionFactory();
+ }
+ }
+
+
+ @SuppressWarnings("serial")
+ static class CustomHibernateConfiguration extends org.hibernate.cfg.Configuration {
+ }
+
+}
diff --git a/org.springframework.integration-tests/src/test/java/org/springframework/orm/hibernate3/scannable/Foo.java b/org.springframework.integration-tests/src/test/java/org/springframework/orm/hibernate3/scannable/Foo.java
new file mode 100644
index 00000000000..0728499b09f
--- /dev/null
+++ b/org.springframework.integration-tests/src/test/java/org/springframework/orm/hibernate3/scannable/Foo.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2002-2011 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.orm.hibernate3.scannable;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class Foo {
+ @SuppressWarnings("unused")
+ @Id private int id;
+
+ private String name;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+}
\ No newline at end of file
diff --git a/org.springframework.integration-tests/src/test/resources/org/springframework/orm/hibernate3/AnnotationSessionFactoryBeanXmlConfig-context.xml b/org.springframework.integration-tests/src/test/resources/org/springframework/orm/hibernate3/AnnotationSessionFactoryBeanXmlConfig-context.xml
new file mode 100644
index 00000000000..dd5ec1d94c8
--- /dev/null
+++ b/org.springframework.integration-tests/src/test/resources/org/springframework/orm/hibernate3/AnnotationSessionFactoryBeanXmlConfig-context.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/org.springframework.integration-tests/src/test/resources/org/springframework/orm/hibernate3/LocalSessionFactoryBeanXmlConfig-context.xml b/org.springframework.integration-tests/src/test/resources/org/springframework/orm/hibernate3/LocalSessionFactoryBeanXmlConfig-context.xml
new file mode 100644
index 00000000000..c3a2f30b314
--- /dev/null
+++ b/org.springframework.integration-tests/src/test/resources/org/springframework/orm/hibernate3/LocalSessionFactoryBeanXmlConfig-context.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+ hibernate.dialect=org.hibernate.dialect.HSQLDialect
+
+
+
+
+
\ No newline at end of file
diff --git a/org.springframework.integration-tests/src/test/resources/org/springframework/orm/hibernate3/scannable/FooMapping.hbm.xml b/org.springframework.integration-tests/src/test/resources/org/springframework/orm/hibernate3/scannable/FooMapping.hbm.xml
new file mode 100644
index 00000000000..187f1452184
--- /dev/null
+++ b/org.springframework.integration-tests/src/test/resources/org/springframework/orm/hibernate3/scannable/FooMapping.hbm.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/AbstractSessionFactoryBean.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/AbstractSessionFactoryBean.java
deleted file mode 100644
index 135538e7953..00000000000
--- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/AbstractSessionFactoryBean.java
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright 2002-2010 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.orm.hibernate3;
-
-import javax.sql.DataSource;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.JDBCException;
-import org.hibernate.SessionFactory;
-
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.dao.DataAccessException;
-import org.springframework.dao.support.PersistenceExceptionTranslator;
-import org.springframework.jdbc.support.SQLExceptionTranslator;
-
-/**
- * Abstract {@link org.springframework.beans.factory.FactoryBean} that creates
- * a Hibernate {@link org.hibernate.SessionFactory} within a Spring application
- * context, providing general infrastructure not related to Hibernate's
- * specific configuration API.
- *
- *
This class implements the
- * {@link org.springframework.dao.support.PersistenceExceptionTranslator}
- * interface, as autodetected by Spring's
- * {@link org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor},
- * for AOP-based translation of native exceptions to Spring DataAccessExceptions.
- * Hence, the presence of e.g. LocalSessionFactoryBean automatically enables
- * a PersistenceExceptionTranslationPostProcessor to translate Hibernate exceptions.
- *
- *
This class mainly serves as common base class for {@link LocalSessionFactoryBean}.
- * For details on typical SessionFactory setup, see the LocalSessionFactoryBean javadoc.
- *
- * @author Juergen Hoeller
- * @since 2.0
- * @see #setExposeTransactionAwareSessionFactory
- * @see org.hibernate.SessionFactory#getCurrentSession()
- * @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor
- */
-public abstract class AbstractSessionFactoryBean
- implements FactoryBean, InitializingBean, DisposableBean, PersistenceExceptionTranslator {
-
- /** Logger available to subclasses */
- protected final Log logger = LogFactory.getLog(getClass());
-
- private DataSource dataSource;
-
- private boolean useTransactionAwareDataSource = false;
-
- private boolean exposeTransactionAwareSessionFactory = true;
-
- private SQLExceptionTranslator jdbcExceptionTranslator;
-
- private SessionFactory sessionFactory;
-
-
- /**
- * Set the DataSource to be used by the SessionFactory.
- * If set, this will override corresponding settings in Hibernate properties.
- *
If this is set, the Hibernate settings should not define
- * a connection provider to avoid meaningless double configuration.
- *
If using HibernateTransactionManager as transaction strategy, consider
- * proxying your target DataSource with a LazyConnectionDataSourceProxy.
- * This defers fetching of an actual JDBC Connection until the first JDBC
- * Statement gets executed, even within JDBC transactions (as performed by
- * HibernateTransactionManager). Such lazy fetching is particularly beneficial
- * for read-only operations, in particular if the chances of resolving the
- * result in the second-level cache are high.
- *
As JTA and transactional JNDI DataSources already provide lazy enlistment
- * of JDBC Connections, LazyConnectionDataSourceProxy does not add value with
- * JTA (i.e. Spring's JtaTransactionManager) as transaction strategy.
- * @see #setUseTransactionAwareDataSource
- * @see HibernateTransactionManager
- * @see org.springframework.transaction.jta.JtaTransactionManager
- * @see org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy
- */
- public void setDataSource(DataSource dataSource) {
- this.dataSource = dataSource;
- }
-
- /**
- * Return the DataSource to be used by the SessionFactory.
- */
- public DataSource getDataSource() {
- return this.dataSource;
- }
-
- /**
- * Set whether to use a transaction-aware DataSource for the SessionFactory,
- * i.e. whether to automatically wrap the passed-in DataSource with Spring's
- * TransactionAwareDataSourceProxy.
- *
Default is "false": LocalSessionFactoryBean is usually used with Spring's
- * HibernateTransactionManager or JtaTransactionManager, both of which work nicely
- * on a plain JDBC DataSource. Hibernate Sessions and their JDBC Connections are
- * fully managed by the Hibernate/JTA transaction infrastructure in such a scenario.
- *
If you switch this flag to "true", Spring's Hibernate access will be able to
- * participate in JDBC-based transactions managed outside of Hibernate
- * (for example, by Spring's DataSourceTransactionManager). This can be convenient
- * if you need a different local transaction strategy for another O/R mapping tool,
- * for example, but still want Hibernate access to join into those transactions.
- *
A further benefit of this option is that plain Sessions opened directly
- * via the SessionFactory, outside of Spring's Hibernate support, will still
- * participate in active Spring-managed transactions. However, consider using
- * Hibernate's getCurrentSession() method instead (see javadoc of
- * "exposeTransactionAwareSessionFactory" property).
- *
WARNING: When using a transaction-aware JDBC DataSource in combination
- * with OpenSessionInViewFilter/Interceptor, whether participating in JTA or
- * external JDBC-based transactions, it is strongly recommended to set Hibernate's
- * Connection release mode to "after_transaction" or "after_statement", which
- * guarantees proper Connection handling in such a scenario. In contrast to that,
- * HibernateTransactionManager generally requires release mode "on_close".
- *
Note: If you want to use Hibernate's Connection release mode "after_statement"
- * with a DataSource specified on this LocalSessionFactoryBean (for example, a
- * JTA-aware DataSource fetched from JNDI), switch this setting to "true".
- * Otherwise, the ConnectionProvider used underneath will vote against aggressive
- * release and thus silently switch to release mode "after_transaction".
- * @see #setDataSource
- * @see #setExposeTransactionAwareSessionFactory
- * @see org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
- * @see org.springframework.jdbc.datasource.DataSourceTransactionManager
- * @see org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
- * @see org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor
- * @see HibernateTransactionManager
- * @see org.springframework.transaction.jta.JtaTransactionManager
- */
- public void setUseTransactionAwareDataSource(boolean useTransactionAwareDataSource) {
- this.useTransactionAwareDataSource = useTransactionAwareDataSource;
- }
-
- /**
- * Return whether to use a transaction-aware DataSource for the SessionFactory.
- */
- protected boolean isUseTransactionAwareDataSource() {
- return this.useTransactionAwareDataSource;
- }
-
- /**
- * Set whether to expose a transaction-aware current Session from the
- * SessionFactory's getCurrentSession() method, returning the
- * Session that's associated with the current Spring-managed transaction, if any.
- *
Default is "true", letting data access code work with the plain
- * Hibernate SessionFactory and its getCurrentSession() method,
- * while still being able to participate in current Spring-managed transactions:
- * with any transaction management strategy, either local or JTA / EJB CMT,
- * and any transaction synchronization mechanism, either Spring or JTA.
- * Furthermore, getCurrentSession() will also seamlessly work with
- * a request-scoped Session managed by OpenSessionInViewFilter/Interceptor.
- *
Turn this flag off to expose the plain Hibernate SessionFactory with
- * Hibernate's default getCurrentSession() behavior, supporting
- * plain JTA synchronization only. Alternatively, simply override the
- * corresponding Hibernate property "hibernate.current_session_context_class".
- * @see SpringSessionContext
- * @see org.hibernate.SessionFactory#getCurrentSession()
- * @see org.springframework.transaction.jta.JtaTransactionManager
- * @see HibernateTransactionManager
- * @see org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
- * @see org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor
- */
- public void setExposeTransactionAwareSessionFactory(boolean exposeTransactionAwareSessionFactory) {
- this.exposeTransactionAwareSessionFactory = exposeTransactionAwareSessionFactory;
- }
-
- /**
- * Return whether to expose a transaction-aware proxy for the SessionFactory.
- */
- protected boolean isExposeTransactionAwareSessionFactory() {
- return this.exposeTransactionAwareSessionFactory;
- }
-
- /**
- * Set the JDBC exception translator for the SessionFactory,
- * exposed via the PersistenceExceptionTranslator interface.
- *
Applied to any SQLException root cause of a Hibernate JDBCException,
- * overriding Hibernate's default SQLException translation (which is
- * based on Hibernate's Dialect for a specific target database).
- * @param jdbcExceptionTranslator the exception translator
- * @see java.sql.SQLException
- * @see org.hibernate.JDBCException
- * @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator
- * @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator
- * @see org.springframework.dao.support.PersistenceExceptionTranslator
- */
- public void setJdbcExceptionTranslator(SQLExceptionTranslator jdbcExceptionTranslator) {
- this.jdbcExceptionTranslator = jdbcExceptionTranslator;
- }
-
-
- /**
- * Build and expose the SessionFactory.
- * @see #buildSessionFactory()
- * @see #wrapSessionFactoryIfNecessary
- */
- public void afterPropertiesSet() throws Exception {
- SessionFactory rawSf = buildSessionFactory();
- this.sessionFactory = wrapSessionFactoryIfNecessary(rawSf);
- afterSessionFactoryCreation();
- }
-
- /**
- * Wrap the given SessionFactory with a proxy, if demanded.
- *
The default implementation simply returns the given SessionFactory as-is.
- * Subclasses may override this to implement transaction awareness through
- * a SessionFactory proxy, for example.
- * @param rawSf the raw SessionFactory as built by {@link #buildSessionFactory()}
- * @return the SessionFactory reference to expose
- * @see #buildSessionFactory()
- */
- protected SessionFactory wrapSessionFactoryIfNecessary(SessionFactory rawSf) {
- return rawSf;
- }
-
- /**
- * Return the exposed SessionFactory.
- * Will throw an exception if not initialized yet.
- * @return the SessionFactory (never null)
- * @throws IllegalStateException if the SessionFactory has not been initialized yet
- */
- protected final SessionFactory getSessionFactory() {
- if (this.sessionFactory == null) {
- throw new IllegalStateException("SessionFactory not initialized yet");
- }
- return this.sessionFactory;
- }
-
- /**
- * Close the SessionFactory on bean factory shutdown.
- */
- public void destroy() throws HibernateException {
- logger.info("Closing Hibernate SessionFactory");
- try {
- beforeSessionFactoryDestruction();
- }
- finally {
- this.sessionFactory.close();
- }
- }
-
-
- /**
- * Return the singleton SessionFactory.
- */
- public SessionFactory getObject() {
- return this.sessionFactory;
- }
-
- public Class extends SessionFactory> getObjectType() {
- return (this.sessionFactory != null ? this.sessionFactory.getClass() : SessionFactory.class);
- }
-
- public boolean isSingleton() {
- return true;
- }
-
-
- /**
- * Implementation of the PersistenceExceptionTranslator interface,
- * as autodetected by Spring's PersistenceExceptionTranslationPostProcessor.
- *
Converts the exception if it is a HibernateException;
- * else returns null to indicate an unknown exception.
- * @see org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor
- * @see #convertHibernateAccessException
- */
- public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
- if (ex instanceof HibernateException) {
- return convertHibernateAccessException((HibernateException) ex);
- }
- return null;
- }
-
- /**
- * Convert the given HibernateException to an appropriate exception from the
- * org.springframework.dao hierarchy.
- *
Will automatically apply a specified SQLExceptionTranslator to a
- * Hibernate JDBCException, else rely on Hibernate's default translation.
- * @param ex HibernateException that occured
- * @return a corresponding DataAccessException
- * @see SessionFactoryUtils#convertHibernateAccessException
- * @see #setJdbcExceptionTranslator
- */
- protected DataAccessException convertHibernateAccessException(HibernateException ex) {
- if (this.jdbcExceptionTranslator != null && ex instanceof JDBCException) {
- JDBCException jdbcEx = (JDBCException) ex;
- return this.jdbcExceptionTranslator.translate(
- "Hibernate operation: " + jdbcEx.getMessage(), jdbcEx.getSQL(), jdbcEx.getSQLException());
- }
- return SessionFactoryUtils.convertHibernateAccessException(ex);
- }
-
-
- /**
- * Build the underlying Hibernate SessionFactory.
- * @return the raw SessionFactory (potentially to be wrapped with a
- * transaction-aware proxy before it is exposed to the application)
- * @throws Exception in case of initialization failure
- */
- protected abstract SessionFactory buildSessionFactory() throws Exception;
-
- /**
- * Hook that allows post-processing after the SessionFactory has been
- * successfully created. The SessionFactory is already available through
- * getSessionFactory() at this point.
- *
This implementation is empty.
- * @throws Exception in case of initialization failure
- * @see #getSessionFactory()
- */
- protected void afterSessionFactoryCreation() throws Exception {
- }
-
- /**
- * Hook that allows shutdown processing before the SessionFactory
- * will be closed. The SessionFactory is still available through
- * getSessionFactory() at this point.
- *
This implementation is empty.
- * @see #getSessionFactory()
- */
- protected void beforeSessionFactoryDestruction() {
- }
-
-}
diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/FilterDefinitionFactoryBean.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/FilterDefinitionFactoryBean.java
index 04b7789d3b8..3f84727aa01 100644
--- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/FilterDefinitionFactoryBean.java
+++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/FilterDefinitionFactoryBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2010 the original author or authors.
+ * Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,24 +37,25 @@ import org.springframework.util.ReflectionUtils;
* definition, as the list element for the "filterDefinitions" bean property.
* For example:
*
- *
*
* Alternatively, specify a bean id (or name) attribute for the inner bean,
* instead of the "filterName" property.
@@ -73,7 +74,7 @@ public class FilterDefinitionFactoryBean implements FactoryBean trClass = FilterDefinitionFactoryBean.class.getClassLoader().loadClass(
"org.hibernate.type.TypeResolver");
heuristicTypeMethod = trClass.getMethod("heuristicType", String.class);
typeResolver = trClass.newInstance();
diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateAccessor.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateAccessor.java
index 7fe337d6595..7b3b4e05a3b 100644
--- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateAccessor.java
+++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateAccessor.java
@@ -181,12 +181,13 @@ public abstract class HibernateAccessor implements InitializingBean, BeanFactory
* property values before writing to and reading from the database.
* Will get applied to any new Session created by this object.
*
Such an interceptor can either be set at the SessionFactory level,
- * i.e. on LocalSessionFactoryBean, or at the Session level, i.e. on
- * HibernateTemplate, HibernateInterceptor, and HibernateTransactionManager.
- * It's preferable to set it on LocalSessionFactoryBean or HibernateTransactionManager
- * to avoid repeated configuration and guarantee consistent behavior in transactions.
+ * i.e. on SessionFactoryBuilder/LocalSessionFactoryBean, or at the Session
+ * level, i.e. on HibernateTemplate, HibernateInterceptor, and
+ * HibernateTransactionManager. It's preferable to set it on
+ * SessionFactoryBuilder or HibernateTransactionManager to avoid repeated
+ * configuration and guarantee consistent behavior in transactions.
* @see #setEntityInterceptorBeanName
- * @see LocalSessionFactoryBean#setEntityInterceptor
+ * @see SessionFactoryBuilder#setEntityInterceptor
* @see HibernateTransactionManager#setEntityInterceptor
*/
public void setEntityInterceptor(Interceptor entityInterceptor) {
@@ -208,7 +209,7 @@ public abstract class HibernateAccessor implements InitializingBean, BeanFactory
if (this.beanFactory == null) {
throw new IllegalStateException("Cannot get entity interceptor via bean name if no bean factory set");
}
- return (Interceptor) this.beanFactory.getBean((String) this.entityInterceptor, Interceptor.class);
+ return this.beanFactory.getBean((String) this.entityInterceptor, Interceptor.class);
}
return (Interceptor) this.entityInterceptor;
}
@@ -272,7 +273,7 @@ public abstract class HibernateAccessor implements InitializingBean, BeanFactory
* Sessions (for example, within a transaction).
* @see #enableFilters(org.hibernate.Session)
* @see org.hibernate.Session#enableFilter(String)
- * @see LocalSessionFactoryBean#setFilterDefinitions
+ * @see SessionFactoryBuilder#setFilterDefinitions
*/
public void setFilterName(String filter) {
this.filterNames = new String[] {filter};
@@ -287,7 +288,7 @@ public abstract class HibernateAccessor implements InitializingBean, BeanFactory
* Sessions (for example, within a transaction).
* @see #enableFilters(org.hibernate.Session)
* @see org.hibernate.Session#enableFilter(String)
- * @see LocalSessionFactoryBean#setFilterDefinitions
+ * @see SessionFactoryBuilder#setFilterDefinitions
*/
public void setFilterNames(String[] filterNames) {
this.filterNames = filterNames;
diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateConfigurationCallback.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateConfigurationCallback.java
new file mode 100644
index 00000000000..1099d1894da
--- /dev/null
+++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateConfigurationCallback.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2002-2011 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.orm.hibernate3;
+
+import org.hibernate.cfg.Configuration;
+
+/**
+ * Callback for use in conjunction with {@link SessionFactoryBuilderSupport#doWithConfiguration}.
+ *
+ * @author Chris Beams
+ * @since 3.1
+ * @see SessionFactoryBuilderSupport#doWithConfiguration
+ * @see SessionFactoryBuilder
+ * @see org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBuilder
+ */
+public interface HibernateConfigurationCallback {
+
+ /**
+ * Configure the given Hibernate {@code Configuration type}. Note that methods
+ * only setter methods should be called, and methods such as
+ * {@link Configuration#buildSessionFactory()} should be avoided.
+ * @throws Exception to propagate any exception thrown by
+ * {@code Configuration} methods
+ */
+ void configure(C configuration) throws Exception;
+
+}
diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateTemplate.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateTemplate.java
index 72962e4087f..d8d0a542040 100644
--- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateTemplate.java
+++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateTemplate.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2009 the original author or authors.
+ * Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,7 +40,6 @@ import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Example;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.event.EventSource;
-
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
@@ -77,10 +76,10 @@ import org.springframework.util.Assert;
* management, not participating in a custom Hibernate CurrentSessionContext
* unless you explicitly switch {@link #setAllowCreate "allowCreate"} to "false".
*
- *
{@link LocalSessionFactoryBean} is the preferred way of obtaining a reference
- * to a specific Hibernate SessionFactory, at least in a non-EJB environment.
- * The Spring application context will manage its lifecycle, initializing and
- * shutting down the factory as part of the application.
+ *
Using a {@link SessionFactoryBuilder} is the preferred way of obtaining a
+ * reference to a specific Hibernate SessionFactory, at least in a non-EJB
+ * environment. The Spring application context will manage its lifecycle,
+ * initializing and shutting down the factory as part of the application.
*
*
Note that operations that return an Iterator (i.e. iterate)
* are supposed to be used within Spring-driven or JTA-driven transactions
@@ -99,7 +98,7 @@ import org.springframework.util.Assert;
* @see #setSessionFactory
* @see HibernateCallback
* @see org.hibernate.Session
- * @see LocalSessionFactoryBean
+ * @see SessionFactoryBuilder
* @see HibernateTransactionManager
* @see org.springframework.transaction.jta.JtaTransactionManager
* @see org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateTransactionManager.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateTransactionManager.java
index ae5f3853b3c..d0910264d99 100644
--- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateTransactionManager.java
+++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/HibernateTransactionManager.java
@@ -80,8 +80,9 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
* this instance needs to be aware of the DataSource ({@link #setDataSource}).
* The given DataSource should obviously match the one used by the given
* SessionFactory. To achieve this, configure both to the same JNDI DataSource,
- * or preferably create the SessionFactory with {@link LocalSessionFactoryBean} and
- * a local DataSource (which will be autodetected by this transaction manager).
+ * or preferably create the SessionFactory with {@link SessionFactoryBuilder} /
+ * {@link LocalSessionFactoryBean} and a local DataSource (which will be
+ * autodetected by this transaction manager).
*
*
JTA (usually through {@link org.springframework.transaction.jta.JtaTransactionManager})
* is necessary for accessing multiple transactional resources within the same
@@ -116,6 +117,7 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
* @since 1.2
* @see #setSessionFactory
* @see #setDataSource
+ * @see SessionFactoryBuilder
* @see LocalSessionFactoryBean
* @see SessionFactoryUtils#getSession
* @see SessionFactoryUtils#applyTransactionTimeout
@@ -129,6 +131,7 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
* @see org.springframework.jdbc.datasource.DataSourceTransactionManager
* @see org.springframework.transaction.jta.JtaTransactionManager
*/
+@SuppressWarnings("serial")
public class HibernateTransactionManager extends AbstractPlatformTransactionManager
implements ResourceTransactionManager, BeanFactoryAware, InitializingBean {
@@ -194,7 +197,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
* The DataSource should match the one used by the Hibernate SessionFactory:
* for example, you could specify the same JNDI DataSource for both.
*
If the SessionFactory was configured with LocalDataSourceConnectionProvider,
- * i.e. by Spring's LocalSessionFactoryBean with a specified "dataSource",
+ * i.e. by Spring's SessionFactoryBuilder with a specified "dataSource",
* the DataSource will be auto-detected: You can still explictly specify the
* DataSource, but you don't need to in this case.
*
A transactional JDBC Connection for this DataSource will be provided to
@@ -208,7 +211,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
* unwrapped to extract its target DataSource.
* @see #setAutodetectDataSource
* @see LocalDataSourceConnectionProvider
- * @see LocalSessionFactoryBean#setDataSource
+ * @see SessionFactoryBuilder#setDataSource
* @see org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy
* @see org.springframework.jdbc.datasource.DataSourceUtils
* @see org.springframework.jdbc.core.JdbcTemplate
@@ -234,11 +237,11 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
/**
* Set whether to autodetect a JDBC DataSource used by the Hibernate SessionFactory,
- * if set via LocalSessionFactoryBean's setDataSource. Default is "true".
+ * if set via SessionFactoryBuilder's setDataSource. Default is "true".
*
Can be turned off to deliberately ignore an available DataSource, in order
* to not expose Hibernate transactions as JDBC transactions for that DataSource.
* @see #setDataSource
- * @see LocalSessionFactoryBean#setDataSource
+ * @see SessionFactoryBuilder#setDataSource
*/
public void setAutodetectDataSource(boolean autodetectDataSource) {
this.autodetectDataSource = autodetectDataSource;
@@ -329,11 +332,11 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
* property values before writing to and reading from the database.
* Will get applied to any new Session created by this transaction manager.
*
Such an interceptor can either be set at the SessionFactory level,
- * i.e. on LocalSessionFactoryBean, or at the Session level, i.e. on
+ * i.e. on SessionFactoryBuilder, or at the Session level, i.e. on
* HibernateTemplate, HibernateInterceptor, and HibernateTransactionManager.
- * It's preferable to set it on LocalSessionFactoryBean or HibernateTransactionManager
+ * It's preferable to set it on SessionFactoryBuilder or HibernateTransactionManager
* to avoid repeated configuration and guarantee consistent behavior in transactions.
- * @see LocalSessionFactoryBean#setEntityInterceptor
+ * @see SessionFactoryBuilder#setEntityInterceptor
* @see HibernateTemplate#setEntityInterceptor
* @see HibernateInterceptor#setEntityInterceptor
*/
@@ -504,6 +507,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
logger.debug(
"Preparing JDBC Connection of Hibernate Session [" + SessionFactoryUtils.toString(session) + "]");
}
+ @SuppressWarnings("deprecation")
Connection con = session.connection();
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
@@ -516,7 +520,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
"HibernateTransactionManager is not allowed to support custom isolation levels: " +
"make sure that its 'prepareConnection' flag is on (the default) and that the " +
"Hibernate connection release mode is set to 'on_close' (SpringTransactionFactory's default). " +
- "Make sure that your LocalSessionFactoryBean actually uses SpringTransactionFactory: Your " +
+ "Make sure that your SessionFactoryBuilder actually uses SpringTransactionFactory: Your " +
"Hibernate properties should *not* include a 'hibernate.transaction.factory_class' property!");
}
if (logger.isDebugEnabled()) {
@@ -560,6 +564,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
// Register the Hibernate Session's JDBC Connection for the DataSource, if set.
if (getDataSource() != null) {
+ @SuppressWarnings("deprecation")
Connection con = session.connection();
ConnectionHolder conHolder = new ConnectionHolder(con);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
@@ -721,6 +726,7 @@ public class HibernateTransactionManager extends AbstractPlatformTransactionMana
// the isolation level and/or read-only flag of the JDBC Connection here.
// Else, we need to rely on the connection pool to perform proper cleanup.
try {
+ @SuppressWarnings("deprecation")
Connection con = session.connection();
DataSourceUtils.resetConnectionAfterTransaction(con, txObject.getPreviousIsolationLevel());
}
diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalCacheProviderProxy.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalCacheProviderProxy.java
index e240800e0f3..bc9c6a906c8 100644
--- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalCacheProviderProxy.java
+++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalCacheProviderProxy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2008 the original author or authors.
+ * Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,16 +28,23 @@ import org.hibernate.cache.CacheProvider;
* "cacheProvider" property.
*
* @author Juergen Hoeller
+ * @author Chris Beams
* @since 2.5.1
* @see LocalSessionFactoryBean#setCacheProvider
+ * @see LocalRegionFactoryProxy
+ * @deprecated as of Spring 3.1 to reflect the deprecation of the
+ * CacheProvider SPI in Hibernate 3.3. Favor the new
+ * {@link org.hibernate.cache.RegionFactory} SPI and Spring's
+ * {@link LocalRegionFactoryProxy} support.
*/
+@Deprecated
public class LocalCacheProviderProxy implements CacheProvider {
private final CacheProvider cacheProvider;
public LocalCacheProviderProxy() {
- CacheProvider cp = LocalSessionFactoryBean.getConfigTimeCacheProvider();
+ CacheProvider cp = SessionFactoryBeanDelegate.getConfigTimeCacheProvider();
// absolutely needs thread-bound CacheProvider to initialize
if (cp == null) {
throw new IllegalStateException("No Hibernate CacheProvider found - " +
diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalDataSourceConnectionProvider.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalDataSourceConnectionProvider.java
index 29a711b3337..0af65601b1b 100644
--- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalDataSourceConnectionProvider.java
+++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalDataSourceConnectionProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2009 the original author or authors.
+ * Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ package org.springframework.orm.hibernate3;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
+
import javax.sql.DataSource;
import org.hibernate.HibernateException;
@@ -28,12 +29,12 @@ import org.hibernate.util.JDBCExceptionReporter;
/**
* Hibernate connection provider for local DataSource instances
* in an application context. This provider will be used if
- * LocalSessionFactoryBean's "dataSource" property is set
+ * SessionFactoryBuilder's "dataSource" property is set
* without a Hibernate TransactionManagerLookup.
*
* @author Juergen Hoeller
* @since 1.2
- * @see LocalSessionFactoryBean#setDataSource
+ * @see SessionFactoryBuilder#setDataSource
*/
public class LocalDataSourceConnectionProvider implements ConnectionProvider {
@@ -43,11 +44,11 @@ public class LocalDataSourceConnectionProvider implements ConnectionProvider {
public void configure(Properties props) throws HibernateException {
- this.dataSource = LocalSessionFactoryBean.getConfigTimeDataSource();
+ this.dataSource = SessionFactoryBuilderSupport.getConfigTimeDataSource();
// absolutely needs thread-bound DataSource to initialize
if (this.dataSource == null) {
throw new HibernateException("No local DataSource found for configuration - " +
- "'dataSource' property must be set on LocalSessionFactoryBean");
+ "'dataSource' property must be set on SessionFactoryBuilder");
}
this.dataSourceToUse = getDataSourceToUse(this.dataSource);
}
@@ -56,10 +57,10 @@ public class LocalDataSourceConnectionProvider implements ConnectionProvider {
* Return the DataSource to use for retrieving Connections.
*
This implementation returns the passed-in DataSource as-is.
* @param originalDataSource the DataSource as configured by the user
- * on LocalSessionFactoryBean
+ * on SessionFactoryBuilder
* @return the DataSource to actually retrieve Connections from
* (potentially wrapped)
- * @see LocalSessionFactoryBean#setDataSource
+ * @see SessionFactoryBuilder#setDataSource
*/
protected DataSource getDataSourceToUse(DataSource originalDataSource) {
return originalDataSource;
diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalJtaDataSourceConnectionProvider.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalJtaDataSourceConnectionProvider.java
index b2da29349e9..c4f204d0aa7 100644
--- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalJtaDataSourceConnectionProvider.java
+++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalJtaDataSourceConnectionProvider.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2007 the original author or authors.
+ * Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ package org.springframework.orm.hibernate3;
/**
* Subclass of LocalDataSourceConnectionProvider that will be used
- * if LocalSessionFactoryBean's "dataSource" property is set
+ * if SessionFactoryBean's "dataSource" property is set
* in combination with a Hibernate TransactionManagerLookup.
*
* @author Juergen Hoeller
diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalRegionFactoryProxy.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalRegionFactoryProxy.java
index d43196ce3fb..6e3c1d5b717 100644
--- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalRegionFactoryProxy.java
+++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalRegionFactoryProxy.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2010 the original author or authors.
+ * Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ import org.springframework.util.ReflectionUtils;
/**
* Proxy for a Hibernate RegionFactory, delegating to a Spring-managed
- * RegionFactory instance, determined by LocalSessionFactoryBean's
+ * RegionFactory instance, determined by SessionFactoryBuilder's
* "cacheRegionFactory" property.
*
*
Compatible with Hibernate 3.3 as well as Hibernate 3.5's version
@@ -41,7 +41,7 @@ import org.springframework.util.ReflectionUtils;
*
* @author Juergen Hoeller
* @since 3.0
- * @see LocalSessionFactoryBean#setCacheRegionFactory
+ * @see SessionFactoryBuilder#setCacheRegionFactory
*/
public class LocalRegionFactoryProxy implements RegionFactory {
@@ -52,11 +52,11 @@ public class LocalRegionFactoryProxy implements RegionFactory {
* Standard constructor.
*/
public LocalRegionFactoryProxy() {
- RegionFactory rf = (RegionFactory) LocalSessionFactoryBean.getConfigTimeRegionFactory();
+ RegionFactory rf = (RegionFactory) SessionFactoryBuilderSupport.getConfigTimeRegionFactory();
// absolutely needs thread-bound RegionFactory to initialize
if (rf == null) {
throw new IllegalStateException("No Hibernate RegionFactory found - " +
- "'cacheRegionFactory' property must be set on LocalSessionFactoryBean");
+ "'cacheRegionFactory' property must be set on SessionFactoryBuilder");
}
this.regionFactory = rf;
}
diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalSessionFactoryBean.java b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalSessionFactoryBean.java
index 0cb0d7335f1..40786470aba 100644
--- a/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalSessionFactoryBean.java
+++ b/org.springframework.orm/src/main/java/org/springframework/orm/hibernate3/LocalSessionFactoryBean.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2010 the original author or authors.
+ * Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,1109 +16,125 @@
package org.springframework.orm.hibernate3;
-import java.io.File;
-import java.lang.reflect.Array;
-import java.lang.reflect.Method;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.Map;
-import java.util.Properties;
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
-
import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-import org.hibernate.Session;
-import org.hibernate.SessionFactory;
-import org.hibernate.cache.CacheProvider;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
-import org.hibernate.cfg.NamingStrategy;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.FilterDefinition;
-import org.hibernate.event.EventListeners;
-import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
-import org.hibernate.transaction.JTATransactionFactory;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.BeanClassLoaderAware;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.Resource;
+import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessException;
-import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
-import org.springframework.jdbc.support.JdbcUtils;
-import org.springframework.jdbc.support.lob.LobHandler;
-import org.springframework.util.ClassUtils;
-import org.springframework.util.ReflectionUtils;
-import org.springframework.util.StringUtils;
+import org.springframework.jdbc.support.SQLExceptionTranslator;
/**
- * {@link org.springframework.beans.factory.FactoryBean} that creates a
- * Hibernate {@link org.hibernate.SessionFactory}. This is the usual way to
- * set up a shared Hibernate SessionFactory in a Spring application context;
- * the SessionFactory can then be passed to Hibernate-based DAOs via
- * dependency injection.
- *
- *
Configuration settings can either be read from a Hibernate XML file,
- * specified as "configLocation", or completely via this class. A typical
- * local configuration consists of one or more "mappingResources", various
- * "hibernateProperties" (not strictly necessary), and a "dataSource" that the
- * SessionFactory should use. The latter can also be specified via Hibernate
- * properties, but "dataSource" supports any Spring-configured DataSource,
- * instead of relying on Hibernate's own connection providers.
+ * Subclass of {@link SessionFactoryBuilder} adhering to Spring's
+ * {@link org.springframework.beans.factory.FactoryBean FactoryBean} contract,
+ * making it suitable for use in XML configuration.
*
- *
This SessionFactory handling strategy is appropriate for most types of
- * applications, from Hibernate-only single database apps to ones that need
- * distributed transactions. Either {@link HibernateTransactionManager} or
- * {@link org.springframework.transaction.jta.JtaTransactionManager} can be
- * used for transaction demarcation, with the latter only necessary for
- * transactions which span multiple databases.
+ *
A typical {@code LocalSessionFactoryBean} bean definition:
*
- *
This factory bean will by default expose a transaction-aware SessionFactory
- * proxy, letting data access code work with the plain Hibernate SessionFactory
- * and its getCurrentSession() method, while still being able to
- * participate in current Spring-managed transactions: with any transaction
- * management strategy, either local or JTA / EJB CMT, and any transaction
- * synchronization mechanism, either Spring or JTA. Furthermore,
- * getCurrentSession() will also seamlessly work with
- * a request-scoped Session managed by
- * {@link org.springframework.orm.hibernate3.support.OpenSessionInViewFilter} /
- * {@link org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor}.
+ *
+ * {@code
+ *
+ *
+ *
+ * }
*
- *
Requires Hibernate 3.2 or later; tested with 3.3, 3.5 and 3.6.
- * Note that this factory will use "on_close" as default Hibernate connection
- * release mode, unless in the case of a "jtaTransactionManager" specified,
- * for the reason that this is appropriate for most Spring-based applications
- * (in particular when using Spring's HibernateTransactionManager).
+ *
Implements the
+ * {@link org.springframework.dao.support.PersistenceExceptionTranslator
+ * PersistenceExceptionTranslator} interface, as autodetected by Spring's {@link
+ * org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor
+ * PersistenceExceptionTranslationPostProcessor}, for AOP-based translation of
+ * native Hibernate exceptions to Spring's {@link DataAccessException} hierarchy.
+ * Hence, the presence of an {@code LocalSessionFactoryBean} automatically
+ * enables a {@code PersistenceExceptionTranslationPostProcessor} to translate
+ * Hibernate exceptions.
*
* @author Juergen Hoeller
+ * @author Chris Beams
* @since 1.2
- * @see HibernateTemplate#setSessionFactory
- * @see HibernateTransactionManager#setSessionFactory
- * @see #setExposeTransactionAwareSessionFactory
- * @see #setJtaTransactionManager
- * @see org.hibernate.SessionFactory#getCurrentSession()
- * @see HibernateTransactionManager
+ * @see SessionFactoryBuilderSupport
+ * @see SessionFactoryBeanOperations
+ * @see org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean
*/
-public class LocalSessionFactoryBean extends AbstractSessionFactoryBean implements BeanClassLoaderAware {
-
- private static final ThreadLocal configTimeDataSourceHolder =
- new ThreadLocal();
-
- private static final ThreadLocal configTimeTransactionManagerHolder =
- new ThreadLocal();
-
- private static final ThreadLocal