IntelliJ调试JPA Spring Boot表达式时疑似StackOverflow问题
问题解决思路
1. 调试时疑似StackOverflow提示的原因与修复
你的User实体用了@Data注解,它会自动生成toString()方法。但实体里包含@OneToMany关联的tokens集合,尽管加了@JsonIgnore,toString()仍会尝试遍历这个集合。如果Token实体里有对User的反向引用(比如@ManyToOne的user字段),调试器展示对象信息时调用toString()就会触发循环调用,出现类似StackOverflow的提示(这是调试器的递归遍历限制,不是真正运行时报错,所以控制台无输出、代码能继续执行)。
修复方案二选一:
- 手动重写
toString(),排除tokens集合:
@Override public String toString() { return "User{" + "id=" + id + ", firstname='" + firstname + '\'' + ", lastname='" + lastname + '\'' + ", email='" + email + '\'' + ", usrname='" + usrname + '\'' + ", avatar='" + avatar + '\'' + ", role=" + role + '}'; }
- 用Lombok的
@ToString(exclude = "tokens")覆盖@Data默认的toString生成(需Lombok 1.16.16及以上版本):
@Data @Builder @NoArgsConstructor @AllArgsConstructor @Entity @Table(name = "_user") @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,property = "id") @ToString(exclude = "tokens") // 排除tokens字段 public class User implements UserDetails { // ... 实体原有字段 }
2. "Could not commit JPA transaction"错误修复
你自定义了nativeQuery的getById方法,但Spring Data JPA本身自带findById(Integer id)方法(继承自JpaRepository),自定义native查询可能导致以下问题:
- Native查询返回的对象是游离态(未被EntityManager管理),后续修改该对象并提交事务时,JPA无法追踪状态变化,引发提交失败。
- 自定义查询未正确处理关联关系懒加载,可能在事务外触发懒加载,导致事务状态异常。
修复步骤:
- 移除自定义的
getById方法,直接用Spring Data JPA自带的findById:
// Service层代码修改为 User updateUser = userRepository.findById(userId) .orElseThrow(() -> new ResourceNotFoundException("L'utilisateur n'existe pas avec l'id: " + userId));
- 确保Service方法被
@Transactional注解修饰,保证操作在同一个事务边界内:
@Service @Transactional public class UserService { public User updateUser(int userId, UserUpdateDto dto) { // 你的业务逻辑代码 } }
- 检查
Token实体的关联配置,确保@ManyToOne的user字段配置正确:
@Entity public class Token { // ... 其他字段 @ManyToOne @JoinColumn(name = "user_id") // 确保外键列名与数据库一致 private User user; }
额外检查点
- 确认数据库中
_user表id=1的记录存在,且tokens关联的外键数据无损坏 - 检查项目的事务管理器配置,确保JPA事务被正确管理
内容的提问来源于stack exchange,提问作者dusk
相关产品推荐
相关产品推荐

