hibernate 删除一方时,删除多对多关系关联的实体:Sping Boot 和JPA

kxe2p93d  于 2023-06-30  发布在  其他
关注(0)|答案(1)|浏览(136)

我有一个有两个ManyToMany关系的场景。我有以下实体-

  1. InsurancePolicy -保留保单详细信息
  2. County -保留国家/地区/州的详细信息
  3. PolicyCounty(维护InsurancePolicy和County之间ManyToMany关系的实体,此关系中的附加属性是cost)。
    1.用户-保留用户详细信息(与UserPolicyQuery具有一对多关系)
  4. UserPolicyQuery(与PolicyCounty有多对多关系)。
    这里是代码-

用户-

@Getter
@Setter
@NoArgsConstructor
@Entity
@Table(name="user")
public class User {

    @Id
    @Column (name ="userid" )
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long userId;

    @Column(name="firstname",nullable = false)
    private String firstName;

    @Column(name="lastname",nullable = false)
    private String lastName;

    @Column(name = "useremail",nullable = false)
    private String email;


    @Column(name = "phonenumber",nullable = false)
    private long phoneNumber;

    @OneToMany(mappedBy = "user",cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    private Set<UserPolicyQuery> userPolicyQueries = new HashSet<>();

    @Override
    public String toString() {
        return "User{" +
                "userId=" + userId +
                ", firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                ", email='" + email + '\'' +
                ", phoneNumber=" + phoneNumber +
                '}';
    }
}

UserPolicyQuery-

@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name="user_policy_query")
public class UserPolicyQuery {

    @Id
    @Column(name="query_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long queryId;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="user_id",nullable=false)
    private User user;

    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name="query_policy_county",
            joinColumns = @JoinColumn(name="query", referencedColumnName = "query_id"),
            inverseJoinColumns = @JoinColumn(name="policy_county", referencedColumnName = "policy_county_id"))
    private Set<PolicyCounty> policyCounties=new HashSet<>();

    @Column(name="comment",nullable = true)
    private String comment;

    @Override
    public String toString() {
        return "UserPolicyQuery{" +
                "queryId=" + queryId +
                ", user=" + user +
                ", comment='" + comment + '\'' +
                '}';
    }
}

政策县-

@Data
@NoArgsConstructor
@Setter
@Entity
@Table(name="policy_county")
public class PolicyCounty {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="policy_county_id")
    private long policyCountyId;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="policy_id")
    private InsurancePolicy policy;


    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "county_id")
    private County county;

    @Column(name="cost",nullable = false)
    private double cost;



    public long getPolicyCountyId() {
        return policyCountyId;
    }

    public InsurancePolicy getPolicy() {
        System.out.println("Policy County: getPolicy() called");
        return policy;
    }

    public County getCounty() {
        System.out.println("Policy county: getCounty() called");
        return county;
    }

    public double getCost() {
        return cost;
    }
}

保险单-

@Entity
@Table(name = "insurance_policy")
@Setter
@NoArgsConstructor
public class InsurancePolicy {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="policy_id")
    private long policyId;

    @Column(name="policy_name",nullable = false,unique = true)
    private String policyName;

    //Short description
    @Column(name="policy_description",nullable = false)
    private String policyDescription;

    //Long description
    @Column(name="choose_description",nullable = false)
    private String chooseDescription;

    //many policies can belong to one category
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "company_id", nullable = false)
    private Company company;

    //many policies can belong to one category
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="category_id",nullable=false)
    private Category category;


    @OneToMany(mappedBy = "policy", cascade = {CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REMOVE},fetch = FetchType.LAZY, orphanRemoval = true)
    private Set<PolicyCounty> policyCounties = new HashSet<>();

    public long getPolicyId() {
        return policyId;
    }

    public String getPolicyName() {
        return policyName;
    }

    public String getPolicyDescription() {
        return policyDescription;
    }

    public String getChooseDescription() {
        return chooseDescription;
    }

    public Company getCompany() {
        System.out.println("InsurancePolicy.getCompany() called");
        return company;
    }

    public Category getCategory() {
        return category;
    }

    public Set<PolicyCounty> getPolicyCounties() {
        System.out.println("Insurance policy getPolicyCounties called");
        return policyCounties;
    }
}

我的要求是-
1.当我删除InsurancePolicy时,我需要删除对应的PolicyCounty(我已经做到了这一点),同时删除引用PolicyCountiesUserPolicyQueries的所有Map(即我必须删除特定UserPolicyQueryPolicyCounty关联的记录(正在删除))。
1.删除
UserUserPolicyQuery时,必须删除与PolicyCounty的Map,但不能删除PolicyCounties**。
1.如果删除公司,则必须删除其所有策略,因此必须删除其所有关联的PolicyCountyUserPolicyQueriesMap。
简而言之,我想在删除策略(或删除PolicyCounty)时,删除表query_policy_countyPolicyCountyUserPolicyQuery之间的关系,而在删除查询时,不删除PolicyCounties。由于两个ManyToMany关系,我不太能理解在这种情况下到底该怎么做。救命啊!

rhfm7lfc

rhfm7lfc1#

您可能需要:
1.在PolicyCounty中,只需添加UserPolicyQueryorphanRemoval=true的关系-这将在删除查询的关联PolicyCounty时删除查询
1.在UserPolicyQuery中,您需要从PolicyCounty关系中删除CascadeType.REMOVE,因为这会阻止在删除查询时删除PolicyCounty(!)
1.在Company中,将CascadeType.REMOVE添加到InsurancePolicy join -这将在删除公司时删除策略和关联的PolicyCountyUserPolicyQueries
所以你会得到这样的结果:

// `PolicyCounty`
@OneToMany(mappedBy = "policyCounty", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<UserPolicyQuery> userPolicyQueries = new HashSet<>();
// `UserPolicyQuery`
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name="query_policy_county",
        joinColumns = @JoinColumn(name="query", referencedColumnName = "query_id"),
        inverseJoinColumns = @JoinColumn(name="policy_county", referencedColumnName = "policy_county_id"))
private Set<PolicyCounty> policyCounties = new HashSet<>();
// `Company`
@OneToMany(mappedBy = "company", cascade = CascadeType.REMOVE)
private Set<InsurancePolicy> insurancePolicies = new HashSet<>();

**UPD:**您也可以使用Entity Listener来手动删除关系,比如:

public class PolicyCountyListener {

    @PostRemove
    public void postRemove(PolicyCounty policyCounty) {
        for (UserPolicyQuery userPolicyQuery: policyCounty.getUserPolicyQueries()) {
            userPolicyQuery.getPolicyCounties().remove(policyCounty);
        }
    }
}
@EntityListeners(PolicyCountyListener.class)
public class PolicyCounty {
...

因此,当删除PolicyCounty实体时,它也会自动删除其与UserPolicyQuery实体的关联,但不会完全删除这些实体

相关问题