title: testing Hibernate with Spring's EmbeddedDatabaseBuilder issues with SpringSessionContext
body: <p>I am unit-testing with Spring Framework's <code>EmbeddedDatabaseBuilder</code> as a datasource and passing this into the Hibernate config for my <code>SessionFactory</code>, using Spring 4 and Hibernate 4. <em>I am not using the Spring context in any way</em> - the only config I use is programmatic (no annotations, no XML except the Hibernate mapping files).</p>
  
  <p>I expected that Hibernate would use its default <code>ThreadLocalSessionContext</code> and that I would be able to start and rollback transactions in the unit test. </p>
  
  <p>However somehow Hibernate has set its <code>SessionFactory.currentSessionContext</code> to Spring's <code>SpringSessionContext</code> and this complains whenever I try to call <code>SessionFactory.getCurrentSession()</code>:</p>
  
  <pre><code>HibernateException: Could not obtain transaction-synchronized Session for current thread
      at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134)
      at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
  </code></pre>
  
  <p>In the code below in my unit test, I have set <code>hibernate.current_session_context_class</code> to <strong><code>thread</code></strong> but this is ignored or replaced with the Spring implementation. </p>
  
  <pre><code>public abstract class HibernateTestBase {
  
      private static EmbeddedDatabase dataSource;
      private static SessionFactory sessionFactory;
      private Session session;
  
      @BeforeClass
      public static void setupClass() {
          dataSource = new EmbeddedDatabaseBuilder().
                  setType(EmbeddedDatabaseType.H2).
                  addScript("file:SQLResources/schema-1.1.sql").
                  addScript("file:SQLResources/schema-1.2.sql").
                  build();
          Configuration configuration = new Configuration();
          configuration.addResource("hibernate-mappings/HierarchyLevel.hbm.xml");
          configuration.addResource("hibernate-mappings/HierarchyFilter.hbm.xml");
          configuration.addResource("hibernate-mappings/AuditLog.hbm.xml");
          configuration.setProperty("hibernate.dialect",
                  "org.hibernate.dialect.Oracle10gDialect");
          configuration.setProperty("hibernate.show_sql", "true");
          configuration.setProperty("hibernate.current_session_context_class",
                  "thread");
          StandardServiceRegistryBuilder serviceRegistryBuilder =
                  new StandardServiceRegistryBuilder();
          serviceRegistryBuilder.applySetting(Environment.DATASOURCE, dataSource);
          serviceRegistryBuilder.applySettings(configuration.getProperties());
          StandardServiceRegistry serviceRegistry =
                  serviceRegistryBuilder.build();
          sessionFactory = configuration.buildSessionFactory(serviceRegistry);
          sessionFactory.openSession();
      }
  
      @AfterClass
      public static void tearDown() {
          if (sessionFactory != null) {
              sessionFactory.close();
          }
          if (dataSource != null) {
              dataSource.shutdown();
          }
      }
  
      @Before
      public final void startTransaction() {
          session = sessionFactory.getCurrentSession();
          session.beginTransaction();
      }
  
      @After
      public final void rollBack() {
          session.flush();
          Transaction transaction = session.getTransaction();
          transaction.rollback();
      }
  }
  </code></pre>
  
  <p>I am forced to call <code>SessionFactory.openSession()</code> instead but then I won't be able to use my DAOs with the same <code>SessionFactory</code> because they all call <code>getCurrentSession()</code>. So I won't be able to benefit from the already coded data handling functionality.</p>
  
  <p>What can I do?</p>