0

对于我正在处理的项目,我正在添加导入/导出功能。这工作正常,没有问题。

我现在要做的是有一个名为“dryRun”的选项,它允许用户在实际执行任何操作之前测试导入,然后返回报告。

所以,我的设置是:

  1. 通过spring mvc(使用OpenSessionInView)获取导入数据
  2. 将其反序列化为我的域类(这是实际映射的休眠类)
  3. 扫描所有内容并确保引用等都正常。
  4. 我所有的服务都有一个@Transactional

这大部分都可以,但是在某个地方..触发了保存(我从不调用保存),并且我的分组对象抱怨瞬态引用..这是正确的,因为它没有保存..我认为这是某种默认模式休眠具有,因为分组对象引用另一个映射的对象。那么我怎样才能确保休眠永远不会保存任何东西?不删除 @Transactional 和 OpenSessionInView (正常情况下需要)

有任何想法吗?

问候,莫腾

4

2 回答 2

2

你说

某处..触发保存

那个“某处”在你得到的堆栈跟踪中,但有例外。

[编辑]堆栈跟踪基本上说“方法 MetaDataController.importXml() 用 @Transactional 注释”。当它返回时,Hibernate 尝试按应有的方式提交事务,然后,它偶然发现了一个未保存的依赖项OrganisationUnitGroup(是的,如果它会说哪个字段包含依赖项会很好,因为 Hibernate 也知道这一点)。

有几种解决方案:

  1. 创建两个导入方法。新的,.importXmlDryRun()不能有@Transactional注释。这可能会奏效,但我的直觉提醒我注意问题,即使我现在无法说出它们的名字。

  2. 请求空运行时抛出异常.importXml()以中止事务,并在默认处理程序中忽略此异常。该异常将导致 Hibernate 回滚。这是最安全的解决方案。

  3. 获取休眠会话并调用clear()文档

于 2012-05-16T08:36:23.637 回答
2

Hibernate 隐式存储实体中的更改。这是它持久性无知的一部分,这实际上是非常重要的。(请参阅此问题。)您可以通过将刷新模式设置为从不来关闭它,但通常不建议这样做。如果您在导入代码中有查询,他们不会考虑内存的变化并返回不同的结果(这可能会破坏空运行的目的)。

选项:

  • 让您执行并在最后回滚所有内容。它仅在您不想同时更改数据库中的某些内容时才有效(例如,发生空运行的日志)。
  • 设置刷新模式 = 从不,避免调用“保存”和“更新”。这有点骇人听闻。
  • 将所有对干运行重要的东西拉到一个不会更改任何实体并且只运行这个的验证类。这是最复杂但也是最干净的解决方案。
于 2012-05-16T08:22:36.847 回答