Spring Boot JPA保存实体时报hashCode空指针错误问题求助
根本原因
- @MapKey注解使用错误是核心诱因:
@MapKey(name = "friendId")指定用Friendship实体的friendId字段(Long类型)作为Map的键,但你当前User类中friendships属性的泛型声明应为Map<User, Friendship>,键类型为User,JPA无法将Long类型的friendId自动转为User实体,导致Map的键被赋值为null。 - 空指针异常的直接来源:JPA持久化关联集合时,会对Map的键调用
hashCode()方法完成哈希表存储,键为null时就会抛出Cannot invoke "java.lang.Object.hashCode()" because "value" is null异常,和User类的username字段无关。
解决方案
可根据业务场景二选一:
方案1:Map键对应好友User实体(常用场景)
- 调整Friendship实体的关联映射,替换纯主键字段为实体关联,同步定义复合主键类:
// 好友关系实体 @Entity @IdClass(FriendshipId.class) public class Friendship { @Id @ManyToOne @JoinColumn(name = "owner_id") private User owner; @Id @ManyToOne @JoinColumn(name = "friend_id") private User friend; // 其他业务属性、getter、setter } // 复合主键类 public class FriendshipId implements Serializable { private Long owner; // 字段名对应Friendship中owner属性,类型匹配User的主键类型 private Long friend; // 字段名对应Friendship中friend属性,类型匹配User的主键类型 // 重写equals、hashCode方法 }
- 修正User类的friendships属性注解:
@OneToMany(mappedBy = "owner", cascade = CascadeType.ALL, orphanRemoval = true) @MapKey(name = "friend") // 用Friendship关联的friend实体作为Map键 private Map<User, Friendship> friendships = new HashMap<>();
方案2:Map键对应好友ID(Long类型)
如果业务只需要用好友ID作为索引,不需要直接关联User实体作为键,直接修改friendships的泛型声明即可:
@OneToMany(mappedBy = "owner", cascade = CascadeType.ALL, orphanRemoval = true) @MapKey(name = "friendId") private Map<Long, Friendship> friendships = new HashMap<>();
内容的提问来源于stack exchange,提问作者milanHrabos
相关产品推荐
相关产品推荐

