我有Spring Data的简单代码示例:
实体
@Entity
@Table(name = "car")
public class Car {
@Id
@GeneratedValue
private Long id;
private String name;
//...
}
存储库:
@Repository
public interface CarRepository extends JpaRepository<Car, Long> {
}
使用示例方法提供服务:
@Service
public class CarService {
@Autowired
private CarRepository carRepository;
public void change() {
Car one = carRepository.findOne(1L);
one.setName("changed"); //important
}
}
和控制器:
@RestController("/")
public class CarController {
@Autowired
private CarRepository carRepository;
@Autowired
private CarService carService;
@GetMapping
public List<Car> home() {
carService.change();
List<Car> all = carRepository.findAll();
return all;
}
}
我也有data.sql有3条记录:
insert into car values (1, 'aaa');
insert into car values (2, 'bbb');
insert into car values (3, 'ccc');
当我向localhost发送请求时:8080我得到三辆车的列表,其中第一辆更新:
insert into car values (1, 'changed');
insert into car values (2, 'bbb');
insert into car values (3, 'ccc');
我的期望是从控制器调用change()之后实际上没有任何反应,因为此方法不是事务性的。那么为什么控制器中的home()方法返回带有更新实体的列表?
这个问题完全不同于Spring data jpa @transactional我不明白为什么你把它标记为重复。
答案 0 :(得分:2)
我假设您正在使用Spring Boot。如果您将Spring Boot与Spring MVC和Spring Data结合使用,则默认情况下,每次您的控制器方法收到请求时,都会打开一个Hibernate Session。会话提供应用程序与数据库之间的物理连接。可以使用spring.jpa.open-in-view
应用程序属性来控制此功能。
Car one = carRepository.findOne(1L); //1
one.setName("changed"); //2
List<Car> all = carRepository.findAll(); //3
return all;
First Level Cache
中。由于修改后的值永远不会刷新到数据库,因此在控制器调用之后,您可以检查数据库,并且您会看到,尽管控制器响应中收到的值不同,对象的旧值仍然保留。 / p>
如果将spring.jpa.open-in-view
属性设置为 false ,则控制器将返回“正确”值。
答案 1 :(得分:0)
如果你使用hibernate作为你的ORM工具,这可能是由于脏检查而发生的。如果你修改了一个hibernate会话已知的对象,当会话被刷新时它会被hibernate自动保存