Files
document-haness/docs/clean-architecture-backend-template/final/evidence/rendered/a05-f018-sql.svg
T
DongHyeonkaandClaude Opus 5 b2963105a8 docs(keycloak-session-store): import the session-storage lab as a new project
The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.

Follows the import procedure in README.md.

  source/     the originating repository verbatim — 78 documents, 28 SVGs,
              8 manifests, plus .source-revision recording the commit
  final/      the SSOT
    document.md   729 lines written from the 29 experiment documents, not
                  concatenated: what was predicted, what was measured, and
                  where the measurement itself was wrong
    evidence/raw    125 outputs, flattened to <experiment>__<file> because
                    the originals collided (01-baseline.txt appeared three
                    times) and the audit only globs the top level
    evidence/meta   one per raw file; command and exitCode are null and the
                    README says why rather than inventing them
    evidence/browser  22 captures
    assets/       three diagrams through techviz
    .techviz/     their VizSpecs

A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.

Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.

verify-pipeline.py passes. audit-records.py reports no issues.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 22:51:59 +09:00

127 lines
22 KiB
XML

<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="2394" viewBox="0 0 1200 2394" role="img">
<title>terminal evidence</title>
<desc>Terminal-style rendering generated from retained command output. Sensitive-looking values are redacted in the visual asset.</desc>
<rect x="1" y="1" width="1198" height="2392" rx="14" fill="#0d1117" stroke="#30363d"/>
<rect x="1" y="1" width="1198" height="44" rx="14" fill="#161b22"/>
<rect x="1" y="30" width="1198" height="14" fill="#161b22"/>
<circle cx="24" cy="22" r="6" fill="#ff5f57"/>
<circle cx="44" cy="22" r="6" fill="#febc2e"/>
<circle cx="64" cy="22" r="6" fill="#28c840"/>
<text x="92" y="27" fill="#8b949e" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace">terminal evidence</text>
<text x="24" y="68" fill="#c9d1d9" font-size="15" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">$ H=src/adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/hibernate
S=src/adapt</tspan><tspan x="24" dy="22">er/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/springdata
echo &#x27;# 검사기가 무엇</tspan><tspan x="24" dy="22">을 하는지, 그리고 무엇을 위한 것인지&#x27;
grep -n &#x27;&#x27; $H/NamedStatementInspector.java | sed -n &#x27;7,18p&#x27;
grep -n &#x27;&#x27; $H/NamedSta</tspan><tspan x="24" dy="22">tementInspector.java | sed -n &#x27;20,43p&#x27;
echo &#x27;# 이름 형식이 이미 * 와 / 를 막는다&#x27;
grep -n &#x27;Pattern.compile&#x27; src/adapte</tspan><tspan x="24" dy="22">r/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/api/query/QueryName.java
echo
echo</tspan><tspan x="24" dy="22"> &#x27;# 하이버네이트가 이 구현을 설치하는 경로 — 저장소 루트, 확장자 무제한&#x27;
echo -n &#x27;# statement_inspector 설정 키: &#x27;
gr</tspan><tspan x="24" dy="22">ep -rn --binary-files=without-match &#x27;statement_inspector\|statementInspector\|STATEMENT_INSPECTOR&#x27; --exclude-dir=build -</tspan><tspan x="24" dy="22">-exclude-dir=.git . | wc -l
echo -n &#x27;# HibernatePropertiesCustomizer / SessionFactoryBuilder / ServiceRegistry / Integ</tspan><tspan x="24" dy="22">rator: &#x27;
grep -rln &#x27;HibernatePropertiesCustomizer\|SessionFactoryBuilder\|StandardServiceRegistry\|org.hibernate.integra</tspan><tspan x="24" dy="22">tor&#x27; --exclude-dir=build --exclude-dir=.git . | wc -l
echo -n &#x27;# persistence.xml: &#x27;
find . -name persistence.xml -not </tspan><tspan x="24" dy="22">-path &#x27;*/build/*&#x27; | wc -l
echo -n &#x27;# src 리소스와 자동설정 등록 파일의 FQCN: &#x27;
grep -rln &#x27;NamedStatementInspector&#x27; --e</tspan><tspan x="24" dy="22">xclude-dir=build src/*/src/main/resources src/*/*/*/src/main/resources 2&gt;/dev/null | wc -l
echo -n &#x27;# 그 클래스의 단위</tspan><tspan x="24" dy="22"> 테스트: &#x27;
find src -name &#x27;NamedStatementInspector*Test.java&#x27; -o -name &#x27;QueryNameContext*Test.java&#x27; | grep -vc build
ec</tspan><tspan x="24" dy="22">ho
echo &#x27;# 이름을 컨텍스트에 넣는 세 곳&#x27;
grep -rn &#x27;QueryNameContext\.with(&#x27; --include=*.java --exclude-dir=build src | g</tspan><tspan x="24" dy="22">rep &#x27;/main/&#x27; | sed &#x27;s|^src/||&#x27;
echo -n &#x27;# 그 컨텍스트를 읽는 곳: &#x27;
grep -rn &#x27;QueryNameContext\.current()&#x27; --include=*.</tspan><tspan x="24" dy="22">java --exclude-dir=build src | wc -l
echo
echo &#x27;# 이름을 SQL 로 옮기는 두 번째 경로&#x27;
grep -rn &#x27;org.hibernate.comment&#x27; -</tspan><tspan x="24" dy="22">-include=*.java --exclude-dir=build src | grep &#x27;/main/&#x27; | sed &#x27;s|^src/||&#x27;
grep -n &#x27;setHint(COMMENT_HINT&#x27; $S/JpaRepositor</tspan><tspan x="24" dy="22">yFragmentSupport.java src/adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/que</tspan><tspan x="24" dy="22">rydsl/QuerydslJpaSupport.java | sed &#x27;s|.*/||&#x27;
echo -n &#x27;# 그 힌트가 SQL 로 나오게 하는 use_sql_comments 를 켜는 곳: &#x27;
g</tspan><tspan x="24" dy="22">rep -rn --binary-files=without-match &#x27;use_sql_comments\|useSqlComments&#x27; --exclude-dir=build --exclude-dir=.git . | wc -l</tspan><tspan x="24" dy="22">
echo
echo &#x27;# 이름을 넣는 세 클래스를 누가 쓰는가&#x27;
for C in JpaStreamExecutor JpaKeysetQuerySupport JpaRepositoryFragme</tspan><tspan x="24" dy="22">ntSupport; do
echo -n &quot;# $C 그 타입을 쓰는 파일 전부: &quot;
grep -rlnw &quot;$C&quot; --include=*.java --exclude-dir=build src </tspan><tspan x="24" dy="22">| sed &#x27;s|.*/||&#x27; | tr &#x27;\n&#x27; &#x27; &#x27;; echo
echo -n &quot;# 상속(전체): &quot;
grep -rn &quot;extends $C&quot; --include=*.java --e</tspan><tspan x="24" dy="22">xclude-dir=build src | sed &#x27;s|.*/||&#x27; | tr &#x27;\n&#x27; &#x27; &#x27;; echo
done</tspan></text>
<text x="24" y="596" fill="#8b949e" font-size="13" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">cwd: /shared/codebase/clean-architecture-backend-template</tspan></text>
<text x="24" y="618" fill="#8b949e" font-size="13" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">time: 2026-09-02T04:10:31+00:00 · exit 0</tspan></text>
<line x1="24" y1="632" x2="1176" y2="632" stroke="#30363d"/>
<text x="24" y="672" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 검사기가 무엇을 하는지, 그리고 무엇을 위한 것인지</tspan></text>
<text x="24" y="694" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">7:/**</tspan></text>
<text x="24" y="716" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">8: * Prefixes each statement with the registered query name that issued it (design §37).</tspan></text>
<text x="24" y="738" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">9: *</tspan></text>
<text x="24" y="760" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">10: * &lt;p&gt;The comment travels with the SQL into {@code pg_stat_activity}, {@code auto_explain} output,</tspan></text>
<text x="24" y="782" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">11: * and the slow-query log, which is the only place a DBA can connect a statement back to the use</tspan></text>
<text x="24" y="804" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">12: * case that produced it. Without it, &quot;which endpoint issues this query&quot; is answered by grepping the</tspan></text>
<text x="24" y="826" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">13: * codebase for fragments of SQL.</tspan></text>
<text x="24" y="848" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">14: *</tspan></text>
<text x="24" y="870" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">15: * &lt;p&gt;Only the registered name is emitted — never a parameter value, an id, or anything from the</tspan></text>
<text x="24" y="892" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">16: * request. The name is already validated as bounded and low-cardinality, and this class</tspan></text>
<text x="24" y="914" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">17: * additionally rejects the comment terminator so a name can never close the comment and continue as</tspan></text>
<text x="24" y="936" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">18: * SQL.</tspan></text>
<text x="24" y="958" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">20:public final class NamedStatementInspector implements StatementInspector {</tspan></text>
<text x="24" y="980" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">21:</tspan></text>
<text x="24" y="1002" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">22: private static final long serialVersionUID = 1L;</tspan></text>
<text x="24" y="1024" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">23:</tspan></text>
<text x="24" y="1046" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">24: /**</tspan></text>
<text x="24" y="1068" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">25: * The comment terminator; a name containing it would end the comment and start statement text.</tspan></text>
<text x="24" y="1090" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">26: */</tspan></text>
<text x="24" y="1112" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">27: private static final String COMMENT_TERMINATOR = &quot;*/&quot;;</tspan></text>
<text x="24" y="1134" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">28:</tspan></text>
<text x="24" y="1156" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">29: @Override</tspan></text>
<text x="24" y="1178" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">30: public String inspect(String sql) {</tspan></text>
<text x="24" y="1200" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">31: if (sql == null) {</tspan></text>
<text x="24" y="1222" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">32: return null;</tspan></text>
<text x="24" y="1244" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">33: }</tspan></text>
<text x="24" y="1266" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">34: Optional&lt;QueryName&gt; queryName = QueryNameContext.current();</tspan></text>
<text x="24" y="1288" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">35: if (queryName.isEmpty()) {</tspan></text>
<text x="24" y="1310" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">36: return sql;</tspan></text>
<text x="24" y="1332" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">37: }</tspan></text>
<text x="24" y="1354" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">38: String value = queryName.get().value();</tspan></text>
<text x="24" y="1376" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">39: if (value.contains(COMMENT_TERMINATOR)) {</tspan></text>
<text x="24" y="1398" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">40: return sql;</tspan></text>
<text x="24" y="1420" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">41: }</tspan></text>
<text x="24" y="1442" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">42: return &quot;/* &quot; + value + &quot; */ &quot; + sql;</tspan></text>
<text x="24" y="1464" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">43: }</tspan></text>
<text x="24" y="1486" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 이름 형식이 이미 * 와 / 를 막는다</tspan></text>
<text x="24" y="1508" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">16: private static final Pattern FORMAT = Pattern.compile(&quot;[a-z][a-z0-9.-]{2,95}&quot;);</tspan></text>
<text x="24" y="1530" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="1552" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 하이버네이트가 이 구현을 설치하는 경로 — 저장소 루트, 확장자 무제한</tspan></text>
<text x="24" y="1574" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># statement_inspector 설정 키: 0</tspan></text>
<text x="24" y="1596" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># HibernatePropertiesCustomizer / SessionFactoryBuilder / ServiceRegistry / Integrator: 0</tspan></text>
<text x="24" y="1618" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># persistence.xml: 0</tspan></text>
<text x="24" y="1640" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># src 리소스와 자동설정 등록 파일의 FQCN: 0</tspan></text>
<text x="24" y="1662" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 그 클래스의 단위 테스트: 0</tspan></text>
<text x="24" y="1684" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="1706" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 이름을 컨텍스트에 넣는 세 곳</tspan></text>
<text x="24" y="1728" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/springdata/JpaStreamExecutor.java:63:</tspan><tspan x="24" dy="22"> return QueryNameContext.with(</tspan></text>
<text x="24" y="1772" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/springdata/JpaKeysetQuerySupport.java</tspan><tspan x="24" dy="22">:49: return QueryNameContext.with(</tspan></text>
<text x="24" y="1816" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/springdata/JpaRepositoryFragmentSuppo</tspan><tspan x="24" dy="22">rt.java:72: return QueryNameContext.with(name, work);</tspan></text>
<text x="24" y="1860" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 그 컨텍스트를 읽는 곳: 1</tspan></text>
<text x="24" y="1882" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="1904" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 이름을 SQL 로 옮기는 두 번째 경로</tspan></text>
<text x="24" y="1926" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/api/query/QueryName.java:8: * &lt;p&gt;The </tspan><tspan x="24" dy="22">name is what appears in metrics, traces, and the {@code org.hibernate.comment} hint, so it</tspan></text>
<text x="24" y="1970" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/springdata/JpaRepositoryFragmentSuppo</tspan><tspan x="24" dy="22">rt.java:27: private static final String COMMENT_HINT = &quot;org.hibernate.comment&quot;;</tspan></text>
<text x="24" y="2014" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">adapter/outbound/persistence-jpa/src/main/java/dev/caskeleton/adapter/outbound/persistence/querydsl/QuerydslJpaSupport.java:24: </tspan><tspan x="24" dy="22"> private static final String COMMENT_HINT = &quot;org.hibernate.comment&quot;;</tspan></text>
<text x="24" y="2058" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">JpaRepositoryFragmentSupport.java:45: return entityManager.createQuery(jpql, resultType).setHint(COMMENT_HINT, name.value());</tspan></text>
<text x="24" y="2080" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">JpaRepositoryFragmentSupport.java:62: return entityManager.createNativeQuery(sql).setHint(COMMENT_HINT, name.value());</tspan></text>
<text x="24" y="2102" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">QuerydslJpaSupport.java:48: return query.offset(page.offset()).limit(page.size()).setHint(COMMENT_HINT, name.value());</tspan></text>
<text x="24" y="2124" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 그 힌트가 SQL 로 나오게 하는 use_sql_comments 를 켜는 곳: 0</tspan></text>
<text x="24" y="2146" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="2168" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 이름을 넣는 세 클래스를 누가 쓰는가</tspan></text>
<text x="24" y="2190" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># JpaStreamExecutor 그 타입을 쓰는 파일 전부: JpaStreamExecutorTest.java JpaStreamExecutor.java </tspan></text>
<text x="24" y="2212" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 상속(전체): </tspan></text>
<text x="24" y="2234" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># JpaKeysetQuerySupport 그 타입을 쓰는 파일 전부: JpaKeysetQuerySupportTest.java JpaKeysetQuerySupport.java </tspan></text>
<text x="24" y="2256" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 상속(전체): </tspan></text>
<text x="24" y="2278" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># JpaRepositoryFragmentSupport 그 타입을 쓰는 파일 전부: JpaRepositoryFragmentSupportTest.java JpaRepositoryFragmentSupport.j</tspan><tspan x="24" dy="22">ava </tspan></text>
<text x="24" y="2322" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 상속(전체): JpaRepositoryFragmentSupportTest.java:74: private static final class Fragment extends JpaRepositoryF</tspan><tspan x="24" dy="22">ragmentSupport { </tspan></text>
</svg>