截断所有表的简单方法,清除一级和二级hibernate缓存?
我正在为我正在研究的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对象的正确方法,并意识到我不需要。 相反,我可以为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配置检查此文件,以便对其进行检查。
另一方面,特别是对于大型模式,它比重建模式更快。
- SessionFactory始终为null – Spring + Hibernate
- 将提取更改为EAGER似乎可以修复无关的会话缓存问题
- 在Hibernate Envers中获取以前版本的实体
- JPA Hibernate希望延迟加载返回空集合
- 如何使用JPA(Hibernate)创建与同一实体的关系?
- 将自定义标识符分配给@id属性
- JTASessionContext与JDBCTransactionFactory一起使用; 使用getCurrentSession()自动刷新将无法正常运行
- javax.persistence.PersistenceException:未找到类或包
- 如何使用Hibernate Context会话创建Generic DAO类