line / kotlin-jdsl

Kotlin library that makes it easy to build and execute queries without generated metamodel
https://kotlin-jdsl.gitbook.io/docs/
Apache License 2.0
711 stars 88 forks source link

연관관계가 있는 Entity Delete 방법 질문 #133

Closed EC-Sol closed 1 year ago

EC-Sol commented 1 year ago

Issue 라는 부모 Entity 가 있고 Comment 라는 자식 Entity 가 1:N 관계를 가지고 있습니다. Comment 는 issue_id라는 컬럼으로 Issue 의 ID를 FK로 가지고있습니다.

Issue 를 Delete 할 때 연관된 Comment 가 Casacade 로 전부 삭제되었으면 합니다.

다음의 세 가지 방법으로 삭제를 시도했으나 쿼리 실행 자체가 되질 않습니다.

queryFactory.deleteQuery<Issue> {
    where(
        col(Issue::id).equal(id)
    )
    associate(Comment::class, Issue::class, on(Comment::issue))
}
queryFactory.deleteQuery<Issue> {
    where(
        col(Issue::id).equal(id)
    )
    associate(Issue::class, Comment::class, on(Comment::issue))
}
queryFactory.deleteQuery<Issue> {
    where(
        col(Issue::id).equal(id)
    )
    associate(Issue::class, Comment::class, on(Issue::comments))
}

세 가지 방법 모두 자동 생성된 쿼리는 다음과 같습니다.

delete
from issues
where id=<입력된 id>

deleteQuery 구문 자체를 잘못 작성한건가요? 올바른 사용법이 어떻게 되는지 가르쳐 주셨으면 합니다.

아래는 Entity 파일 내용 입니다.

@Entity
@Table(name = "issues")
data class Issue(
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long? = null,

    @Column(name = "user_id")
    var userId: Long,

    @Column(name = "user_name")
    var userName: String,

    @OneToMany(
        fetch = FetchType.LAZY,
        mappedBy = "issue",
        cascade = [CascadeType.ALL],
        // orphanRemoval = true
    )
    val comments: Set<Comment> = emptySet(),

    @Column(name = "summary")
    var summary: String,

    @Column(name = "description")
    var description: String,

    @Column(name = "type")
    @Enumerated(EnumType.STRING)
    var type: IssueType,

    @Column(name = "priority")
    @Enumerated(EnumType.STRING)
    var priority: IssuePriority,

    @Column(name = "status")
    @Enumerated(EnumType.STRING)
    var status: IssueStatus,
)
@Entity
@Table(name = "comments")
data class Comment(
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long? = null,

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "issue_id") // FK 외래키
    val issue: Issue,

    @Column(name = "user_id")
    val userId: Long,

    @Column(name = "user_name")
    val userName: String,

    @Column(name = "body")
    var body: String,
)
shouwn commented 1 year ago

@cj848 안녕하세요. Delete 쪽에 대해서는 제가 잘 몰라서 혹시 위의 문의 내용 확인 가능하신가요?

cj848 commented 1 year ago

delete query 는 cascade 를 처리할 수 없습니다. 이유는 쿼리를 직접 생성해서 호출하는 형태이기 때문입니다. cascade 는 select 후 delete 를 entity manager 의 remove 를 통해 수행해야 합니다. // orphanRemoval = true 주석처리하신 부분도 살리셔야 합니다.

정리하면, jdsl 로는 cascade 로 자동 삭제가 불가능합니다.

EC-Sol commented 1 year ago

@cj848 답변 감사합니다

cj848 commented 1 year ago

업무가 좀 많아서 자세히 볼 여유가 없어서 답이 좀 많이 늦어졌습니다. 죄송합니다. 양해 부탁드립니다.