Spring+Hibernate保存User时触发PropertyAccessException错误求助
Hibernate保存User实体时PropertyAccessException错误排查
问题概述
使用Hibernate保存User实体时触发org.hibernate.PropertyAccessException,核心错误提示为:无法为com.example.demo.model.User.id设置java.lang.Long类型值,底层根因是代码尝试将User对象赋值给Long类型的id字段。
错误原因分析
从堆栈信息的根异常java.lang.IllegalArgumentException: Can not set java.lang.Long field com.example.demo.model.User.id to com.example.demo.model.User可以确定:Hibernate在通过increment主键生成器生成ID时,错误地将User实例传递给了setId(Long id)方法。该问题源于increment生成器与Jakarta Persistence注解的兼容性问题,且该生成器本身不适合MySQL数据库的自增主键场景。
解决方案
替换主键生成策略为MySQL原生支持的自增主键策略,使用JPA标准注解替代原有的Hibernate自定义生成器。
修改后的User实体类
package com.example.demo.model; import jakarta.persistence.*; @Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 替换原increment生成策略 private Long id; private String name; private String email; // 构造方法 public User() {} public User(String name, String email) { this.name = name; this.email = email; } // Getter和Setter方法 public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
可选替代方案
也可以使用Hibernate的native策略,效果与IDENTITY一致,会自动适配数据库的主键生成机制:
@Id @GeneratedValue(strategy = GenerationType.NATIVE) private Long id;
额外说明
increment是Hibernate旧有生成策略,通过查询表中最大ID生成新ID,不适合高并发场景,且在新版本中与Jakarta注解存在兼容性隐患。- MySQL的自增主键策略(
IDENTITY)贴合数据库原生特性,性能和稳定性更优。
内容的提问来源于stack exchange,提问作者hkguile
相关产品推荐
相关产品推荐

