sourcecode

JPA: 단방향 다대일 및 캐스케이드 삭제

copyscript 2022. 11. 26. 08:46
반응형

JPA: 단방향 다대일 및 캐스케이드 삭제

단방향이라고 합니다. @ManyToOne다음과 같은 관계:

@Entity
public class Parent implements Serializable {

    @Id
    @GeneratedValue
    private long id;
}

@Entity
public class Child implements Serializable {

    @Id
    @GeneratedValue
    private long id;

    @ManyToOne
    @JoinColumn
    private Parent parent;  
}

만약 내가 P부모와 C자녀가1 있다면...P를 참조하는 C는 JPA에서 자동으로 C를1 제거할 수 있는 깨끗하고 예쁜 방법이 있습니까n?P가n 제거되었을 때 C(즉,entityManager.remove(P))?

제가 찾고 있는 기능은 다음과 같습니다.ON DELETE CASCADESQL에 있습니다.

휴지 상태를 JPA 공급자로 사용하는 경우 주석을 사용할 수 있습니다.@OnDelete. 이 주석은 트리거 관계를 추가합니다.ON DELETE CASCADE이것은 하위 삭제를 데이터베이스에 위임합니다.

예:

public class Parent {
   
        @Id
        private long id;

}


public class Child {
        
        @Id
        private long id;
  
        @ManyToOne
        @OnDelete(action = OnDeleteAction.CASCADE)
        private Parent parent;
}
     

이 솔루션에서는 자녀에서 부모까지의 단방향 관계만으로도 모든 자녀를 자동으로 제거할 수 있습니다.이 솔루션에는 청취자 등이 필요하지 않습니다.JPQL 쿼리도 다음과 같습니다.DELETE FROM Parent WHERE id = 1아이들을 제거할 것입니다.

JPA의 관계는 부모 및 자녀와 양방향으로 관련짓지 않는 한 항상 단방향입니다.부모에서 자녀로 REMOVE 작업을 캐스케이드하려면 부모에서 자녀로의 관계가 필요합니다(반대뿐만 아니라).

따라서 다음 작업을 수행해야 합니다.

  • 둘 중 하나, 단방향 변경@ManyToOne쌍방향 관계@ManyToOne, 또는 단방향@OneToMany그런 다음 REMOVE 작업을 캐스케이드하여 부모 및 자식 작업을 제거할 수 있습니다.또한 부모 컬렉션의 하위 엔티티가 null로 설정되어 있는 경우, 즉 부모 컬렉션에 존재하지 않는 경우 하위 엔티티를 삭제하도록 true로 지정할 수 있습니다.
  • 또는 하위 테이블의 외부 키 제약 조건을 다음과 같이 지정합니다.ON DELETE CASCADE. 퍼시스텐스 콘텍스트를 갱신할 필요가 있기 때문에 호출 후에 호출해야 합니다.자 엔티티는 데이터베이스에서 삭제된 후에는 퍼시스텐스 콘텍스트에 존재하지 않습니다.

다음과 같이 쌍방향 관계를 만듭니다.

@Entity
public class Parent implements Serializable {

    @Id
    @GeneratedValue
    private long id;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE)
    private Set<Child> children;
}

단방향 @ManytoOne에서 봤는데 삭제가 예상대로 작동하지 않습니다.부모를 삭제하면 자녀도 삭제해야 하지만 부모만 삭제되고 자녀는 삭제되지 않고 고립된 상태로 남습니다.

사용되는 테크놀로지는 Spring Boot/Spring Data JPA/Hibernate입니다.

Sprint Boot : 2.1.2.풀어주다

Spring Data JPA/Hibernate는 행을 삭제하는 데 사용됩니다.

parentRepository.delete(parent)

는 표준 합니다( 참조).ParentRepository extends CrudRepository<T, ID>

다음은 엔티티 클래스입니다.

@Entity(name = “child”)
public class Child  {

    @Id
    @GeneratedValue
    private long id;

    @ManyToOne( fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = “parent_id", nullable = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Parent parent;
}

@Entity(name = “parent”)
public class Parent {

    @Id
    @GeneratedValue
    private long id;

    @Column(nullable = false, length = 50)
    private String firstName;


}

한쪽 면만 삭제하려면 이 방법을 사용합니다.

    @ManyToOne(cascade=CascadeType.PERSIST, fetch = FetchType.LAZY)
//  @JoinColumn(name = "qid")
    @JoinColumn(name = "qid", referencedColumnName = "qid", foreignKey = @ForeignKey(name = "qid"), nullable = false)
    // @JsonIgnore
    @JsonBackReference
    private QueueGroup queueGroup;

@Cascade(또는 hibernate. 주석).캐스케이드 타입DELETE_ORFAN)

주석은 나에게 효과가 있었다.시험해 볼 수 있다

예:-

     public class Parent{
            @Id
            @GeneratedValue(strategy=GenerationType.AUTO)
            @Column(name="cct_id")
            private Integer cct_id;
            @OneToMany(cascade=CascadeType.REMOVE, fetch=FetchType.EAGER,mappedBy="clinicalCareTeam", orphanRemoval=true)
            @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
            private List<Child> childs;
        }
            public class Child{
            @ManyToOne(fetch=FetchType.EAGER)
            @JoinColumn(name="cct_id")
            private Parent parent;
    }

코드 대신 쌍방향 어소시에이션을 사용할 필요는 없습니다.CascaType만 추가하면 됩니다.ManyToOne 주석의 속성으로 제거한 다음 @OnDelete(작업 = OnDeleteAction)를 사용합니다.CASCADE)는 문제 없습니다.

언급URL : https://stackoverflow.com/questions/7197181/jpa-unidirectional-many-to-one-and-cascading-delete

반응형