영속성 콘텍스트의 범위.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)
[질문 내용]
안녕하세요.
영속성콘텍스트에 영속화된 Entity 로 생각이 드는데도 불구하고 영속성 콘텍스트가 아니고 쿼리의 호출결과로 데이터를 얻어오는 부분이 있어서 질문을 드립니다.
테스트 코드는 아래와 같습니다.
참고: boardId = boardEntity @Id
@Transactional
public BoardDto updateBoard(Integer boardId, String title) {
jBoardEntity entity = jpaQueryFactory.selectFrom(boardEntity).where(boardEntity.baordId.eq(boardId)).fetchOne();
entity.updateTitle(title);
entityManagerFactory.getPersistenceUnitUtil().isLoaded(entity) // true
return jpaQueryFactory.selectFrom(boardEntity).where(boardEntity.baordId.eq(boardId)).fetchOne();
}에서 처음 selectFrom 때 select 쿼리후 entity 정상반환하여 영속회되고 update title 문까지 정상동작합니다.
이후 영속성 콘텍스트에 로드가 됐다는걸 확인해보았고 동일한 ID 의 entity 를 조회했을때는 영속성 컨텍스트에서 제공되길 기대했으나 console 로그에는 sql 이 나가는 것으로 보아 실제 db 에 sql 이 작동한것으로 보입니다.
혹시 제가 놓친 부분이있다면 말씀해주시면 감사하겠습니다.
回答 2
0
안녕하세요, 인프런 AI 인턴이에요.
영속성 컨텍스트의 범위에 대해 궁금하신 것 같네요. 영속성 컨텍스트는 엔티티를 관리하고, 변경 사항을 추적하며, 데이터베이스와의 상호 작용을 관리하는 역할을 합니다.
보통 영속성 컨텍스트는 트랜잭션 범위 내에서 동작하며, 트랜잭션이 종료될 때 함께 종료됩니다. 따라서 영속성 컨텍스트는 트랜잭션당 하나의 범위를 가지게 됩니다.
하지만 코드를 보면, updateBoard 메서드 안에서 selectFrom 하는 시점에 영속성 컨텍스트가 이미 존재하고 있는 것 같습니다. 그리고 updateTitle 메서드를 호출하여 엔티티의 상태를 변경한 후, 다시 selectFrom하여 같은 엔티티를 가져옵니다.
이 경우, 이미 영속성 컨텍스트에 존재하는 엔티티가 업데이트되는 것이므로, 영속성 컨텍스트에서 찾아보는 동작은 발생하지 않습니다. 대신 쿼리를 실행하여 새로운 결과를 가져올 것입니다.
영속성 컨텍스트는 엔티티를 식별자(보통은 기본 키)를 통해 추적하므로, 엔티티가 변경되지 않은 경우에는 쿼리를 실행하지 않고 영속성 컨텍스트에 있는 엔티티를 반환하게됩니다. 따라서 여러분이 기대하는 것과는 조금 다른 결과가 나타날 수 있습니다.
이를 해결하기 위해서는 영속성 컨텍스트에 있는 엔티티를 제거하고 다시 쿼리를 실행하는 방법을 사용할 수 있습니다. entityManager.clear() 메서드를 호출하면 현재 영속성 컨텍스트의 내용이 초기화되고, 다음 쿼리 실행 시 새로운 결과를 가져오게 됩니다.
영속성 컨텍스트와 관련한 깊은 이해가 필요한 부분이기 때문에, 더 자세한 내용을 알고 싶으시다면 관련된 책이나 강의를 참고하는 것이 좋을 것 같습니다. 질문 주셔서 감사합니다.
0
수정된 질문을 올리겠습니다.
우선 코드부터 작성해보면
@Transactional
public BoardDto updateBoard(Integer boardId, String title) {
BoardEntity entity = jpaQueryFactory.selectFrom(boardEntity).where(boardEntity.baordId.eq(boardId)).fetchOne();
entityManagerFactory.getPersistenceUnitUtil().isLoaded(entity) // true
return jpaQueryFactory.selectFrom(boardEntity).where(boardEntity.baordId.eq(boardId)).fetchOne();
}update 부분만 제거하였습니다.
첫번째 selectFrom (db 에 실제 select 문이 실행됨) 으로 부터 얻어온 entity가 영속화 된걸 동일하게 isLoaded 로 확인하였습니다.
문제는 이후 다시 selectFrom 으로 return 받을때는 영속화된 객체를 그대로 줄것으로 예상했으나 console 에는 db에 실제 select 문이 실행되는것으로 확인하였습니다.
결과적으로는 select 문이 2번 실행되는것을 확인하였습니다.
해당 결과에 대해서 놓친부분이 있다면 말씀해주시면 감사하겠습니다.
SpringBoot 4.X에서의 Querydsl 설정
0
85
2
querydsl 오픈소스에 대한 질문
0
71
1
예제에서의 카운트 쿼리에서 join문과 where문은 필요없지 않나요?
0
108
1
Querydsl 6.X버전에 대해서 어떻게 생각하시나요?
0
316
2
여러 테이블 조인하여 통계치를 구하고자 할 때 어떤 방법이 더 효율적일까요
1
69
1
fetchResults()는 더이상 권장되지 않는다는데 맞나요?
0
160
1
querydsl sum() 메서드 없어요.
0
158
2
build 디렉터리 생성
0
135
2
자바 ORM 표준 JPA 프로그래밍 - 기본편 듣고 바로 학습해도 괜찮을까요?
0
113
2
현재 Querydsl에서 from절 서브쿼리를 지원하나요?
0
90
1
오타 제보 드립니다.
0
71
2
벌크 연산과 flush, clear
0
76
1
Run As Intellij 로 변경시 Q타입 import 불가
0
87
1
QHello import하기 문제 발생
0
147
2
등록된 함수 보는법(H2Dialect) 질문
0
68
2
5.0부터 Querydsl은 향후 fetchCount() , fetchResult() 를 지원하지 않기로 결정했다고 하는데 이에 맞는 강의
1
195
2
[환경설정 PDF 부트 3.0이후 설명 질문] build.gradle에 compileQuerydsl을 정의하지 않은 상태에서 Gradle->Tasks->other->compileQuerydsl을 클릭하라고 하는 이유가 무엇인가요??
1
200
1
querydsl 설정 문제
0
222
2
quey dsl 설정부분
0
158
2
count 쿼리 관련 질문입니다!
0
75
1
stringtemplate를 이용하여 where절 검색 방법 질문 드립니다.
0
89
1
답변부탁드리겠습니다.
0
89
2
(OrderSpecifier)관련 내용 어디있을가요
0
65
1
중급문법 벌크연산에서
0
81
2

