JPA - JPAQuery와 Q클래스

2021. 4. 17. 02:20 Spring Data/Spring Data JPA

JPA - JPAQuery와 Q클래스

긴 포스팅은 아니지만 예제로 소스를 짜는 도중에 몰랐던 내용을 알게되어서 작성한다. QueryDSL로 예제중 나온 상황이다.

 

public List<MyEntity> findMyDumbEntities(long id) {    
      QMyEntity qMyEntity = QMyEntity.myEntity;
      JPAQuery jpaQuery = new JPAQuery(entityManager);
      MyEntity myFirstEntity = jpaQuery.from(qMyEntity)
                                        .where(qMyEntity.id.eq(id)).uniqueResult(qMyEntity);
      MyEntity mySecondEntity = jpaQuery.from(qMyEntity)
                                        .where(qMyEntity.id.eq(id+1)).uniqueResult(qMyEntity);
 
      return Arrays.asList(myFirstEntity, mySecondEntity);    
}

 

언뜻 보기에는 크게 문제가 없는 듯 싶다. 하지만 이 소스를 실행하면 이러한 예외가 발생한다.

 

 

java.lang.IllegalStateException: qMyEntity is already used

 

즉, 같은 JPAQuery 객체로 같은 Q타입클래스를 사용할 수없는 것이다. 사실 내부를 까보지는 않아서 원인파악은 해보아야겠지만 일단 결론은 그렇다. 그렇기 때문에 소스가 이런식으로 변경되어야한다.

 

public List<MyEntity> findMyDumbEntities(long id) {        
          QMyEntity qMyEntity = QMyEntity.myEntity;
          MyEntity myFirstEntity = new JPAQuery(entityManager).from(qMyEntity)
                                    .where(qMyEntity.id.eq(id)).uniqueResult(qMyEntity);
          MyEntity mySecondEntity = new JPAQuery(entityManager).from(qMyEntity)
                                    .where(qMyEntity.id.eq(id+1)).uniqueResult(qMyEntity);
 
          return Arrays.asList(myFirstEntity, mySecondEntity);        
}

이런식으로 JPAQuery 객체를 만드는 메소드를 하나 정의하는 것이 좋을 것같다.

 

protected JPQLQuery jpaQuery() {
    return new JPAQuery(entityManager);
}
 
@Override
public List<Article> findAll() {
      return jpaQuery().from(article).fetchAll().list(article);
}
 
public Article findById(@Nonnull final long id) {
      return jpaQuery().from(article).where(article.id.eq(id)).uniqueResult(article);
}



출처: https://coding-start.tistory.com/103?category=781616 [코딩스타트]