기존 레거시는 Oracle과 MyBatis를 사용하여 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에 주석을 사용하기 위해서는 Hibernate에 use_sql_comments속성을 추가해야 한다.
spring:
jpa:
...
properties:
hibernate:
use_sql_comments: true
...
이후 JPA Query Method에 @QueryHints와 @QueryHint를 추가하여 사용하고자 하는 Hint의 name과 value를 설정하면된다.
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가 출력되지 않는 이유가 약간 이해가 되었다. 해당 메소드로 실행되어야 하는 DML이 CREATE인지 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 조회로 해당 관리가 의미가 있는지는 잘 알지 못하겠다.