- analysis/·source-index·state.json 을 final/document.md 제2부·제3부로 접었다. SSOT 는 하나다 - 파일럿 — commit-ambiguity-as-a-result 를 새 기준으로 재선별. 후보 14 → 글감 5 (PROMOTE 5 · MERGE_INTO 3 · KEEP_IN_SSOT 4 · 보류 2). 기록 5건을 다시 썼고 그림 1개를 techviz 로 만들었다 - 재선별이 잡은 것: 제1부 §6.2·§11.1 이 자기 §13.2 와 어긋나 있었다(레인을 안 돌렸다 vs 돌렸다) — 정정. 이미 답이 나와 있던 Question 을 HEAD 재실행 질문으로 다시 세웠다. Concept 이 인용한 코드가 SSOT 에 없어 뺐다 - candidateScope·sourceRepository 기록. 나머지 43개 주제는 재선별 대기(PENDING 905) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
8.3 KiB
kind, slug, title, topic, project, status, sourceRevision, rootTreeNode, evidenceCapturedOn, assets, evidence, source
| kind | slug | title | topic | project | status | sourceRevision | rootTreeNode | evidenceCapturedOn | assets | evidence | source | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| CASE | a05-f018-sql | 쿼리 이름을 SQL 로 옮기는 두 경로가 양쪽 끝만 있고 가운데가 없다 | runtime-reachability-and-composition | clean-architecture-backend-template | 게시 전 | 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916 | case:a05-f018-sql | 2026-09-02 |
|
|
|
쿼리 이름을 SQL 로 옮기는 두 경로가 양쪽 끝만 있고 가운데가 없다
쿼리 이름을 SQL 주석으로 실어 나르는 문장 검사기가 있다. 어떤 SessionFactory 도 그것을 설치하지 않아 inspect() 가 호출되지 않는다. 두 번째 경로인 org.hibernate.comment 힌트도 그것을 SQL 로 내보내는 설정이 꺼져 있다. 이름을 넣는 프로덕션 클래스 셋은 자기 단위 테스트 밖에서 쓰이지 않는다.
관계
- @Bean이 있다는 것은 조립 증거가 아니다 구현의 존재를 조립의 증거로 읽는다는 점이 같다.
- 이름은 값이 아니라 registry key다 쿼리 이름이 등록된 식별자로 쓰이는 맥락이다.
- 카디널리티 경계를 타입으로 표현하기 그 이름이 메트릭 태그가 되는 경계다.
문제
주석에 이름이 실려야 DBA 가 눈앞의 문장을 어느 유스케이스에서 나온 것인지 되짚는다. 검사기 javadoc 이 그 이유를 적고, 없으면 어느 엔드포인트가 이 쿼리를 내는지를 SQL 조각으로 코드베이스를 뒤져 답하게 된다고 덧붙인다.
결론
inspect() 는 다 쓰여 있다. 현재 스레드에 묶인 이름을 꺼내 /* 이름 */ 을 앞에 붙이고, 이름에 주석 종료자가 있으면 원본을 돌려준다. 그 분기는 도달하지 않는다. QueryName 의 형식 [a-z][a-z0-9.-]{2,95} 가 이미 * 와 / 를 막고, javadoc 도 그 검사를 additionally 라고 적는다.
단위 테스트는 없다. 검사기에도 컨텍스트에도 테스트 파일이 없다.
SessionFactory 가 설치해 주지 않으면 inspect() 는 불리지 않는다. 네 경로는 저장소 루트에서 확장자 제한 없이 훑어 얻었다. 설정 키 0, HibernatePropertiesCustomizer 와 SessionFactoryBuilder 와 ServiceRegistry 와 Integrator 0, persistence.xml 0, 런타임 리소스의 FQCN 0 이다.
이름을 넣는 쪽은 배선되어 있다. QueryNameContext.with(...) 를 부르는 프로덕션 코드가 셋이다. 그 컨텍스트를 읽는 쪽은 검사기 하나뿐이다.
SQL 로 이름을 옮기는 길이 그것 말고 또 있다. org.hibernate.comment 힌트를 거는 것은 리포지토리 조각 지원과 Querydsl 지원이다. 그 힌트도 스위치 하나에 달려 있는데 저장소에 그 키가 0 이다.
두 경로 다 이름을 넣는 코드와 그것을 읽는 자리는 있는데, 그 사이를 잇는 설치와 스위치가 없다.
넣는 세 클래스도 실행되지 않는다. 각 타입을 쓰는 파일은 자기 자신과 자기 단위 테스트뿐이고, 리포지토리 조각 지원을 상속하는 유일한 코드도 그 테스트 안의 중첩 클래스다.
검증 환경
OpenJDK : 21.0.12 확인 방식 : 설치 경로 넷을 저장소 루트에서 계수, 이름을 넣고 읽는 지점 추적, 두 번째 경로의 활성 설정 확인 소스 수정 : x
재현 조건
- 검사기 구현과 javadoc, 그리고 QueryName 의 형식 정규식을 읽는다.
- 저장소 루트에서 확장자 제한 없이 설치 경로 넷을 각각 센다.
- 그 클래스의 단위 테스트가 있는지 찾는다.
- 이름을 넣는 호출과 읽는 호출을 각각 센다.
- org.hibernate.comment 힌트를 거는 곳과, use_sql_comments 를 켜는 곳을 센다.
- 넣는 세 클래스를 쓰는 파일과 상속하는 코드를 전부 나열한다.
본문
쿼리 이름이 SQL 주석으로 실려야 DBA 가 pg_stat_activity 나 느린 쿼리 로그의 문장을 유스케이스로 되돌릴 수 있다. 검사기 javadoc 이 그 이유를 적는다.
inspect() 가 하는 일
:::evidence key="a05-f018-sql" alt="문장 검사기의 javadoc 앞부분과 클래스 본문, 쿼리 이름의 형식 정규식, 하이버네이트가 이 구현을 설치하는 경로 넷을 저장소 루트에서 확장자 제한 없이 센 결과와 그 클래스의 단위 테스트 수, 이름을 컨텍스트에 넣는 세 곳과 읽는 곳, 이름을 SQL 로 옮기는 두 번째 경로와 그것을 활성화하는 설정의 수, 그리고 넣는 세 클래스를 쓰는 파일과 상속하는 코드를 출력한 터미널 기록." caption="검사기 javadoc 과 본문 · 이름 형식이 이미 * 와 / 를 막음 · 설치 경로 넷 전부 0 · 단위 테스트 0 · 넣는 곳 셋과 읽는 곳 하나 · 두 번째 경로의 use_sql_comments 0 · 세 클래스는 자기 테스트만 — 69줄 · exit 0" zoom="true" :::
public String inspect(String sql) {
if (sql == null) {
return null;
}
Optional<QueryName> queryName = QueryNameContext.current();
if (queryName.isEmpty()) {
return sql;
}
String value = queryName.get().value();
if (value.contains(COMMENT_TERMINATOR)) {
return sql;
}
return "/* " + value + " */ " + sql;
}
현재 스레드에 묶인 이름을 꺼내 주석으로 붙인다. 이름에 */ 가 있으면 원본을 돌려주는 분기가 하나 더 있는데, QueryName 의 형식 [a-z][a-z0-9.-]{2,95} 가 이미 * 와 / 를 막으므로 도달하지 않는다. javadoc 도 그 검사를 additionally 라고 적는다.
이 클래스에는 단위 테스트가 없다. 컨텍스트 쪽도 없다.
검사기를 설치하는 설정이 없다
하이버네이트가 inspect() 를 부르려면 SessionFactory 가 이 구현을 설치해야 한다. 설치 경로 넷을 저장소 루트에서 확장자 제한 없이 셌다.
statement_inspector 설정 키 : 0
HibernatePropertiesCustomizer / SessionFactoryBuilder / Integrator : 0
persistence.xml : 0
런타임 리소스의 FQCN : 0
이름을 컨텍스트에 넣는 세 곳
JpaStreamExecutor:63, JpaKeysetQuerySupport:49, JpaRepositoryFragmentSupport:72 가 작업을 감싸며 이름을 컨텍스트에 넣는다. 그 컨텍스트를 읽는 코드는 검사기 하나다.
이름을 SQL 로 옮기는 경로는 하나가 더 있다. 리포지토리 조각 지원과 Querydsl 지원이 org.hibernate.comment 힌트를 건다.
return entityManager.createQuery(jpql, resultType).setHint(COMMENT_HINT, name.value());
그 힌트가 SQL 로 나오려면 hibernate.use_sql_comments 가 켜져야 한다. 저장소에 그 키는 0 이다.
두 경로 모두 양쪽 끝만 있고 가운데가 없다.
세 클래스의 프로덕션 참조
각 타입을 쓰는 파일은 자기 자신과 자기 단위 테스트뿐이다. 리포지토리 조각 지원을 상속하는 유일한 코드도 그 테스트 안의 중첩 클래스다.
스프링 데이터의 조각 규약으로 연결될 여지도 없다. 그 클래스는 인터페이스가 아니라 추상 클래스이고, repositoryBaseClass 도 @NoRepositoryBean 도 저장소에 없다.
이름은 실행 경로에 오르지 않는다.
확인하지 못한 것
애플리케이션을 부팅해 실제 문장에 주석이 붙지 않는 것을 관측하지 않았다. 설치 경로와 호출 지점을 센 것까지가 확인 범위다.