我理解错误消息,我知道如何解决它,但我想知道为什么它发生在这个特定的地方,特别是在查找方法上。我为此创建了一个小例子。
我有三个实体:
@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")
例外情况:在第二个调用中,我在repo.findByZooCity("OTHER STRING!!!!")
上得到一个“传递到持久化的独立实体:repo.findByZooCity("OTHER STRING!!!!")
”。我知道这是因为我之前添加了一个“独立”的人。但是为什么会发生在findBy上呢?(甚至没有结果?)
有脏支票吗?
谢谢你的时间和帮助。
发布于 2022-05-15 11:46:31
这种行为取决于FlushMode of EntityManager。
FlushMode
定义新实体以及对现有实体的更改何时写入数据库,换句话说,定义flush()
操作执行的时间。
刷新过程通过检测状态更改和执行SQL语句来同步数据库状态和会话状态。
JPA规范将FlushModeType.AUTO定义为默认的刷新模式。它在接下来的情况下刷新持久性上下文:
根据文档
自动 在执行查询之前,有时会刷新会话,以确保查询永远不会返回陈旧状态。这是默认的刷新模式。
摘要:
因此,在您的示例中,我们有默认的FlushMode.AUTO
,在查询执行框架执行flush()
操作期间,这就是原因。
FlushMode.AUTO
在查询的基础上解决了一致性问题,但另一方面也会导致不可预测的刷新操作,从而导致大型服务的性能问题。当您不需要解决一致性问题时,我建议将FlushMode
改为COMMIT
。FlushModeType.COMMIT在提交事务之前需要刷新,但没有定义在执行查询之前需要发生什么。执行任何查询都不会刷新任何挂起的更改。
FlushMode
**:** Changing
1.全局服务器添加到属性
spring.jpa.properties.org.hibernate.flushMode=COMMIT
2.为特定查询设置
Query quey = entityManager.createQuery("SELECT * from Foo");
quey.setFlushMode(FlushModeType.COMMIT);
Session
设置为3.
将EntityManager
注入您的服务。
@Transactional
fun save(name:String, city: String){
entityManager.setFlushMode(FlushModeType.COMMIT)
...
}
https://stackoverflow.com/questions/72205108
复制相似问题