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 CASCADE
SQL에 있습니다.
휴지 상태를 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
'sourcecode' 카테고리의 다른 글
MySQL: 쿼리 결과에서 사용자 변수 설정 (0) | 2022.11.26 |
---|---|
ERROR 1698 (28000):사용자 'root'@'localhost'에 대한 액세스가 거부되었습니다. (0) | 2022.11.26 |
Firestore onSnapshot() 메서드가 여러 번 실행됩니다. (0) | 2022.11.26 |
날짜보다 큰 연산자를 사용하는 방법 (0) | 2022.11.26 |
SQL - FROM 절의 하위 쿼리에 문제가 있습니다. (0) | 2022.11.26 |