如何在Hibernate中实现带额外字段的自关联好友关系映射?
最终正确映射配置方案
你需要补充独立的复合主键类、完善Friendship关联实体的双用户关联、修正User实体的集合映射,具体代码如下:
1. 定义复合主键类
FriendshipId.java,用于封装Friendship的联合主键,必须实现Serializable接口,并重写equals和hashCode方法:
@Data public class FriendshipId implements Serializable { // 字段名要和Friendship实体中@Id标注的字段名完全一致 private Integer ownUser; private Integer friendUser; }
2. 完善Friendship关联实体
配置两个User的关联字段作为联合主键,绑定对应的IdClass:
@Entity @Data @IdClass(FriendshipId.class) public class Friendship { // 发起好友关系的用户 @Id @ManyToOne private User ownUser; // 对应的好友用户 @Id @ManyToOne private User friendUser; // 好友关系等级 private String level; }
3. 修正User实体的映射配置
friends集合存储当前用户作为发起方的所有好友关系记录:
@Entity @Data public class User { @Id private Integer id; private String name; private String about; // mappedBy指向Friendship实体中的ownUser字段,代表当前用户是关系发起方 @OneToMany(mappedBy = "ownUser", cascade = CascadeType.ALL, orphanRemoval = true) private Set<Friendship> friends = new HashSet<>(); // 可选配置:如果需要查询当前用户被哪些人添加为好友,新增以下集合 @OneToMany(mappedBy = "friendUser", cascade = CascadeType.ALL, orphanRemoval = true) private Set<Friendship> beAddedFriends = new HashSet<>(); }
注意事项
- 若业务要求好友关系是双向唯一的(即A是B的好友则B自动是A的好友),可以在添加好友的业务逻辑中增加校验,避免存储两条重复的关系记录,也可以直接在查询时同时拉取
friends和beAddedFriends的集合做合并。 - 级联策略可以根据自己的业务需求调整,不需要级联操作可删除
cascade和orphanRemoval配置。
内容的提问来源于stack exchange,提问作者milanHrabos
相关产品推荐
相关产品推荐

