我正在为我正在编写的Spring/Hibernate应用程序编写一些集成测试,并且我想尽可能接近真实条件来测试,包括使用Hibernate的二级缓存和提交事务。简单的方法来截断所有表,清除第一级和第二级休眠缓存?
我想知道是否有一种有效的方法让Hibernate从数据库和缓存中删除所有内容。我能想到的最好方法是使用HQL“从XImpl中删除”行来查看每种类型的对象,但我有几十个域对象,感觉应该有更好的方法。
我正在为我正在编写的Spring/Hibernate应用程序编写一些集成测试,并且我想尽可能接近真实条件来测试,包括使用Hibernate的二级缓存和提交事务。简单的方法来截断所有表,清除第一级和第二级休眠缓存?
我想知道是否有一种有效的方法让Hibernate从数据库和缓存中删除所有内容。我能想到的最好方法是使用HQL“从XImpl中删除”行来查看每种类型的对象,但我有几十个域对象,感觉应该有更好的方法。
对于数据库,使用SchemaExport
工具来重新架构:
Configuration cfg = ....;
new SchemaExport(cfg).create(false, true);
对于二级缓存,从SessionFactory
获得访问底层的缓存区域和驱逐一切:
SessionFactory sf = ...;
Cache cache = sf.getCache();
cache.evictEntityRegions();
cache.evictCollectionRegions();
cache.evictQueryRegions();
对于一级缓存,只需获取新的Session
或致电session.clear()
。
考虑到上面的Pascal方法,我找到了在Spring中创建SchemaUpdate对象的正确方法,并意识到我不需要。相反,我可以获取Spring的SessionFactory对象,并要求它放弃/创建模式。结合Pascal的解决方案的其余部分,我们得到这个:
LocalSessionFactoryBean localSessionFactoryBean = (LocalSessionFactoryBean)appContext.getBean("&sessionFactory");
localSessionFactoryBean.dropDatabaseSchema();
localSessionFactoryBean.createDatabaseSchema();
Cache cache = sf.getCache();
cache.evictEntityRegions();
cache.evictCollectionRegions();
cache.evictQueryRegions();
这是非常有效的。唯一的缺点是(至少对我来说)比每个表名称中的“从obj1中删除”,“从obj2中删除”要慢得多。不过,我喜欢不必重复自己。
看看Unitils。它对database testing(使用DbUnit)有很大的支持,我们已经使用了很长一段时间。它非常灵活,所以如果您发现需要将数据预加载到数据库中以进行特定的单元测试,那么您可以使用它。
随着Unitils,您将创建表示空数据库中的数据集文件(empty-db.xml
):
<?xml version='1.0' encoding='UTF-8'?>
<dataset>
<obj1/>
<obj2/>
</dataset>
在需要配置数据集
@DataSet("empty-db.xml")
类或测试我们对所有持久性测试都有一个共同的基类,所以我们能够将注释放在一个地方。
不利的一面是,每次向Hibernate添加实体时,您都必须为此文件添加行。而且您必须获得与外键约束一致的订单。我们最终添加了一个单元测试来检查这个文件是否与Hibernate配置保持一致。
另一方面,特别是对于大型模式,它的速度比重建模式要快。
SchemaExport!非常棒的主意 - 星期一我会尝试一下。 – 2010-06-27 20:49:07