使用休眠截断所有表的最佳方法?
我想截断一个集成测试与另一个集成测试之间的所有数据库表。使用休眠来执行此操作的最佳方法是什么?
目前我正在这样做:
public void cleanDatabase() {
doWithSession(new Action1<Session>() {
@Override
public void doSomething(Session session) {
SQLQuery query = session.createSQLQuery("truncate table stuff");
// todo - generify this to all tables
query.executeUpdate();
}
});
(doWithSession 是一个创建和关闭会话的小包装器)。我可以使用反射迭代所有映射的对象...我想知道是否有人已经解决了这个问题。
I would like to truncate all my database tables between one integration test to another. What is the best way to do this using hibernate?
Currently I'm doing this:
public void cleanDatabase() {
doWithSession(new Action1<Session>() {
@Override
public void doSomething(Session session) {
SQLQuery query = session.createSQLQuery("truncate table stuff");
// todo - generify this to all tables
query.executeUpdate();
}
});
(doWithSession is a small wrapper that creates and closes a session). I could iterate on all my mapped objects using reflection ... I'm wondering if someone already solved this problem.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我猜你可能没有使用Spring。如果你这样做了, Spring 的事务测试支持将是理想的。
简而言之:Spring 在每个测试用例之前自动启动一个事务,并在测试用例之后自动回滚它,为您留下一个空(或至少未更改)的数据库。
也许您可以模仿该机制:
在
@Before
方法中打开事务,在@After
方法中回滚它。I guess you probably don't use Spring. If you did, Spring's transactional test support would be ideal.
In short: Spring automatically starts a transaction before each test case and automatically rolls it back after the test case, leaving you with an empty (or at least unchanged) database.
Perhaps you could just mimic that mechanism:
Open a transaction in a
@Before
method, roll it back in an@After
method.我正是为此目的编写了一个积分器。基本上,我们连接到会话工厂创建流程,迭代 Hibernate 找到的表映射,并对每个表执行 TRUNCATE TABLE xxx。由于我们无法截断具有外键约束的表,因此在截断操作之前禁用外键检查,然后重新启用。
用法:我们必须在会话工厂创建流程中使用这个
Integrator
,并且还需要为每个测试创建一个新的会话工厂。I wrote an integrator exactly for this purpose. Basically, we hook into the session factory creation flow, iterating over the table mappings found by the Hibernate, and the execute
TRUNCATE TABLE xxx
for each table. Since we couldn't truncate tables with foreign key constraints, foreign key checks disabled before truncation operation and then re-enabled.Usage: We have to use this
Integrator
in session factory creation flow, and also need to create a new session factory for each test.你看过内存中的mysql http://dev.mysql.com/downloads/connector/mxj /?每次测试后是否也无法回滚?我相信你可以像这样配置它。
Have you looked at in memory mysql http://dev.mysql.com/downloads/connector/mxj/? also is it not possible to rollback after each test? I believe you can configure it like so.
您可以使用 SchemaExport,尽管这看起来相当严厉。回滚事务听起来是一个更好的主意。
You could probably drop and recreate the Hibernate schema using SchemaExport, although that seems pretty heavy-handed. Rolling back a transaction sounds like a better idea.
您可以使用内存数据库并在测试之间删除完整的数据库。
如果您的测试不多但时间较长,则可以使用这种方式。
但请注意,每个数据库的行为都与其他数据库有所不同。因此,在某些情况下,使用内存数据库(例如 HyperSQL)的行为与普通数据库的行为并不完全相同 - 因此这不是正确的集成测试。
You could use a in memmory database and drop the complete database between your tests.
You can use that way if you have not so many but long tests.
But be aware that every database behaves a bit different then all other. So using an in memory database (for example HyperSQL) will not behave exactly like your normal data base in some cases - so it is not a correct integration test.