【问题标题】:JPA EntityManager : save objects only when explicitly requestedJPA EntityManager:仅在明确请求时保存对象
【发布时间】:2020-05-29 13:36:53
【问题描述】:

我对 Hibernate 和 JPA 还很陌生,目前正在开发一个通过 JPA 的 EntityManager 使用它的应用程序。

在查看一些使用 Hibernate session 的基本 hibernate 教程时,我发现我可以做到:

val session = HibernateUtil.getSessionFactory().getCurrentSession()
session.beginTransaction()
val coordinates = session.find(Coordinates::class.java, "12345")
coordinates.longitude = 0.0
session.save(coordinates)
session.getTransaction().commit()

使用Entitymanager时,是这样完成的:

val em = emFactory.createEntityManager()
em.transaction.begin()
val coordinates = em.find(Coordinates::class.java, "12345")
coordinates.longitude = 0.0
em.transaction.commit()

这里的主要区别在于,使用 EntityManager,我不必显式调用 save 函数来实际更新对象,该对象最终将在提交期间刷新。当然,我可以做类似的事情

if(obj.id == null) {
    return em.merge()
} else {
    val saved = em.persist(obj)
    return saved
}

但是,如果已经存在的对象无论如何都被保存了,那又有什么意义呢?无论我是否调用它?

令人惊讶的是,这里发现的examples 似乎也依赖于保存方法。

我的问题是:有没有办法将 EntityManager 配置为仅在特别请求时才更新对象(即模仿会话行为)?还是我必须使用 Session 来实现这一点?

【问题讨论】:

  • 实体经理的想法是,顾名思义,他管理实体(与实体经理所在的事务相关联)。也许您需要解释您的实际问题,以使我们了解您想要实现的目标,而不是询问 JPA 的技术细节。 EM 上的merge 可用于 e。 G。将实体重新附加到会话,而无需重新加载实体并根据分离的实体填充字段。
  • 我当然明白。我的问题正是我所描述的:仅在被要求时才要求我保存实体(即调用保存方法,这意味着如果未明确保存,则应丢弃已修改的实体)。我正在尝试估计是否可以使用现有的 EntityManager 进行快速修复,或者我是否必须切换到使用 Session,这将花费更多。
  • 如果您不想更改实体,为什么还要更改它们? ;-) 一个简单的“突破”请求丢弃​​ JEE 中所有更改的方法是抛出一个 @ApplicationException(rollback=true),正如它的参数所暗示的,这会导致事务回滚。
  • 但是我的观点仍然有效:您没有提到为什么要放弃对实体的更改,只是说您想要这种可能性。
  • 实际上有几个原因:在某些情况下,实体被修改但随后出现一些业务规则要求丢弃这些更改(您可以质疑代码结构的有效性,但对于现在是这样写的)。另一点是,这段代码来自一个最初没有使用 RDBMS 的应用程序(而是一个 nosql 数据存储),它没有任何持久性上下文的概念。所有这些都在常规 CRUD 调用之后被抽象出来,所以我被要求尽可能保持相同的行为。但我想这回答了我的问题:)

标签: java hibernate jpa kotlin entitymanager


【解决方案1】:

merge 是 EntityManager 实际执行数据库操作的机会。合并、持久化、刷新和提交基本上都是与数据库的接触点。

对于简单的情况,您可以简单地依靠在提交时更改行为而不是物理合并自己,但许多人喜欢控制知道何时实际发生。知道“在此之后,它在数据库中”。因为在合并之后,不仅数据和任何级联行为都被持久化了,而且数据库上的触发器等的任何副作用也发生了。

他们没有承诺,但他们已经发生了。为父母和孩子分配了键,触发了触发器,触发了生命周期方法,一切都是“应有的”、“现在”和“将来的某个时间”,即使这可能只有几毫秒的时间。

【讨论】:

  • 这些我都知道,但感谢您非常清楚的解释 :)
猜你喜欢
  • 2016-04-06
  • 2016-05-07
  • 2020-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多