java JPA中flush的确切目的是什么
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32108491/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is exact purpose of flush in JPA
提问by Nick Div
Some confusing explanation: flush(); Flushing is the process of synchronizing the underlying persistent store with persistable state held in memory.it will update or insert into your tables in the running transaction, but it may not commit those changes.
一些令人困惑的解释:flush(); 刷新是将底层持久存储与保存在内存中的持久状态同步的过程。它会更新或插入正在运行的事务中的表,但它可能不会提交这些更改。
If the changes are anyways going to be persisted in the database only after the commit then why to flush in the middle of the code.
如果无论如何更改只会在提交后才保留在数据库中,那么为什么要在代码中间刷新。
And after running the flush if any changes are made to the managed object then will that throw an Exception or will those get synchronized and then will get perisisted. If they get synchronized then again why flush in the first place.
并且在运行刷新之后,如果对托管对象进行了任何更改,那么会抛出异常,或者这些会被同步,然后会被持久化。如果它们同步,那么首先为什么要刷新。
采纳答案by Mathias Begert
In theory, you (as a user of JPA) should never (or in absolutely rare situations) get in a situation to call flush()
.
理论上,您(作为 JPA 的用户)永远不应该(或在绝对罕见的情况下)遇到调用flush()
.
Flushing is the process of synchronizing the underlying persistent store with persistable state held in memory
刷新是将底层持久存储与内存中保持的持久状态同步的过程
In other words, on a flush()
all the insert, update, delete or whatever statements are actually called on the database, before a flush()
nothing happens on your database. Flushing is caused by a commit of your transaction or some kinds of database reads. For example if you execute a JPQL query, a flush()
has to be done to get the correct results from the database. But this is just very nice to know and completely handled by your JPA implementation.
换句话说,在flush()
数据库上flush()
没有任何反应之前,在数据库上实际调用了所有插入、更新、删除或任何语句。刷新是由事务提交或某些类型的数据库读取引起的。例如,如果您执行 JPQL 查询,则必须执行 aflush()
才能从数据库中获得正确的结果。但这很高兴知道并完全由您的 JPA 实现处理。
There may be some situations you want to control this flushing on your own and then you can invoke it with flush()
.
在某些情况下,您可能希望自己控制此刷新,然后您可以使用flush()
.
Editto answer the questions in comment:
编辑以回答评论中的问题:
Not on every read a flush is necessary, consider this scenario (one transaction):
并非每次读取都需要刷新,请考虑这种情况(一个事务):
- Read a person
Person p = em.find(Person.class, 234)
- Update person
p.setAge(31)
- Read a building
Building b = em.find(Building.class, 123
- Read a building with JPQL query
select b from Building b where b.id = 123
- 读一个人
Person p = em.find(Person.class, 234)
- 更新人
p.setAge(31)
- 读一栋楼
Building b = em.find(Building.class, 123
- 使用 JPQL 查询读取建筑物
select b from Building b where b.id = 123
Automatic flushoccurs only before 4., because Eclipselink can't determine what you are gonna read, so the person's age must be up to date on the database before this read can occur. Before 3. there is no flush needed because Eclipselink knows that the update on a person can not affect a building.
自动刷新仅在 4. 之前发生,因为 Eclipselink 无法确定您要读取的内容,因此在此读取发生之前,该人的年龄必须在数据库上是最新的。在 3. 之前不需要刷新,因为 Eclipselink 知道对一个人的更新不会影响建筑物。
To work with optimistic locking, you have to implement it. Read about the @Version
annotation here: https://blogs.oracle.com/carolmcdonald/entry/jpa_2_0_concurrency_and. Without that your entity will not use optimistic locking and the "last update wins".
要使用乐观锁定,您必须实现它。在@Version
此处阅读注释:https: //blogs.oracle.com/carolmcdonald/entry/jpa_2_0_concurrency_and。没有它,您的实体将不会使用乐观锁定并且“最后更新获胜”。
回答by owenrb
When the transaction commits the entity manager does that flush-ing for you. In some case, like handling optimistic locking in a container-managed transaction, you may need to manually invoke the flush method to catch and handle specific locking exception.
当事务提交时,实体管理器会为您执行刷新操作。在某些情况下,例如在容器管理的事务中处理乐观锁定,您可能需要手动调用flush 方法来捕获和处理特定的锁定异常。