You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 16:57:42