1

我有一个简单的控制器方法,在其中创建一个新对象Car,然后将其名称设置为Audi

@GetMapping(value = "/resource")
public ResponseEntity visit() {
    Car car = carRepo.save(new Car("VolksWagen")); // Car should be managed now?
    car.setName("Audi"); // <-- has no effect on database state

    return ResponseEntity.ok().build();
}

在数据库中,它永远不会变成Audi,而是保持VolksWagen.

为什么会这样?对于持久性上下文,新创建的不Car应该处于托管状态吗?

注意:如果我添加@Transactional注释,它会起作用。我认为如果启用 OSIV 就足够了。我对 OSIV 和 有什么误解@Transactional

4

2 回答 2

2

Open Session In View (OSIV) 使会话保持打开状态,以便在呈现视图时能够延迟加载关联。但它不会让交易保持开放状态。

更改已经提交,并且以后的更改将不会保留,因为以后的更改会被刷新或提交(并且因为更改不应该首先发生)

无论如何,OSIV 是一个肮脏的黑客,因为在事务提交后加载的数据可能与事务内部加载的数据不一致。我会避免它。有关更多原因,请参阅https://vladmihalcea.com/the-open-session-in-view-anti-pattern 。

于 2019-04-19T10:40:46.967 回答
0

carRepo.save 是坚持还是合并?如果您正在使用合并,请获取合并的结果!

“Persist 获取一个实体实例,将其添加到上下文中并管理该实例(即,将跟踪实体的未来更新)。

Merge 创建实体的新实例,从提供的实体复制状态,并管理新副本。您传入的实例将不会被管理(您所做的任何更改都不会成为事务的一部分 - 除非您再次调用合并)。”如this answer中所述

于 2019-04-19T10:26:25.320 回答