JPA EntityManager:仅在显式请求时保存对象。

huangapple go评论121阅读模式
英文:

JPA EntityManager : save objects only when explicitly requested

问题

我在Hibernate和JPA方面相对新手,在目前正在使用JPA的EntityManager的应用程序上进行工作。

在查看了一些使用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
}

但是,如果已经存在的对象无论是否调用这个函数都会被保存,那么这样做有什么意义呢?

令人惊讶的是,这里找到的示例似乎也依赖于一个save方法。

我的问题是:是否有一种方法可以配置EntityManager仅在明确请求更新对象时(即模仿会话行为)才进行更新?还是说我必须使用Session来实现这一点?

英文:

I'm fairly new to Hibernate and JPA, and am currently working on an application that uses it through JPA's EntityManager.

When looking at some basic hibernate tutorials using Hibernate session, I see that I can do :

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()

When using Entitymanager, it's done this way :

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

The main difference here is that using EntityManager, I don't have to explicitly make a call to a save function to actually update the object, which will be flushed eventually during commit. Of course, I coul do something like

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

But what's the point for already existing objects if they get saved anyway, no matter if I call this or not ?

Surprisingly, the examples found around here seem to rely on a save method as well.

My question is : is there a way to configure EntityManager to update the objects only when requested specifically (i.e. mimick session behavior) ? Or do I have to use Session to achieve this ?

答案1

得分: 1

merge是EntityManager实际执行数据库操作的机会。合并(Merging)、持久化(Persisting)、刷新(Flushing)和提交(Committing)本质上都是与数据库交互的接触点。

对于简单情况,你可以在提交时依赖于更改行为,而不必自己实际执行合并,但许多人喜欢控制知道它何时实际发生。知道“在此之后,它已经在数据库中”。因为在合并之后,不仅数据已持久化,还有任何级联行为,以及数据库上的任何触发器等产生的任何副作用也已经发生。

它们尚未被提交,但它们已经发生。父项和子项被分配了键,触发器已经触发,生命周期方法已经触发,一切都“应该是”的,就是“现在”,而不是“将来的某个时刻”,即使那可能只有几毫秒的距离。

英文:

merge is the opportunity for the EntityManager to actually perform database operations. Merging, persisting, flushing, and committing are essentially all contact points with the database.

For simple cases, you can simply rely on changing the behavior at commit and not physically merge yourself, but many like the control knowing when it will actually happen. Knowing that "after this, it's in the DB". Because after the merge, not only is the data persisted, along with any cascading behavior, but also any side effects from triggers etc. on the DB have happened as well.

They're not committed, but they've happened. Keys are assigned for parents and children, triggers have fired, lifecycle methods have fired, everything is "as it should be", "right now", vs "sometime in the future" even if that may only be milliseconds away.

huangapple
  • 本文由 发表于 2020年5月29日 21:36:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/62087270.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定