2010-10-28 70 views
6

我正在编写集成测试,并且在一种测试方法中,我想将一些数据写入数据库然后读取它。在春季设置休眠会话的刷新模式

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:applicationContext.xml"}) 
@TransactionConfiguration() 
@Transactional 
public class SimpleIntegrationTest { 

    @Resource 
    private DummyDAO dummyDAO; 

    /** 
    * Tries to store {@link com.example.server.entity.DummyEntity}. 
    */ 
    @Test 
    public void testPersistTestEntity() { 
     int countBefore = dummyDAO.findAll().size(); 
     DummyEntity dummyEntity = new DummyEntity(); 
     dummyDAO.makePersistent(dummyEntity); 

     //HERE SHOULD COME SESSION.FLUSH() 

     int countAfter = dummyDAO.findAll().size(); 

     assertEquals(countBefore + 1, countAfter); 
    } 
} 

正如你可以存储和读取数据之间看到,会议应被刷新,因为默认FushModeAUTO因此没有数据可以实际存储在数据库中。

问题:我可以一些如何设置FlushMode在会话工厂ALWAYS或其他地方,以避免重复session.flush()电话吗?

DAO中的所有数据库调用均使用HibernateTemplate实例。

在此先感谢。

+1

你可以让Spring将'SessionFactory'注入到测试中,并在'setUp'中获取当前的'Session'并调用'setFlushMode()'吗? – 2010-10-28 23:59:48

回答

0

这应该是足够了:

@ContextConfiguration(locations="classpath:applicationContext.xml") 
public class SimpleIntegrationTest extends AbstractTransactionalJUnit4SpringContextTests { 

    @Autowired(required = true) 
    private DummyDAO dummyDAO; 

    @Test 
    public void testPersistTestEntity() { 
     assertEquals(0, dummyDAO.findAll().size()); 
     dummyDAO.makePersistent(new DummyEntity()); 
     assertEquals(1, dummyDAO.findAll().size()); 
    } 
} 

从applicationContext.xml中

<bean id="transactionManager" class="org.springframework.orm.hibernate.HibernateTransactionManager"> 
    <property name="sessionFactory"> 
     <ref bean="sessionFactory"/> 
    </property> 
</bean> 

观的TransactionalTestExecutionListener的来源,如果您有任何关于交易在这种情况下如何工作的问题。

您也可以使用AOP (aspect oriented programming)来代理交易。

+0

对不起,足够了吗?我真的不明白这是如何解决存储对象后刷新休眠会话的问题。 – glaz666 2010-10-29 09:47:45

+0

虽然您已注释为事务性,但实际上并未处理任何事务。看看TransactionalTestExecutionListener类。有一个可以打开事务的beforeTestMethod和一个关闭/回滚的afterTestMethod。 – hisdrewness 2010-10-29 17:31:52

+0

我看了一下TransactionalTestExecutionListener类。它的文档清楚地表明,使用@Transactional注解的类将启动并完成方法执行周围的事务,并且如果还使用@TransactionConfiguration对类进行注释,则它将回滚。你提到的方法是“......能够执行特定的设置或拆除事务之外的代码”。所以我猜,事实上根据需要进行处理 – glaz666 2010-11-03 13:45:47

1

尝试添加以下内容:

@Autowired 
private SessionFactory sessionFactory; 

@Before 
public void myInitMethod(){ 
    sessionFactory.getCurrentSession().setFlushMode(FlushMode.ALWAYS); 
} 
1

hibernate object flushing,冲洗在以下几点默认会:

  • 在某些查询执行
  • 从org.hibernate.Transaction.commit ()
  • from Session.flush()

因此,在调用dummyDAO.findAll().size();之前,会话中的对象已经在db中刷新。设置FlushMode总是没有必要。