작성
·
1.2K
0
@Entity
@Table(name = "tbl_board")
class Board (
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
val bdSeq: Int? = null,
var bdTitle: String?,
var bdContents: String?,
var bdRegdt: LocalDateTime? = LocalDateTime.now(),
@OneToMany(fetch = FetchType.LAZY, mappedBy = "board")
@Filter(name = "filterTest", condition = "bdcSeq = :bdcSeq")
var boardCmts: MutableSet<BoardCmt> = mutableSetOf(),
@OneToMany(fetch = FetchType.LAZY, mappedBy = "board")
var boardTags: MutableSet<BoardTag> = mutableSetOf()
)
@Entity
@Table(name = "tbl_board_cmt")
class BoardCmt(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
val bdcSeq: Int? = null,
@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "bd_seq")
var board: Board?,
var bdcContents: String?,
@OneToMany(fetch = FetchType.LAZY, mappedBy = "boardCmt")
var boardCmtTags: MutableSet<BoardCmtTag> = mutableSetOf()
)
두개의 엔티티가 있는데
val board = QBoard.board
val boardTag = QBoardTag.boardTag
val boardCmt = QBoardCmt.boardCmt
val rows = query.select(board, boardCmt)
.from(board)
.leftJoin(board.boardCmts, boardCmt).on(boardCmt.bdcSeq.notIn(100)).fetchJoin()
.fetch()
// 오류
// org.hibernate.query.SemanticException: with-clause not allowed on fetched associations; use filters
오류가 발생합니다.
fetchJoin을 쓰면 on을 못쓰고 on을 쓰면 fetchJoin을 못쓰는 상황입니다.
이와 관련해서 솔루션이 없는게 이해가 안되요. github나 stackoverflow나...
제가 유일하게 찾은 솔루션은 두개
// case 1 (query에서 on 조건을 빼고 kotlin에서 filter를 이용해서 처리)
// comment 데이터가 많을수록 db성능 최악
val board = QBoard.board
val boardCmt = QBoardCmt.boardCmt
var rows = query.selectFrom(board)
.leftJoin(board.boardCmts, boardCmt).fetchJoin()
.fetch()
rows = rows.map {
it.boardCmts.filter { f -> f.bdcSeq != 100 }
it
}
// case 2 (Tuple로 각각 받아와서 board 엔티티에 밀어넣기
// 쿼리성능에 이슈가 없지만 매핑하는데 피로도 상승
val rows = query.select(board, boardCmt)
.from(board)
.leftJoin(board.boardCmts, boardCmt).on(boardCmt.bdcSeq.notIn(100))
.fetch()
return rows.fetchTest(board) { entity, fetchData ->
entity.boardCmts = mutableSetOf()
fetchData.forEach {
it.get(boardCmt)?.let { item -> entity.boardCmts.add(item) }
}
}.map { it.toDto() }
테이블마다 DEL_YN 필드가 들어가는 바람에
leftjoin시 필수로 on(board.delYn.eq("Y)) 가 들어가야 되는 상황인데
fetchJoin은 성능상 꼭 쓰고싶고, on은 반드시 들어갸야되고
참 어렵습니다.
답변 1
0
안녕하세요, 인프런 AI 인턴이에요.
fetchJoin과 on 절을 동시에 사용하면 with-clause not allowed on fetched associations; use filters 오류가 발생하게 됩니다. 이 오류는 Hibernate 성능과 일관성을 보장하기 위한 제한입니다. 두 가지를 함께 사용하려면 하나를 필터로 변경해야 합니다. 따라서, case 1에서는 query에서 on 조건을 제거하고, Kotlin의 filter를 사용해서 처리할 수 있고, case 2에서는 각각의 값을 Tuple 로 받아와 board 엔티티에 밀어넣는 방법으로 해결할 수 있습니다.
데이터의 양이 많아지면 성능 이슈가 발생할 수 있는데, 이 경우에는 쿼리문이 복잡해질 수밖에 없습니다.
마지막으로, DEL_YN 필드가 들어가서 반드시 on(board.delYn.eq(“Y”)) 가 들어가야 하는 상황이라면, on 절을 잘 작성하여 fetchJoin을 성공적으로 수행하실 수 있습니다.
도움이 되었기를 바라며, 추가적으로 궁금하신 사항이 있으면 언제든지 문의해주세요. 감사합니다.