JPA Query Comment 사용

YouMakeMeSmile·2021년 6월 7일
2

기존 레거시는 OracleMyBatis를 사용하여 SQL 를 자유롭게 작성하여 사용했었다. 이러하여 모든 DML(SELECT, INSERT, UPDATE, DELETE) 바로 뒤에 표준으로 반드시 SQL_ID가 작성되었으며 각종 Oracle Hint가 사용되었다.

SELECT /* user.retrieveById*/
       ID,
       NAME,
       AGE
  FROM USER
 WHERE ID = #id#

이번 MSA로 전환하며 Oracle에서 MySql로 전환되고 MyBatis에서 JPA로 전환하여 기존 Hint는 사용하지 못하지만 요구사항중 하나는 SQL_ID는 남겨야 한다는 것이였다.


우선 JPA에서 SQL에 주석을 사용하기 위해서는 Hibernateuse_sql_comments속성을 추가해야 한다.

spring:
  jpa:
    ...
    properties:
      hibernate:
        use_sql_comments: true
        ...

이후 JPA Query Method@QueryHints@QueryHint를 추가하여 사용하고자 하는 Hintnamevalue를 설정하면된다.

public interface UserRepository extends JpaRepository<User, String> {
    @QueryHints({
            @QueryHint(name = org.hibernate.annotations.QueryHints.COMMENT, value = "userRepository.findAll")
    })
    List<User> findAll();

    @QueryHints({
            @QueryHint(name = org.hibernate.annotations.QueryHints.COMMENT, value = "userRepository.findById")
    })
    Optional<User> findById(String id);

    @QueryHints({
            @QueryHint(name = org.hibernate.annotations.QueryHints.COMMENT, value = "userRepository.save")
    })
    User save(User user);
}

위와 같이 설정 후 findAll* 메소드들의 쿼리 실행 로그를 살펴 보면 @QueryHints의 설정대로 Comment가 추가되는 것을 확인할 수 있다.

Hibernate: 
    /* userRepository.findAll */ select
        user0_.id as id1_0_,
        user0_.age as age2_0_,
        user0_.name as name3_0_ 
    from
        user user0_

하지만 save, findById등의 메소드의 쿼리는 생각과 다르게 Comment가 생성되거나 생성되지 않았다.

  • save 쿼리
Hibernate: 
    /* load io.velog.youmakemesmile.queryhint.entity.User */ select
        user0_.id as id1_0_0_,
        user0_.age as age2_0_0_,
        user0_.name as name3_0_0_ 
    from
        user user0_ 
    where
        user0_.id=?
Hibernate: 
    /* insert io.velog.youmakemesmile.queryhint.entity.User
        */ insert 
        into
            user
            (age, name, id) 
        values
            (?, ?, ?)

실행된 쿼리의 결과를 보고 생각처럼 Comment가 출력되지 않는 이유가 약간 이해가 되었다. 해당 메소드로 실행되어야 하는 DMLCREATE인지 UPDATE 인지 @QueryHints에서는 지정할 수 없었다. 또한 load 이후 insert가 출력되는 것으로 보아 use_sql_comments 속성은 hibernate에서 동작하는 쿼리 메소드에 적용되는 것으로 추측된다.

  • findById 쿼리
Hibernate: 
    select
        user0_.id as id1_0_0_,
        user0_.age as age2_0_0_,
        user0_.name as name3_0_0_ 
    from
        user user0_ 
    where
        user0_.id=?

테스트를 위해서 findById 메소드의 실행 쿼리를 확인해 보았는데 아무런 Comment가 출력되지 않았다. 어떠한 이유로 기본 Comment도 출력되지 않았는지 추후에 시간이 된다면 디버깅 해볼 예정이다.


결론적으로는 @QueryHints를 이용하면 Comment를 추가 SQL_ID를 출력할 수 있지만 findAllBy* 메소드에만 적용한 Comment가 출력되는 것으로 확인하였다.
또한 추가적으로 레거시에서 처럼 SQL를 직접 작성하여 호출 하는 형태가 아니기 때문에 해당 Comment 위치를 직접 지정하지 못하는 큰 문제가 있다. 추가적으로 SQL_ID를 통해 많은 시간이 소요되는 쿼리를 관리하기위해 Comment를 추가하는 것으로 생각되는데 JPA Query Method의 경우 대부분이 Equal 조회로 해당 관리가 의미가 있는지는 잘 알지 못하겠다.

profile
어느새 7년차 중니어 백엔드 개발자 입니다.

0개의 댓글