Home > Mobile >  Deleting relation data with one of the composite keys spring data jpa
Deleting relation data with one of the composite keys spring data jpa

Time:12-30

I have relation Entity with composite primary key.

@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);
  }
}

And also Vulnerability and Target entities. And my Id class is :

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

  private long vulnerability;
  private long target;

}

BTW i tried to add target id to VulnerabilityTarget entity like this and got error '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;

So, i want to delete all relations when i deleting a target. How can i delete VulnerabilityTarget by using target_id? (Via named query or by using cascase remove)

CodePudding user response:

After some researches on web i find a solution to perform delete operation on a relation table with composite id and i am adding as a solution. But i think a concise way more than my solution could possibly exist.

@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);
}

NOTE : some parts of the question needs to be clarified this answer only makes clear how wwe can delete relational entity has composite PK.

CodePudding user response:

If you want a targetId basic mapping as well as a target reference mapping, try using derived ids:

@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;
}

You just then need to change the VulnerabilityTargetId to rename the target and vulnerability properties to targetId and vulnerabilityId respectively.

  • Related