【发布时间】:2017-10-06 18:43:24
【问题描述】:
我正在编写两种方法来在我的应用程序中重新初始化数据库。 首先应该动态列出所有表,然后截断它们。第二个负责数据重新填充。
Truncate 方法使用原生查询:
public void truncate() throws Exception {
List<String> names = getAllTableNames();
names.forEach(tableName -> {
entityManager.createNativeQuery("TRUNCATE TABLE " + tableName + " CASCADE").executeUpdate();
});
// entityManager.setFlushMode(FlushModeType.COMMIT);
// entityManager.getEntityManagerFactory().getCache().evictAll();
entityManager.flush();
}
数据重新初始化的第二种方法只是解析一些文档,创建实体并批量保存。
这两种方法都位于标记为@Transactional 的服务中。
我有两个端点可以分别调用它们。
现在发生的情况是,在我截断表后(没有错误结束)我调用 re-init 并得到:
WARNING: org.springframework.dao.DataIntegrityViolationException: A different object with the same identifier value was already associated with the session : [com.nws.vedica.model.entity.DocType#ACCOUNTCONTRACTCANCEL]; nested exception is javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [com.nws.vedica.model.entity.DocType#ACCOUNTCONTRACTCANCEL]
就好像实体仍然存在于 EM 的缓存中一样。
在 EM 的缓存(注释行)之后驱逐后也会发生同样的情况。
现在有两个观察结果:
1.- 第二次重新创建实体的请求总是成功的。
2.- 如果我运行重新创建两次(第一次成功,第二次失败)然后截断然后重新创建,则重新创建请求在截断操作之后成功。 --很奇怪
请指导我发生了什么以及如何使其正常工作。
谢谢!
编辑:
我注意到打电话后
truncateDatabaseSrv.truncate();
当我尝试查询集合时程序挂起:
List<DocType> docTypes = docTypeDAO.getAllDocTypes();
所以我放了
entityManager.createNativeQuery("COMMIT;").executeUpdate();
进入截断方法。
现在它不会挂起,会按预期返回空数组。但是当我在下一个请求中调用 DocType 集合重新初始化时,我仍然得到与上述相同的错误。
我还注意到截断后正在进行 diry-checking:
2:05:04,200 DEBUG AbstractFlushingEventListener:132 - Processing flush-time cascades
12:05:04,202 DEBUG AbstractFlushingEventListener:174 - Dirty checking collections
12:05:04,203 DEBUG Collections:189 - Collection found: [com.nws.vedica.model.entity.DocType.fieldValidities#ACCOUNTCONTRACTCANCEL], was: [com.nws.vedica.model.entity.DocType.fieldValidities#ACCOUNTCONTRACTCANCEL] (initialized)
12:05:04,203 DEBUG Collections:189 - Collection found: [com.nws.vedica.model.entity.DocType.keywords#ACCOUNTCONTRACTCANCEL], was: [com.nws.vedica.model.entity.DocType.keywords#ACCOUNTCONTRACTCANCEL] (initialized)
12:05:04,204 DEBUG Collections:189 - Collection found: [com.nws.vedica.model.entity.DocType.fieldValidities#ACCOUNTDEBTSLIENCONTRACT], was: [com.nws.vedica.model.entity.DocType.fieldValidities#ACCOUNTDEBTSLIENCONTRACT] (initialized)
(initialized) 对我来说似乎很可疑,但这就是我这次的全部内容......
【问题讨论】:
-
我对 Hibernate 生疏了...您是否尝试过类似的方法: entityManager.getTransaction().commit() ?
-
一旦您尝试获取交易表单 em,它就会失败。在截断操作之前。错误说,tx 已经被管理..(我想通过@Transactional 注释)
标签: java hibernate jpa transactions nativequery