阅山

  • WIN
    • CSharp
    • JAVA
    • OAM
    • DirectX
    • Emgucv
  • UNIX
    • FFmpeg
    • QT
    • Python
    • Opencv
    • Openwrt
    • Twisted
    • Design Patterns
    • Mysql
    • Mycat
    • MariaDB
    • Make
    • OAM
    • Supervisor
    • Nginx
    • KVM
    • Docker
    • OpenStack
  • WEB
    • ASP
    • Node.js
    • PHP
    • Directadmin
    • Openssl
    • Regex
  • APP
    • Android
  • AI
    • Algorithm
    • Deep Learning
    • Machine Learning
  • IOT
    • Device
    • MSP430
  • DIY
    • Algorithm
    • Design Patterns
    • MATH
    • X98 AIR 3G
    • Tucao
    • fun
  • LIFE
    • 美食
    • 关于我
  • LINKS
  • ME
Claves
长风破浪会有时,直挂云帆济沧海
  1. 首页
  2. Platforms
  3. WINDOWS
  4. JAVA
  5. 正文

spring boot/spring data jpa list接口中数据被修改问题

2025-07-14

一、问题现象

service中仅仅使用visionGatewayRepository.findAllByCompanyId(UserUtils.getCompanyId(), pageable);查询了列表,然后对列表的数据进行了修改,直接通过Controller返回了前端,但是发现数据库的数据被修改了。

二、问题分析

原因解释

当您从数据库查询实体对象时,JPA 会将这些对象纳入持久化上下文(Persistence Context)管理。在默认情况下:

  1. ​实体处于托管状态​:通过 JPA Repository 查询返回的实体对象是"托管(managed)"状态的
  2. ​自动脏检查​:当事务提交时,JPA 会自动检测这些托管实体的变化
  3. ​自动同步到数据库​:如果发现实体属性有变化,JPA 会自动生成 UPDATE 语句将变更同步到数据库

为什么没有调用 save() 也会更新

这是因为在以下情况下会自动触发更新:

  1. 您的方法有 @Transactional 注解(Spring Boot 默认很多方法都有事务)
  2. 您修改了从 Repository 查询返回的实体对象
  3. 方法执行完毕,事务提交时 JPA 检测到实体变化并自动同步

解决方案

如果您不希望自动更新,可以考虑以下方法:

  1. ​手动分离实体​: java复制EntityManager entityManager; // 注入 entityManager.detach(entity); // 将实体从持久化上下文分离
  2. ​使用 DTO 返回​:
    不直接返回实体对象,而是转换为 DTO 对象返回
  3. ​查询时指定只读​: java复制@Transactional(readOnly = true) public Entity getEntity(Long id) { return repository.findById(id).orElse(null); }
  4. ​使用 Projection​:
    只查询需要的字段而不是整个实体

最佳实践

  • 明确区分读写操作,写操作显式调用 save()
  • 在只读场景使用 @Transactional(readOnly = true)
  • 对外暴露接口时使用 DTO 而不是直接暴露实体

这种自动更新机制是 JPA 的一个便利特性,但需要开发者明确了解其行为以避免意外更新。

三、解决方法

给查询函数前面,添加@Transactional(readOnly = true)

标签: 暂无
最后更新:2025-07-14

代号山岳

知之为知之 不知为不知

点赞
< 上一篇

COPYRIGHT © 2099 登峰造极境. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

蜀ICP备14031139号-5

川公网安备51012202000587号