매장에 대해 추천 메뉴를 재설정하는 로직을 작성할 때 오류가 발생했습니다..
update 쿼리 실행 후, select 조회 후 값을 변경 하였지만, 값이 변경되지 않았습니다. ( 변경 감지 안됨 )
@Transactional public void updateRecommendationSideMenu(long marketId, List<Long> menuId) { menuRepository.resetRecommendSideMenu(marketId); List<Menu> menus = marketRepository.findMarketMenuById(marketId, menuId); for(Menu menu : menus) { menu.setRecommendSideMenu(); } }
위의 로직은 다음과 같이 진행됩니다.
추천 사이드 메뉴 제거 > 메뉴 검색 > 해당 메뉴를 추천 사이드 메뉴로 설정
로그에서는 첫 번째 update문이 잘 실행되고 있었습니다. 이후 for 문 안에 수정 대상이 되는 엔티티가 정상적으로 순회가 되고 있었으나, 특정 엔티티는 update 문이 실행되지 않는 문제를 확인했습니다.
for문을 통해 데이터를 모두 출력했을 땐 모든 데이터가 잘 조회되는 것 같다..
로그를 확인해 봤을 때 특정 엔티티가 update되지 않았다. find 메서드를 통해 조회는 되지만 update가 실행되지 않는데, 이유는 다음과 같은 가설을 세울 수 있습니다.
1차 캐시
)변경 감지
가 동작하지 않는다.entityManager.clear();
를 통해서 영속성 컨텍스트를 초기화 해보자
문제가 해결이 되었다.
@Override
public long resetRecommendSideMenu(long marketId) {
List<Menu> menus = jpaQueryFactory.select(menu)
.from(market)
.innerJoin(market.menuContainers, menuContainer)
.innerJoin(menuContainer.menus, menu)
.where(market.marketId.eq(marketId))
.fetch();
return jpaQueryFactory.update(menu).set(menu.isRecommendSideMenu, false)
.where(menu.in(menus))
.execute();
}
영속성 컨텍스트에 들어가 있는 이유는 저 위의 이유입니다..
처음 메뉴를 초기화 하는 과정에서 select 문을 통해 모든 menu를 조회했기 때문에 영속성 컨텍스트에 해당 엔티티가 들어가있습니다.
JPA에 대해서 기본 이해가 없었다면 절대로 풀지 못했을 것이였다..
영속성 컨텍스트의 특징과 메서드를 잘 알고 있지 않았다면 많은 삽질을 했을 것이다.