1

我在独立应用程序中使用 Hibernate 4.0.1.Final。底层数据库是 MySQL 5.5。使用 JUnit 4.8.1,我正在测试我的数据访问对象,并希望运行测试,以便当我的 JUnit 测试结束时,我的所有更改都会回滚。有没有一种优雅的方式来做到这一点?现在,一切都在进行中,这是有道理的。这是我的 JUnit 测试……</p>

@Before
public void setUp() throws IOException { 
    final InputStream in = getClass().getClassLoader().getResourceAsStream("test.properties");
    testProps = new Properties();
    testProps.load(in);
    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);
}   // setUp

@Test
public void testInsertSchool() { 
    final Organization org = new Organization();
    org.setOrganizationId(testProps.getProperty("test.id"));
    org.setName(testProps.getProperty("test.name"));
    orgDao.saveOrUpdate(org);
    final Organization foundOrg = orgDao.findById(org.getOrganizationId());
    Assert.assertEquals(org, foundOrg);
}

这是来自数据访问对象的代码……</p>

protected void saveOrUpdate(Object obj) {
    try {
        startOperation();
        session.saveOrUpdate(obj);
        tx.commit();
    } catch (HibernateException e) {
        handleException(e);
    } finally {
        session.close();
    }
}

protected Object find(Class clazz, Serializable id) {
    Object obj = null;
    try {
        startOperation();
        obj = session.get(clazz, id);
        tx.commit();
    } catch (HibernateException e) {
        handleException(e);
    } finally {
        session.close();
    }
    return obj;
}
4

2 回答 2

1

我决定使用 HSSql 内存数据库,如此处所述——http: //vageeshhoskere.wordpress.com/2011/06/16/unit-test-with-junit-for-hibernate-using-hsqldb -内存中/。这样,我可以重复运行 JUnit 测试(在服务级别),并保证每次运行它们时世界的状态都是相同的。

于 2012-06-22T20:25:06.003 回答
0

The way to do that would be to separate out your commits and session closes from your database operations. I actually think it's better to do that anyhow because not every database operation should be its own transaction. There are significant advantages to being able to use the same session in multiple operations and to use the same transaction for multiple operations.

The way I'd characterize the transaction layer is it's a business rule concern, as they define atomic units of work at the database level. It ought to be one layer out from the layer that abstracts hibernate operations for persist, find, and merge. Heres why:

  1. Doing this will allow a lot greater flexibility in how you design your application's business rules to handle new cases in which different database operations are interdependent without forcing you to write a million methods in that database object just to handle the different transaction rules for each case.
  2. Not only that, moving those operations out allows you to achieve what you want in your unit tests.
  3. Open/Close operations are expensive, if you're doing 5 queries in a row and there's no reason for them to be in a separate session, you shouldn't be opening and closing 5 sessions.
于 2012-06-21T14:38:06.237 回答