截断所有表的简单方法,清除一级和二级hibernate缓存?

时间:2010-06-25 22:05:00

标签: java unit-testing hibernate orm

我正在为我正在研究的S​​pring / Hibernate应用程序编写一些集成测试,我想尽可能接近真实条件进行测试,包括使用Hibernate的二级缓存和提交事务。

我想知道是否有一种有效的方法让Hibernate从数据库和缓存中删除所有内容。我能想到的最好的就是为每种类型的对象使用HQL“从XImpl删除”行,但我有几十个域对象,感觉应该有更好的方法。

3 个答案:

答案 0 :(得分:5)

对于数据库,使用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()

答案 1 :(得分:1)

采用上面的Pascal方法,我一直在寻找在Spring中创建SchemaUpdate对象的正确方法,并意识到我不需要。相反,我可以为Hibernate获取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删除”要慢得多。不过,我不想重复自己。

答案 2 :(得分:1)

看看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配置检查此文件,以便对其进行检查。

特别是对于大型架构而言,它的优势在于它比重建架构更快。