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 */\n";
@Override
public String inspect(String sql) {
return QueryContext.get()
.map(comment -> String.format(COMMENT_FORMAT, comment) + sql)
.orElse(sql);
}
}
public class QueryContext {
private static final ThreadLocal<String> context = new ThreadLocal<>();
public static void set(String source) {
context.set(source);
}
public static Optional<String> get() {
return Optional.ofNullable(context.get());
}
public static void clear() {
context.remove();
}
}
@Aspect
@Component
public class QuerySourceAspect {
@Pointcut("within(org.springframework.data.repository.Repository+)")
public void springDataRepository() {}
@Pointcut("execution(* *..repository..*RepositoryCustom.*(..))")
public void customRepository() {}
@Around("springDataRepository() || customRepository()")
public Object traceRepositoryCall(ProceedingJoinPoint pjp) throws Throwable {
try {
Class<?> actualClass;
Object target = pjp.getTarget();
// 프록시인 경우: 인터페이스를 직접 가져옴
if (Proxy.isProxyClass(target.getClass())) {
Class<?>[] interfaces = target.getClass().getInterfaces();
actualClass = (interfaces.length > 0) ? interfaces[0] : target.getClass();
} else {
actualClass = target.getClass();
}
String source = actualClass.getName() + "." + pjp.getSignature().getName();
QueryContext.set(source);
return pjp.proceed();
} finally {
QueryContext.clear();
}
}
}
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();
}
}
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
반응형
'spring > spring jpa' 카테고리의 다른 글
| [JPA] Entity에 Enum 사용하기 (0) | 2024.04.25 |
|---|---|
| [QueryDSL] FullText 검색을 위한 Match ... against 절 사용법 (0) | 2023.08.24 |
| [SpringBoot] QueryDSL org.apache.jasper.JasperException: Unable to compile class for JSP: (0) | 2023.08.24 |
| [SpringBoot2] JPA Master/Slave 구조 분기 처리 (2) | 2023.08.23 |
| [SpringBoot] JPA Projection (0) | 2021.06.23 |
댓글