spring/spring jpa

[SpringBoot] JPA Comment (주석 추가) 설정 방법

moonsiri 2024. 2. 2. 15:16
728x90
반응형

JPA Comment (주석 추가) 설정 방법

 

application.yml

spring:
  jpa:
    properties:
      hibernate:
       show_sql: false
       format_sql: true
       use_sql_comments: true	# sql comments 사용

 

1. JPA Repository에 적용 방법

To apply JPA QueryHints to the queries declared in your repository interface you can use the QueryHints annotation. It takes an array of JPA QueryHint annotations plus a boolean flag to potentially disable the hints applied to the addtional count query triggered when applying pagination.

public interface UserRepository extends Repository<User, Long> {

      @QueryHints({
            @QueryHint(name = org.hibernate.annotations.QueryHints.COMMENT, value = "select user info")
      })
      Optional<User> findByUserId(String userId);
}
더보기

1-1. Custom hibernate interceptor

JPA에 일괄 적용하기

	@Bean
	public EntityManagerFactory entityManagerFactory(DataSource dataSource, StatementInspector jpaCommentMaker) {

		LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
		// ....

		Map<String, Object> properties = new HashMap<>();
		properties.put(AvailableSettings.STATEMENT_INSPECTOR, jpaCommentMaker);
		// ....
		factory.setJpaPropertyMap(properties);
		factory.afterPropertiesSet();

		return factory.getObject();
	}

	@Bean
	public Interceptor hibernateInterceptor() {
		return new JPACommentMaker();
	}
@Component
public class JPACommentMaker implements StatementInspector {
	private static final String COMMENT_FORMAT = "/* %s */ ";
	private static final String JPA_REPOSITORY_SUFFIX = "Repository";

	@Override
	public String inspect(String sql) {
		return this.comment().map(from -> String.format(COMMENT_FORMAT, from) + sql).orElse(sql);
	}

	private Optional<String> comment() {
		StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
		for (StackTraceElement element : stackTrace) {
			if (StringUtils.endsWithIgnoreCase(element.getClassName(), JPA_REPOSITORY_SUFFIX)) {
				return Optional.of(element.getClassName() + SEPERATOR_DOT + element.getMethodName());
			}
		}

		return Optional.empty();
	}

}

 

2. QueryDSL에 적용 방법

@Repository
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class UserRepositoryCustom {

	private final JPAQueryFactory jpaQueryFactory;

	private static final String JPA_COMMENT_KEY = "org.hibernate.comment";

	public User findById(String userId) {
		return jpaQueryFactory.selectFrom(user)
			.where(user.userId.eq(userId))
			.setHint(JPA_COMMENT_KEY, "select user info")
			.fetchOne();
	}
}
더보기

2-1. JPAQueryFactory Custom

queryDsl에 일괄 적용하기

public class CustomJPAQueryFactory extends JPAQueryFactory {

	private static final String JPA_COMMENT_KEY = "org.hibernate.comment";

	public CustomJPAQueryFactory(EntityManager entityManager) {
		super(entityManager);
	}

	public CustomJPAQueryFactory(JPQLTemplates templates, EntityManager entityManager) {
		super(templates, entityManager);
	}

	public CustomJPAQueryFactory(Provider<EntityManager> entityManager) {
		super(entityManager);
	}

	public CustomJPAQueryFactory(JPQLTemplates templates, Provider<EntityManager> entityManager) {
		super(templates, entityManager);
	}

	@Override
	public JPAQuery<?> query() {
		return super.query().setHint(JPA_COMMENT_KEY, this.comment());
	}

	/**
	 * Query Comment
	 *
	 * @return repository class, repository method
	 */
	private String comment() {
		try {
			for (int i = 4; i <= 6; i++) {
				StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[i];
				if (stackTraceElement.getClassName().endsWith("RepositoryCustom")) {	// queryDSL은 *RepositoryCustom 클래스 사용
					return stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName();
				}
			}
		} catch (Exception ignored) {
		}

		return null;
	}
}
@Configuration
public class QueryDslConfiguration {

	@PersistenceContext
	private EntityManager entityManager;

	@Bean
	public JPAQueryFactory jpaQueryFactory() {
		return new CustomJPAQueryFactory(entityManager);
	}
}

 

3. 결과

2024-02-02 15:02:07 [DEBUG] org.hibernate.SQL:128 - 
    /* select user info */ select
        user0_.`user_id` as col_0_0_,
        user0_.`user_nm` as col_1_0_
    from
        `user` user0_ 
    where
        user0_.`user_id`=?

 

[Reference]

https://docs.spring.io/spring-data/jpa/reference/jpa/query-methods.html#jpa.query-hints

728x90
반응형