Spring Boot JPA中Process、Customer、Agent三实体双向多对多映射咨询
JPA双向多对多映射方案(Process、Customer、Agent)
以下是满足需求的JPA映射配置,核心实现双向多对多关联且删除Process时仅清理关联关系,不删除Customer/Agent实体:
关键配置说明
- 选择
ProcessEntity作为双向多对多的维护端,负责管理中间表的关联记录;CustomerEntity和AgentEntity作为被维护端,通过mappedBy反向关联。 - 级联操作仅配置
PERSIST和MERGE,避免REMOVE级联,确保删除Process时仅删除中间表的关联条目,不会删除关联的Customer或Agent。 - 显式定义中间表名称与字段,提升可读性。
1. ProcessEntity 实体配置
import jakarta.persistence.*; import java.util.HashSet; import java.util.Set; import java.util.UUID; @Entity @Table(name = "processes") public class ProcessEntity { @Id @GeneratedValue(generator = "uuid2") @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator") private UUID id; private String name; private String description; private String deepLinkId; // 根据StatusDto实际类型调整注解,示例为枚举类型 @Enumerated(EnumType.STRING) private StatusDto status; // 根据TaskDto实际类型调整注解,示例为嵌入式对象 @Embedded private TaskDto task; // 与Customer的双向多对多关联:维护端 @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) @JoinTable( name = "process_customer", joinColumns = @JoinColumn(name = "process_id"), inverseJoinColumns = @JoinColumn(name = "customer_id") ) private Set<CustomerEntity> customers = new HashSet<>(); // 与Agent的双向多对多关联:维护端 @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}) @JoinTable( name = "process_agent", joinColumns = @JoinColumn(name = "process_id"), inverseJoinColumns = @JoinColumn(name = "agent_id") ) private Set<AgentEntity> agents = new HashSet<>(); // 双向关系维护方法(替代直接赋值集合,避免状态同步问题) public void addCustomer(CustomerEntity customer) { customers.add(customer); customer.getProcesses().add(this); } public void removeCustomer(CustomerEntity customer) { customers.remove(customer); customer.getProcesses().remove(this); } public void addAgent(AgentEntity agent) { agents.add(agent); agent.getProcesses().add(this); } public void removeAgent(AgentEntity agent) { agents.remove(agent); agent.getProcesses().remove(this); } // 其他字段的Getter/Setter }
2. CustomerEntity 实体配置
import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Setter; import java.util.HashSet; import java.util.Set; import java.util.UUID; import java.util.Date; @Entity @Table(name = "customers") public class CustomerEntity { @Id @GeneratedValue(generator = "uuid2") @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator") private UUID id; @Setter(AccessLevel.NONE) private int roleId = 1; private String name; private UUID notificationId; private String mobile; private String email; private Boolean active; private Date iat; // 与CountryEntity的多对一关联(按需调整fetch策略) @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "country_id") private CountryEntity country; // 与Process的双向多对多关联:被维护端 @ManyToMany(mappedBy = "customers") private Set<ProcessEntity> processes = new HashSet<>(); // 关联集合仅提供Getter,通过Process的add/remove方法维护双向关系 public Set<ProcessEntity> getProcesses() { return processes; } // 其他字段的Getter/Setter }
3. AgentEntity 实体配置
import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Setter; import java.util.HashSet; import java.util.Set; import java.util.UUID; import java.util.Date; @Entity @Table(name = "agents") public class AgentEntity { @Id @GeneratedValue(generator = "uuid2") @GenericGenerator(name = "uuid2", strategy = "org.hibernate.id.UUIDGenerator") private UUID id; @Setter(AccessLevel.NONE) private int role_id = 2; private String name; private String mobile; private String email; private String companyName; private Boolean active; private String username; private String password; private Date iat; // 与CompanyEntity的多对一关联(按需调整fetch策略) @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "company_id") private CompanyEntity company; // 与Process的双向多对多关联:被维护端 @ManyToMany(mappedBy = "agents") private Set<ProcessEntity> processes = new HashSet<>(); // 关联集合仅提供Getter,通过Process的add/remove方法维护双向关系 public Set<ProcessEntity> getProcesses() { return processes; } // 其他字段的Getter/Setter }
核心规则验证
- 删除Process时的行为:当删除
ProcessEntity实例时,JPA会自动清理process_customer和process_agent中间表中对应的关联记录,但不会删除关联的CustomerEntity或AgentEntity(未配置CascadeType.REMOVE),完全符合需求。 - 双向关系一致性:通过自定义的add/remove方法维护双向关联状态,避免出现持久化时的关系不一致问题。
内容的提问来源于stack exchange,提问作者Abdullaah
相关产品推荐
相关产品推荐

