2012-06-21 47 views
1

我正在使用Hibernate 4.0.1.Final編寫獨立的Java應用程序。當測試我的數據訪問層,我發現了以下異常如何解決「org.hibernate.HibernateException:createCriteria無效,沒有活動事務」異常?

org.hibernate.HibernateException:爲對象進行搜索時個createCriteria也不是沒有 活動事務

有效。我試圖從我的數據庫操作代碼中分離出我的事務級代碼。我的JUnit測試是

@Before 
public void setUpDAOTest() { 
    final Configuration configuration = new Configuration(); 
    configuration.configure().setProperty("hibernate.show_sql", "false"); 
    final ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry(); 
    sessionFactory = configuration.buildSessionFactory(serviceRegistry); 
    orgDao = new OrganizationDAOImpl(sessionFactory); 
    session = sessionFactory.openSession(); 
    tx = session.beginTransaction(); 
} // setUp 

@Test 
public void testFindStateByAbbrev() { 
    final String abbrev = testProps.getProperty("test.state.abbrev"); 
    final State state = orgDao.findStateByAbbrev(abbrev); 
    Assert.assertNotNull(state); 
    Assert.assertEquals(testProps.getProperty("test.state.abbrev"), state.getAbbrev()); 
} // testFindStateByAbbrev 

和單元測試調用的代碼是...

public class OrganizationDAOImpl extends AbstractDAO implements OrganizationDAO { 
    … 
    public State findStateByAbbrev(final String abbrev) { 
     State ret = null; 
     final Session session = sessionFactory.getCurrentSession(); 
     final Criteria crit = session.createCriteria(State.class).add(Restrictions.eq("abbrev", abbrev)); 
     final List<State> results = crit.list(); 
     if (results != null && results.size() > 0) { 
      ret = results.get(0); 
     } // if 
     return ret; 
    } 

異常在該行的DAO拋出,

final Criteria crit = session.createCriteria(State.class).add(Restrictions.eq("abbrev", abbrev)); 

我怎麼能調整我的JUnit測試(或我的DAO代碼)以消除此異常並使我的代碼正常運行?這是我的hibernate.cfg.xml文件...

<?xml version='1.0' encoding='utf-8'?> 
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 

<hibernate-configuration> 
    <session-factory> 
     <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 
     <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/dbid</property> 
     <property name="hibernate.connection.username">user</property> 
     <property name="hibernate.connection.password">password</property> 
     <property name="hibernate.connection.pool_size">10</property> 
     <property name="show_sql">true</property> 
     <property name="dialect">org.hibernate.dialect.MySQLDialect</property> 

     <!-- Enable Hibernate's automatic session context management --> 
      <property name="current_session_context_class">thread</property> 

     <mapping class="org.myco.myproject.orgsclient.model.Organization" /> 
     <mapping class="org.myco.myproject.orgsclient.model.State" /> 

    </session-factory> 
</hibernate-configuration> 

回答

9

您可以移動

session = sessionFactory.openSession(); 
tx = session.beginTransaction(); 

您的DAO方法內部或新會話綁定到@Before方法當前線程。

您已指定休眠應使用ThreadLocalSessionContext。但是,沒有什麼可以將Session綁定到當前線程。

ThreadLocalSessionContext提供了一個靜態的bind(org.hibernate.Session session)方法,您可以使用它確保sessionFactory.getCurrentSession()可以訪問您打開的會話。

只是打開一個新的會話不會將其綁定到線程。

+1

ThreadLocalSessionContext.bind(session);挽救了一天。非常感謝。 OTher建議我將事務代碼與數據庫操作代碼分開。 – Dave

+1

你能告訴我你在哪裏添加了綁定方法?我在我的grails項目中遇到了這個問題。我正在使用休眠3,現在升級到休眠4 .. – Swaprks

相關問題