Files
llm-wiki/raw/company-tech-blogs/hexagonal-reflectoring-transactional-placement.md
T

8.5 KiB

title, source_type, url, archive_url, status, confidence, tags, related_branches, related_projects, created, last_reviewed
title source_type url archive_url status confidence tags related_branches related_projects created last_reviewed
Hexagonal Architecture with Java and Spring — Reflectoring (Tom Hombergs) company-tech-blog https://reflectoring.io/spring-hexagonal/ raw medium
ca-transaction-boundary
hexagonal
at-transactional
application-service
feature-application-port-usecase-contract
feature-transaction-concurrency-contract
ca-skeleton-operational-contract
2026-05-22 2026-05-27

Hexagonal Architecture with Java and Spring — Tom Hombergs / Reflectoring

Layer: raw/company-tech-blogs/ — 외부 엔지니어 블로그의 원문 발췌·출처 기록. Tom Hombergs (저서 Get Your Hands Dirty on Clean Architecture 저자) 의 reflectoring.io 레퍼런스 글로, 헥사고날 사실상 표준 패턴에서 @Transactional 위치를 보여주는 baseline 사례. 검증된 요약은 /ingestwiki/concepts/에 별도 작성. 원본은 raw에 영구 보관.

Parent / 활용 branch (필수)

Branch 이 자료가 정당화하는 결정
raw/branch-notes/feature-application-port-usecase-contract ca-tmpl 이 의식적으로 거부한 baseline 패턴 (@Transactional 을 use case 구현체에 직접 부착) 의 사례 근거
raw/branch-notes/feature-transaction-concurrency-contract Topic 2 — Transaction Boundary 대안 비교에서 "대안 1: @Transactional direct" 의 reference 구현체
raw/project-notes/ca-skeleton-operational-contract §14. Transaction / Concurrency Contract — ca-tmpl 의 TransactionPort 결정에 대한 비교군 baseline

컨텍스트 / 왜 저장했는지

ca-tmpl 결정의 비교군: 헥사고날 아키텍처 사실상 표준 reference 에서 @Transactional 을 application service(use case) 에 직접 부착하는 사례. 즉 ca-tmpl 이 의식적으로 거부한 baseline 패턴을 옹호하는 참조.

출처 / Source

  • 원본 URL: https://reflectoring.io/spring-hexagonal/
  • 아카이브 URL: (미수집)
  • 저자 / 조직: Tom Hombergs (저서 Get Your Hands Dirty on Clean Architecture 저자) / reflectoring.io
  • 발행일: continuously updated reference article
  • 마지막 확인일: 2026-05-27

핵심 인용 / Key quotes (verbatim)

[§Building a Use Case and Output Ports] "@RequiredArgsConstructor @Component @Transactional public class SendMoneyService implements SendMoneyUseCase {"

[§Input and Output Ports] "An input port is a simple interface that can be called by outward components and that is implemented by a use case."

[§Input and Output Ports] "An output port is again a simple interface that can be called by our use cases if they need something from the outside."

[§Input and Output Ports] "A use case in this sense is a class that handles everything around, well, a certain use case."

[§Building a Web Adapter] "If you're familiar with Spring MVC, you'll find that this is a pretty boring web controller."

Claims Extracted / 추출된 주장

Claim ID Claim (이 자료가 직접 말하는 것) Evidence quote Strength Applies to Does not prove
HEX-REFL-C1 reflectoring 레퍼런스 예제에서 SendMoneyService (use case 구현체) 가 @Component + @Transactional 을 직접 부착 [§Building a Use Case and Output Ports] "@RequiredArgsConstructor @Component @Transactional public class SendMoneyService implements SendMoneyUseCase {" engineering-blog Spring + 헥사고날 baseline 패턴 이 배치가 모든 헥사고날 구현의 모범이라는 뜻은 아님 — 저자도 명시적 정당화는 책으로 미룸
HEX-REFL-C2 input port 는 외부 컴포넌트가 호출하는 단순 인터페이스이고 use case 가 구현한다 [§Input and Output Ports] "An input port is a simple interface that can be called by outward components and that is implemented by a use case." engineering-blog 헥사고날의 port 정의 (저자 관점) port 의 granularity (큰 port 1개 vs use case 당 port 1개) 는 본 인용 범위 밖
HEX-REFL-C3 output port 는 use case 가 외부에 무언가 필요할 때 호출하는 단순 인터페이스 [§Input and Output Ports] "An output port is again a simple interface that can be called by our use cases if they need something from the outside." engineering-blog 헥사고날의 driven-adapter 통신 방향 정의 output port 가 트랜잭션 제어를 담당해야 한다는 뜻은 아님 — 본 글은 그 결정을 다루지 않음
HEX-REFL-C4 use case 는 "특정 use case 주변의 모든 것" 을 처리하는 클래스이다 [§Input and Output Ports] "A use case in this sense is a class that handles everything around, well, a certain use case." engineering-blog 헥사고날 use case 의 책임 정의 "모든 것" 의 정확한 경계 (트랜잭션, 인증, 검증 포함 여부) 는 본 인용에 명시 없음
HEX-REFL-C5 본 글은 transaction boundary 정책 / @Transactional 부착 위치에 대한 명시적 권고 또는 정당화를 하지 않는다 (예제로만 보여줌) (부재 자체가 claim — WebFetch 재확인: "No explicit recommendation provided"; 본 인용 내에 transaction boundary 권고 문장 없음) needs-confirmation 본 글의 표현 범위 저자가 다른 매체 (책) 에서 다룬 정당화는 본 인용으로 증명 안 됨

Usage Boundaries / 적용 경계

  • 이 자료가 직접 증명하는 것:
    • HEX-REFL-C1: reflectoring 의 canonical 예제 코드 그대로의 @Transactional 위치 (use case 구현체 클래스)
    • HEX-REFL-C2 ~ C4: 저자의 port 와 use case 정의 (Hombergs 관점)
    • HEX-REFL-C5: 본 글이 transaction boundary 결정의 정당화를 직접 제공하지 않는다는 사실
  • 이 자료가 증명하지 않는 것:
    • 이 패턴이 헥사고날 커뮤니티의 "공식 best practice" 라는 주장 (company-tech-blog 수준이 아니라 engineering-blog 수준 — 개인 블로그)
    • 이 패턴이 prod 환경에서 검증되었다는 주장 (저자의 책/블로그 reference 예제일 뿐)
    • "framework-free 원칙 위반" 이라는 비판 — 본 글이 직접 그 표현을 쓰지 않음
  • 내 프로젝트에 적용하려면 추가 확인이 필요한 것:
    • ca-tmpl 의 TransactionPort 가 reflectoring 패턴 대비 갖는 dependency rule 차이 (Spring annotation import 유무) 의 실제 측정
    • 저자의 책 Get Your Hands Dirty on Clean Architecture 에서 동일 결정의 정당화 본문 확인

메모 / Notes (내 프로젝트 해석)

본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석.

  • 이 패턴이 한국·해외 헥사고날 튜토리얼의 90% 이상에서 그대로 반복됨. ca-tmpl 의 결정은 이 디폴트에 대한 의식적 일탈로 봐야 함.
  • 적용 시나리오: 빠른 프로토타이핑, 팀이 Spring 이외 stack 으로 옮길 계획이 없는 경우.
  • 장점:
    • 코드 적음. 진입 장벽 최저.
    • 헥사고날 커뮤니티 표준이라 코드 리뷰/온보딩 용이.
  • 단점:
    • application 레이어가 org.springframework.transaction.annotation.Transactional 을 import → 책에서 강조하는 "domain-application 은 framework-free" 원칙과 실제 코드가 어긋남. (저자도 명시적 정당화 없음 — HEX-REFL-C5 참조.)
    • 트랜잭션 boundary 테스트가 Spring context 를 요구.
  • ca-tmpl(TransactionPort) 와의 차이: ca-tmpl 은 위 모순을 닫기 위해 TransactionPort + TransactionalUseCaseRunner 로 한 단계 더 abstraction 을 둠. Reflectoring 패턴은 그 모순을 실용주의로 수용.
  • testability 영향: 낮음.
  • code 복잡도 영향: 낮음 (하지만 dependency-rule cost 는 숨겨져 있음).