使用复合键之一删除关系数据 spring data jpa

Deleting relation data with one of the composite keys spring data jpa

我有带复合主键的关系实体。

@Getter
@Setter
@Entity
@IdClass(VulnerabilityTargetId.class)
@Table(name = "vulnerabilities_targets")
@Where(clause = "deleted='false'")
@SQLDelete(
    sql =
        "UPDATE vulnerabilities_targets SET deleted = true WHERE target_id = ? and vulnerability_id = ?")
public class VulnerabilityTarget extends BaseRelEntity {

  @Id
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "target_id")
  private Target target;

  @Id
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "vulnerability_id")
  private Vulnerability vulnerability;


  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    VulnerabilityTarget that = (VulnerabilityTarget) o;
    return target.equals(that.target) && vulnerability.equals(that.vulnerability);
  }

  @Override
  public int hashCode() {
    return Objects.hash(target, vulnerability);
  }
}

还有漏洞目标实体。我的 ID class 是:

@Getter
@Setter
@EqualsAndHashCode
public class VulnerabilityTargetId implements Serializable {

  private long vulnerability;
  private long target;

}

顺便说一句,我尝试像这样将目标 ID 添加到 VulnerabilityTarget 实体,但出现错误 'Repeated column in mapping for entity: com.security.raze.pojo.internal.entity.relation.VulnerabilityTarget_AUD'

@Id
  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "target_id", insertable = false, updatable = false)
  private Target target;

@Column(name = "target_id")
private Long targetId;

所以,我想在删除目标时删除所有关系。如何使用 target_id 删除 VulnerabilityTarget? (通过命名查询或使用 cascase 删除)

在网络上进行一些研究后,我找到了对具有复合 ID 的关系 table 执行删除操作的解决方案,我将其添加为解决方案。但我认为可能存在比我的解决方案更简洁的方法。

@Repository
public interface VulnerabilityTargetRepository
    extends JpaRepository<VulnerabilityTarget, VulnerabilityTargetId> {
  @Transactional
  @Modifying
  @Query(
      value =
          "UPDATE VulnerabilityTarget vt SET vt.deleted = true WHERE vt.target IN (Select t from Target t WHERE t.id = :targetId)")
  void deleteByTargetId(long targetId);
}

注意:问题的某些部分需要澄清这个答案只说明了 wwe 如何删除具有复合 PK 的关系实体。

如果您需要 targetId 基本映射以及目标引用映射,请尝试使用派生 ID:

@Getter
@Setter
@Entity
@IdClass(VulnerabilityTargetId.class)
@Table(name = "vulnerabilities_targets")
@Where(clause = "deleted='false'")
@SQLDelete(
    sql =
        "UPDATE VulnerabilityTarget SET deleted = true WHERE targetId = ? and vulnerabilityId = ?")
public class VulnerabilityTarget extends BaseRelEntity {

  @Id
  @Column(name = "vulnerability_id")
  private Long vulnerabilityId;

  @MapsId("vulnerabilityId")
  @ManyToOne(fetch = FetchType.LAZY)
  private Vulnerability vulnerability;

  @Id
  @Column(name = "target_id")
  private Long targetId;

  @MapsId("targetId")
  @ManyToOne(fetch = FetchType.LAZY)
  private Target target;
}

您只需更改 VulnerabilityTargetId,将目标和漏洞属性分别重命名为 targetId 和 vulnerabilityId。