【问题标题】:merging / re-attaching IN JPA / Hibernate without updating the DB在不更新数据库的情况下合并/重新附加 IN JPA / Hibernate
【发布时间】:2010-05-10 09:26:43
【问题描述】:

在 OSIV Web 环境中使用 JPA/Hibernate 让我发疯;)

以下场景:我有一个通过 JPA 加载的实体 A,并且有一个 B 实体的集合。那些 B 实体有一个必填字段。

当用户通过在 webapp 中按下链接将新的 B 添加到 A 时,不会设置该必填字段(因为没有合理的默认值)。

在下一个 http 请求时,OSIV 过滤器尝试合并 A 实体,但由于 Hibernate 抱怨新 B 的必填字段未设置,因此失败。

javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value

阅读 JPA 规范,我没有看到合并阶段需要这些检查的迹象(我没有活动的事务)

我不能将 B 的集合保留在 A 之外,只有在用户按下“保存”(又名 entitymanager.persist())时才将它们添加到 A,因为保存按钮所在的位置不知道 B ,仅关于 A。

A 和 B 也只是例子,我到处都有类似的东西..

有什么想法吗?其他 JPA 实现在这里的行为是否相同?

提前致谢。

【问题讨论】:

    标签: java hibernate web-applications jpa


    【解决方案1】:

    我做了很多阅读和测试。问题来自我对 JPA / Hibernate 的误解。 merge() 总是对数据库产生影响,并为实体安排更新。我在 JPA 规范中没有发现任何提及这一点,但“Java Persistence with Hibernate”一书中确实提到了它。

    通过 EntityManager(和作为后备的 Session)API 来看,似乎没有办法在不安排更新的情况下将实体分配给当前的持久上下文。毕竟,我想要的是导航对象图,根据需要更改属性并稍后触发更新(如果需要,请进行版本检查)。我认为每个使用 ORM 的 Webapp 都必须做的事情?

    我正在寻找的基本工作流程:

    1. 从数据库中加载一个实体(或创建一个新实体)
    2. 让实体(及其所有关联变得分离(因为 EntitManager 在 HTTP 请求结束时关闭)
    3. 当下一个 HTTP 请求进来时,再次使用这些对象,在树中导航而不用担心 LazyInitExceptions
    4. 调用一个方法来持久化 1-3) 期间所做的所有更改

    使用 spring 的 OSIV 过滤器和 wicket 的 IModel 实现,我想我已经存档了。

    我基本上看到了两种可能的方法:

    a) 在进入某个页面(用例)时加载实体和所有需要的关联,让它们分离,在几个 http 请求的过程中根据需要添加/更改它们。当用户启动保存时重新附加它们(验证器将确保有效状态)并将它们提交到数据库。

    b) 使用当前设置,但确保所有新添加的实体都设置了所有必填字段(可能使用一些向导组件)。对于每个merge(),我仍然会对数据库进行所有更新,但希望数据库管理员不会意识到;)

    其他人如何在 Web 环境中使用 JPA?我还有其他选择吗?

    【讨论】:

      猜你喜欢
      • 2011-04-07
      • 1970-01-01
      • 1970-01-01
      • 2013-04-30
      • 1970-01-01
      • 1970-01-01
      • 2010-10-18
      • 2014-05-13
      • 2018-07-06
      相关资源
      最近更新 更多