본문으로 건너뛰기

라우팅 데이터 소스의 세 가지 근본 원인

증상

읽기/쓰기 데이터 소스 라우팅 변경 후 백엔드 시작이 곧 실패하며, 종종 jpaSharedEM_entityManagerFactory unresolved와 같은 잘못된 다운스트림 메시지 또는 다른 엔터티 관리자 연결 오류로 인해 실패합니다.

이 실패 클래스는 현재 백엔드 소스에 직접 문서화되어 있습니다.

  • lumie-backend/app/src/main/java/com/lumie/app/config/RoutingDataSourceConfig.java
  • lumie-backend/app/src/main/resources/application.yaml
  • lumie-backend/app/src/test/java/com/lumie/app/config/RoutingDataSourceIntegrationTest.java

대신 Flyway CREATE INDEX CONCURRENTLY에서 시작이 중단되면 Flyway Monolith Migration Traps를 사용하세요.

실제 근본 원인

2026-05-20 사건 노트는 모두 동일한 JPA Bean 오류로 가장할 수 있는 세 가지 업스트림 원인을 좁혔습니다.

  1. Hibernate 방언 자동 감지는 LazyConnectionDataSourceProxy에 대해 실행되며 엔터티 관리자 부팅 중에 실제 JDBC 메타데이터를 읽을 수 없습니다.
  2. AbstractRoutingDataSource는 내부적으로 생성되지만 afterPropertiesSet()를 수신하지 않으므로 첫 번째 JDBC 사용에서는 DataSource router not initialized가 발생합니다.
  3. Flyway는 원시 기본 데이터 소스 또는 전용 마이그레이션 데이터 소스 대신 지연 라우팅 프록시에서 데이터 소스를 파생시키려고 합니다.

진단

체결된 계약을 먼저 확인하세요.

  • application.yaml는 여전히 spring.jpa.database-platform: org.hibernate.dialect.PostgreSQLDialect를 고정해야 합니다.
  • RoutingDataSourceConfignew LazyConnectionDataSourceProxy(routing)를 반환하기 전에 routing.afterPropertiesSet()를 호출해야 합니다.
  • RoutingDataSourceConfig는 기본 URL과 spring.flyway.user/password에서 빌드된 전용 @FlywayDataSource를 계속 노출해야 합니다.

현재 구성 주석은 해당 행이 존재하는 이유를 명시적으로 기록하므로 이 오류가 다시 나타날 때 가장 먼저 정보를 얻을 수 있는 소스입니다.

수정

  • Hibernate가 게으른 프록시로부터 추론하려고 시도하는 경우 명시적인 PostgreSQL 언어를 복원합니다.
  • 라우터가 인라인되거나 리팩토링된 경우 afterPropertiesSet() 호출을 복원합니다.
  • 라우팅 프록시가 아닌 원시 마이그레이션 데이터 소스에 Flyway를 유지합니다.

이 영역에 대한 현재 회귀 가드는 빈 그래프를 실행하고 기본, 읽기 전용 및 비트랜잭션 라우팅을 확인하는 lumie-backend/app/src/test/java/com/lumie/app/config/RoutingDataSourceIntegrationTest.java입니다.

예방

  • 다운스트림 엔터티-관리자 연결 오류를 증상으로 처리합니다. Bean 이름을 변경하기 전에 데이터 소스 및 Hibernate 부팅 경로로 이동하세요.
  • 기본 데이터 소스가 지연될 때마다 방언을 명시적으로 고정합니다.
  • 데이터 소스 라우팅을 위한 하나의 집중적인 통합 테스트와 Flyway 관련 시작 실패에 대한 별도의 가이드를 유지합니다.

원본 사고 세부사항

2026년 5월 20일 원본 사고는 하나의 routing datasource startup failure처럼 보였던 문제 뒤에 실제 root cause가 세 개 있음을 확인했습니다. 이 문서의 목적은 마지막에 보이는 Spring exception만 고치고 upstream boot path를 남기지 않는 것입니다.

Root causeFailure shape
명시적인 Hibernate dialect 누락Hibernate가 lazy routing proxy를 통해 database를 추론하려 했습니다
afterPropertiesSet() 누락target datasource resolution이 초기화되기 전에 AbstractRoutingDataSource가 반환됐습니다
Flyway가 routing proxy를 통함migration startup이 raw migrator datasource 대신 잘못된 datasource abstraction을 사용했습니다

진단 순서가 중요합니다.

  1. 마지막 repository 또는 entity-manager 증상이 아니라 첫 datasource/Hibernate boot error에서 시작합니다.
  2. spring.jpa.database-platform이 명시되어 있는지 확인합니다.
  3. Routing datasource가 LazyConnectionDataSourceProxy로 감싸지기 전에 초기화되는지 확인합니다.
  4. Flyway가 primary connection property와 migrator credential로 만든 전용 @FlywayDataSource를 갖는지 확인합니다.

이 페이지에 이름이 적힌 integration test는 각 root cause가 다른 downstream bean failure로 다시 나타날 수 있기 때문에 존재합니다.