如何在不使用@Mapsid的情况下用JPA Hibernate关联三个实体
不使用@MapsId实现JPA Hibernate三实体关联(Users、Roles、Project)
根据你的数据库设计,我们可以通过复合主键类+中间关联实体的方式,在不使用@MapsId注解的前提下完成三实体的关联映射。
1. 定义复合主键类
中间表has的主键由user_id、role_id、project_id组成,需要先创建一个可序列化的复合主键类:
import java.io.Serializable; import java.util.Objects; public class HasId implements Serializable { private Long userId; private Long roleId; private Long projectId; // JPA要求的无参构造器 public HasId() {} public HasId(Long userId, Long roleId, Long projectId) { this.userId = userId; this.roleId = roleId; this.projectId = projectId; } // 复合主键必须实现equals和hashCode @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; HasId hasId = (HasId) o; return Objects.equals(userId, hasId.userId) && Objects.equals(roleId, hasId.roleId) && Objects.equals(projectId, hasId.projectId); } @Override public int hashCode() { return Objects.hash(userId, roleId, projectId); } // getter和setter方法 public Long getUserId() { return userId; } public void setUserId(Long userId) { this.userId = userId; } public Long getRoleId() { return roleId; } public void setRoleId(Long roleId) { this.roleId = roleId; } public Long getProjectId() { return projectId; } public void setProjectId(Long projectId) { this.projectId = projectId; } }
2. 实现中间关联实体Has
这个实体映射到中间表,通过@EmbeddedId嵌入复合主键,同时手动关联三个主实体:
import javax.persistence.*; @Entity @Table(name = "has") public class Has { @EmbeddedId private HasId id; @ManyToOne @JoinColumn(name = "user_id", insertable = false, updatable = false, referencedColumnName = "user_id") private Users user; @ManyToOne @JoinColumn(name = "role_id", insertable = false, updatable = false, referencedColumnName = "role_id") private Roles role; @ManyToOne @JoinColumn(name = "project_id", insertable = false, updatable = false, referencedColumnName = "project_id") private Project project; public Has() {} public Has(HasId id) { this.id = id; } // 手动维护主键与关联实体的绑定关系 public void setUser(Users user) { this.user = user; if (id == null) id = new HasId(); id.setUserId(user.getUserId()); } public void setRole(Roles role) { this.role = role; if (id == null) id = new HasId(); id.setRoleId(role.getRoleId()); } public void setProject(Project project) { this.project = project; if (id == null) id = new HasId(); id.setProjectId(project.getProjectId()); } // getter和setter public HasId getId() { return id; } public void setId(HasId id) { this.id = id; } public Users getUser() { return user; } public Roles getRole() { return role; } public Project getProject() { return project; } }
注:
insertable = false, updatable = false是因为主键字段已由HasId维护,关联字段无需参与插入/更新操作。
3. 主实体双向关联配置(以Users为例)
在Users中添加@OneToMany实现与Has的双向关联,Roles和Project配置逻辑完全一致:
import javax.persistence.*; import java.util.List; @Entity @Table(name = "users") public class Users { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "user_id") private Long userId; // 你的其他字段,如username、password等 private String username; private String password; @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) private List<Has> hasList; public Users() {} // 便捷方法:快速添加/移除关联关系 public void addHas(Has has) { hasList.add(has); has.setUser(this); } public void removeHas(Has has) { hasList.remove(has); has.setUser(null); } // 省略其他字段的getter/setter public Long getUserId() { return userId; } public void setUserId(Long userId) { this.userId = userId; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public List<Has> getHasList() { return hasList; } public void setHasList(List<Has> hasList) { this.hasList = hasList; } }
4. 使用示例
// 创建基础实体 Users user = new Users(); user.setUsername("test_user"); user.setPassword("123456"); Roles role = new Roles(); role.setRoleName("PROJECT_ADMIN"); Project project = new Project(); project.setProjectName("Demo_Project"); // 创建关联关系 Has has = new Has(); has.setUser(user); has.setRole(role); has.setProject(project); // 绑定到用户的关联列表 user.addHas(has); // 持久化到数据库 entityManager.persist(user); entityManager.persist(role); entityManager.persist(project); entityManager.persist(has);
内容的提问来源于stack exchange,提问作者Julen Amedo Gibaja
相关产品推荐
相关产品推荐

