Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Can';刷新后,在Hibernate会话之外看不到更改_Java_Spring_Hibernate_Flush - Fatal编程技术网

Java Can';刷新后,在Hibernate会话之外看不到更改

Java Can';刷新后,在Hibernate会话之外看不到更改,java,spring,hibernate,flush,Java,Spring,Hibernate,Flush,我将Spring3.1.2与Hibernate4一起使用 我有一个用@Repository注释的DAO实现类MyDaoImpl,以便启用异常转换。我有一个服务类MyService,用@Transactional注释如下: public class MyDaoImpl implements MyDao { private SessionFactory sessionFactory; @Autowired public void setSessionFactory(Ses

我将Spring3.1.2与Hibernate4一起使用

我有一个用
@Repository
注释的DAO实现类
MyDaoImpl
,以便启用异常转换。我有一个服务类
MyService
,用
@Transactional
注释如下:

public class MyDaoImpl implements MyDao {

    private SessionFactory sessionFactory;

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
       this.sessionFactory = sessionFactory;
    }

    @Override
    public void saveA(A a)
    {
        this.sessionFactory.getCurrentSession().saveOrUpdate(a);
    }
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:beans.xml" })
@Transactional
public class MyDaoImplTest implements IMyDaoImplTest {

    private MyDao myDao;

    private SessionFactory sessionFactory;

    @Autowired
    public void setMyDao(MyDao myDao)
    {
        this.myDao = myDao;
    }

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }

    @Test
    @Override
    public void testCreateA()
    {
       A a = new A("A1");
       this.myDao.saveA(a);

       this.sessionFactory.getCurrentSession().flush();

       IDataSet databaseDataSet = this.getConnection().createDataSet();
       ITable actualTable = databaseDataSet.getTable("Applications");

   IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(this.getClass().getClassLoader().getResourceAsStream("test-data/applications/savenew.xml"));
   ITable expectedTable = expectedDataSet.getTable("Applications");

   Assertion.assertEquals(expectedTable, actualTable);
    }
}
我编写了一个单元测试类
MyDaoImplTest
,如下所示:

public class MyDaoImpl implements MyDao {

    private SessionFactory sessionFactory;

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
       this.sessionFactory = sessionFactory;
    }

    @Override
    public void saveA(A a)
    {
        this.sessionFactory.getCurrentSession().saveOrUpdate(a);
    }
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:beans.xml" })
@Transactional
public class MyDaoImplTest implements IMyDaoImplTest {

    private MyDao myDao;

    private SessionFactory sessionFactory;

    @Autowired
    public void setMyDao(MyDao myDao)
    {
        this.myDao = myDao;
    }

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory)
    {
        this.sessionFactory = sessionFactory;
    }

    @Test
    @Override
    public void testCreateA()
    {
       A a = new A("A1");
       this.myDao.saveA(a);

       this.sessionFactory.getCurrentSession().flush();

       IDataSet databaseDataSet = this.getConnection().createDataSet();
       ITable actualTable = databaseDataSet.getTable("Applications");

   IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(this.getClass().getClassLoader().getResourceAsStream("test-data/applications/savenew.xml"));
   ITable expectedTable = expectedDataSet.getTable("Applications");

   Assertion.assertEquals(expectedTable, actualTable);
    }
}
根据Spring文档,我在更改后刷新会话以避免误报。问题是,刷新后,如果我在Hibernate之外访问DB(例如使用DBUnit),我看不到更改,因此我的断言总是失败


我的配置有什么问题?

这是预期的行为。刷新与事务提交是不同的概念。只有在提交后才能看到事务外部的更改。

如果要在事务提交后检查数据库的状态,有两个选项:

  • 签入带有
    @posterTransaction
    注释的方法。此方法将在
    @Tranactional
    测试方法定义的事务结束后由Spring JUnit runner执行。不要忘记禁用自动事务回滚
    (@TransactionConfiguration(defaultRollback=false)
    )。如果您需要对不同的测试方法进行不同的检查,您可以执行以下操作:

    private Runnable check;
    
    @AfterTransaction
    public void performCheck() {
        if (check != null) check.run();
    }
    
    @Test
    @Override
    public void testCreateA() {
        ... // Code being tested
        check = new Runnable() {
            public void run() {
                ... // Code to check the state
            }
        };
    }
    
  • 在测试方法中使用编程事务划分:

    private TransactionTemplate tx;
    
    @Autowired
    private void setTransactionManager(PlatformTransactionManager ptm) {
        tx = new TransactionTemplate(ptm);
    }
    
    @Test
    @Override
    @Transactional(progrgation = Propagation.NOT_SUPPORTED) // Disable declarative transaction
    public void testCreateA() {
        tx.execute(...); // Code to test
        tx.execute(...); // Check
    }
    

或者,如果您的目标是使用DbUnit检查Hibernate刷新的结果,则可以在同一事务中执行,例如,使用
sessionFactory.getCurrentSession().doWork(…)

谢谢您的回答。那么,我测试刀的方式有什么问题?通过这种方式,我看不到更改,因此无法测试我的DAO。您的测试将需要在同一会话/事务中检索数据。@DanMatthews问如何在同一会话/事务中使用DBUnit?DBUnit直接与数据库通信。