如何不持久作为活动会话一部分的对象(并映射)

时间:2012-05-16 08:13:32

标签: hibernate

对于我正在进行的项目,我正在添加导入/导出功能。这样做没问题。

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

所以,我的设置是:

  1. 通过spring mvc(使用OpenSessionInView)获取导入数据
  2. 将其反序列化为我的域类(实际映射的hibernate类)
  3. 扫描所有内容并确保引用等正常。
  4. 我的所有服务都有@Transactional围绕他们
  5. 这基本上没问题,但某处......触发了保存(我从不调用保存),我的分组对象抱怨瞬态引用..这是正确的,因为它没有保存..我假设这是hibernate有一些默认模式,因为分组对象引用了另一个被映射的对象。那么如何确保hibernate永远不会保存任何东西呢?不删除@Transactional和OpenSessionInView(正常情况下需要)

    有什么想法吗?

    此致 的Morten

2 个答案:

答案 0 :(得分:2)

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

选项:

  • 保持实施并在最后回滚所有内容。它只有在您不想同时更改数据库中的某些内容时才有效(例如,发生干运行的日志)。
  • 设置刷新模式=从不并且避免调用“保存”和“更新”。这有点像hacky。
  • 将对干运行重要的所有内容拖到验证类中,验证类不会更改任何实体并仅运行此实体。这是最复杂但也是最干净的解决方案。

答案 1 :(得分:2)

你说

  

某处......触发了保存

“某处”在堆栈跟踪中,除了异常之外。

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

有几种解决方案:

  1. 创建两种导入方法。新的.importXmlDryRun()必须没有@Transactional注释。那个可能会工作,但即使我现在无法给他们命名,我的直觉也会让我发出警告。

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

  3. 获取休眠会话并致电clear()docs