Hibernate多对多映射时出现Bad value for type long错误
Hibernate多对多关联异常及权限集合未加载问题处理
报错信息
Could not extract column [3] from JDBC ResultSet [Bad value for type long : Allows creating new projects] [n/a]
数据库表结构
- Roles表:
id(long类型)、name(String类型) - Permissions表:
id(long类型)、description(text类型)、permission(String类型) - Role_Permission表:关联
role_id与permission_id的多对多中间表
实体类代码
Role实体
@Entity @Table(name = "roles") public class Role { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private long id; @Column(name = "name", nullable = false, unique = true) private String name; @ManyToMany @JoinTable( name = "role_permission", joinColumns = @JoinColumn(name = "role_id"), inverseJoinColumns = @JoinColumn(name = "permission_id") ) private Set<Permission> permissions; @OneToMany(mappedBy = "role") private Set<User> users; }
Permission实体
@Entity @Table(name = "permissions") public class Permission { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) private long id; @Column(name = "permission", nullable = false) private String permission; @Lob @Column(name = "description", nullable = true, columnDefinition = "text") private String description; @ManyToMany(mappedBy = "permissions") private Set<Role> roles; }
User实体关联部分
@ManyToOne @JoinColumn(name = "role_id", nullable = false) private Role role;
业务代码片段
User newUser = new User(); newUser.setUsername(registrationDto.getUsername()); newUser.setEmail(registrationDto.getEmail()); newUser.setPassword(bCryptPasswordEncoder.encode(registrationDto.getPassword())); newUser.setRole(roleRepository.findByName(registrationDto.getRole())); Role manager = newUser.getRole();
问题现象
- 抛出类型转换异常:尝试将字符串
Allows creating new projects转为long类型 - Role的
permissions集合为Hibernate的PersistanceSet代理对象,实际内容为null,设置FetchType.EAGER无效 - Role_Permission表数据已正确填充,能正常获取角色关联的用户,但无法加载权限集合
解决方案
1. 修复类型转换异常
报错核心是Hibernate尝试把权限的文本字段(description或permission)转换为long类型,需排查以下点:
- 确认Role_Permission表结构:必须仅包含
role_id和permission_id两个外键列,无多余字段(比如误将permission字段存入中间表) - 核对
@JoinTable映射:确保inverseJoinColumns指定的是permission_id而非permission/description。当前实体映射逻辑正确,但需注意数据库字段大小写是否与代码一致(部分数据库区分大小写)
2. 修复权限集合未加载问题
PersistanceSet是Hibernate延迟加载的代理集合,即使设置FetchType.EAGER,若Repository查询未关联权限表,依然不会加载数据:
- 修改
roleRepository.findByName方法,添加JOIN FETCH强制关联权限表:@Repository public interface RoleRepository extends JpaRepository<Role, Long> { @Query("SELECT r FROM Role r JOIN FETCH r.permissions WHERE r.name = :name") Role findByName(@Param("name") String name); } - Spring Data JPA默认的
findByName仅查询Role表字段,不会关联Permissions表,必须显式通过JOIN FETCH加载关联集合
3. 额外注意事项
- 避免同时使用
FetchType.EAGER与未关联查询的Repository方法,两者冲突会导致加载失效 - 检查事务边界:若在事务外访问
permissions集合,会触发LazyInitializationException,需确保操作在事务范围内执行
内容的提问来源于stack exchange,提问作者Martin Dúbravka
相关产品推荐
相关产品推荐

