賞金將在 13 小時后到期。此問題的答案有資格獲得 200聲望賞金。 pL4Gu33希望引起對這個問題的更多關注。
我理解錯誤訊息并且我知道如何解決它,但我想知道它為什么會出現在這個特定的地方,尤其是在 find 方法上。我為此創建了一個迷你示例。
我有三個物體:
@Entity
data class Animal(
var name: String,
@ManyToOne(cascade = [CascadeType.ALL]) val zoo: Zoo) {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Int = -1
}
@Entity
data class Zoo(
var city: String,
@OneToMany(cascade = [CascadeType.ALL]) val employee: MutableList<Person>) {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Int = -1
}
@Entity
data class Person(var age: Int) {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Int = -1
}
服務:
@Transactional
fun save(name:String, city: String){
repo.findByZooCity(city).ifPresent {
it.zoo.employee.add(Person(22))
}
repo.findByZooCity("OTHER STRING!!!!").ifPresent { println("FOUND!") }
repo.save(Animal(name, Zoo(city, mutableListOf(Person(33)))))
}
回購:
interface AnimalRep: JpaRepository<Animal, Int>{
fun findByZooCity(name: String): Optional<Animal>
}
稱呼:
animalService.save("Zoo1", "Animal1")
animalService.save("Zoo1", "Animal1")
例外:在第二次通話中,我得到一個“分離的物體傳遞給堅持:com.example.Person” repo.findByZooCity("OTHER STRING!!!!")。我知道會發生這種情況,因為我之前添加了一個“超然”的人。但為什么它會出現在 findBy 上?(即使它不在結果中?)
有臟支票嗎?
感謝您的時間和幫助。
uj5u.com熱心網友回復:
此行為取決于EntityManager的FlushMode。
定義何時將新物體和您對現有物體的更改寫入資料庫,換句話說,定義何時執行操作。FlushModeflush()
重繪 程序通過檢測狀態變化和執行 SQL 陳述句來同步資料庫狀態和會話狀態。
JPA 規范將FlushModeType.AUTO定義為默認重繪 模式。它會在以下情況下重繪 持久性背景關系:
- 在事務提交之前
- 在執行使用持久性背景關系包含任何未決更改的任何資料庫表的查詢之前。
根據檔案:
AUTO
會話有時會在查詢執行之前被重繪 ,以確保查詢永遠不會回傳過時狀態。這是默認的重繪 模式。
摘要:
所以在您的示例中,我們有 default FlushMode.AUTO,在查詢執行框架執行flush()操作期間,這就是原因。
FlushMode.AUTO正在基于查詢修復一致性問題,但另一方面可能導致不可預知的重繪 操作,并在大型服務的情況下導致性能問題。當您不需要解決一致性問題時,我建議更改FlushMode為。COMMITFlushModeType.COMMIT需要在提交事務之前重繪 ,但沒有定義在執行查詢之前需要發生什么。執行任何查詢都不會重繪 任何掛起的更改。
更改FlushMode:
1. 全域為服務器添加到屬性
spring.jpa.properties.org.hibernate.flushMode=COMMIT
2.針對具體查詢設定
Query quey = entityManager.createQuery("SELECT * from Foo");
quey.setFlushMode(FlushModeType.COMMIT);
3. 設定為Session
注入EntityManager到您的服務中。
@Transactional
fun save(name:String, city: String){
entityManager.setFlushMode(FlushModeType.COMMIT)
...
}
詳細描述在自動重繪 策略如何在 JPA 和 Hibernate 中作業
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/478773.html
