You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot使用Jpa Repository更新登录用户数据时新增记录问题

问题原因分析
  • save操作对象不匹配:你修改了currentuser对象的余额属性,但最终调用repo.save()时传入的是未做任何赋值的logindata对象,该对象没有携带已登录用户的主键标识,JPA的save方法识别到实体主键为空时,就会执行插入操作而非更新操作,因此会生成仅包含余额字段的新记录。
  • 认证对象与数据库实体混淆:CustomUserDetails是Spring Security的认证信息载体,不是和数据库映射的实体类对象,直接修改它的属性不会关联到数据库中的对应记录,即便直接保存currentuser也无法完成正确更新。
修复方案

1. 调整接口逻辑,先查询对应实体再更新

你需要先通过currentuser中存储的唯一标识(比如用户名、用户ID)查询出数据库中对应的用户实体,修改后再保存:

@PostMapping("/Balnce_add")
public String GoesUp(@AuthenticationPrincipal CustomUserDetails currentuser) throws IOException {
    // 按用户名查询数据库中对应的用户实体,替换为你实际的查询方法
    UserEntity loginUser = repo.findByUsername(currentuser.getUsername());
    // 修改余额
    int newBalance = loginUser.getBalance() + 10;
    loginUser.setBalance(newBalance);
    // 保存携带主键的实体,会执行更新操作
    repo.save(loginUser);
    System.out.println("cool ==> "+ loginUser.getBalance());
    return "user";
}

2. 补充Repository的查询方法

确认你的Repository接口中已经定义了对应的查询方法,示例如下:

public interface UserRepository extends JpaRepository<UserEntity, Long> {
    // 方法名要和实体类的用户名字段对应,如字段为userId就改成findByUserId
    UserEntity findByUsername(String username);
}

优化建议

如果要避免并发场景下的余额覆盖问题,也可以直接写增量更新的JPQL语句,省略查询步骤:

// 在Repository中新增方法
@Modifying
@Transactional
@Query("update UserEntity u set u.balance = u.balance + 10 where u.username = :username")
int incrementBalance(@Param("username") String username);

接口中直接调用该方法即可完成更新,性能更高且并发安全性更好。

内容的提问来源于stack exchange,提问作者LEGENDRYzZzZ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 17:24:04