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

我正在为我正在研究的S​​pring / 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对象的正确方法,并意识到我不需要。 相反,我可以为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删除”要慢得多。 不过,我不想重复自己。

看看Unitils吧 。 它对我们已经使用了很长一段时间的数据库测试 (使用DbUnit)有很大的支持。 它非常灵活,因此如果您发现需要将数据预加载到数据库中以进行特定的unit testing,则可以使用它。

使用Unitils,您将创建一个表示空数据库的数据集文件( empty-db.xml ):

      

在需要配置数据集的类或测试上

 @DataSet("empty-db.xml") 

我们有一个用于所有持久性测试的公共基类,因此我们能够将注释放在一个地方。

缺点是每次向Hibernate添加实体时都必须向此文件添加行。 并且您必须使订单正确以与外键约束保持一致。 我们最终添加了一个unit testing,以针对Hibernate配置检查此文件,以便对其进行检查。

另一方面,特别是对于大型模式,它比重建模式更快。