Skip to content

fix(codegen): JPA 트랜잭션 마법사의 Java Config 템플릿이 입력받은 DataSource Name 을 버리던 문제 수정 - #153

Merged
eGovFrameSupport merged 1 commit into
eGovFramework:mainfrom
wantaekchoi:fix/jpa-vm-datasource-name
Sep 18, 2026
Merged

eGovFrameSupport merged 1 commit into
eGovFramework:mainfrom
wantaekchoi:fix/jpa-vm-datasource-name

Conversation

@wantaekchoi

@wantaekchoi wantaekchoi commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

수정 사유 Reason for modification

  • 버그수정 Bug fixes
  • 기능개선 Enhancements
  • 기능추가 Adding features
  • 기타 Others

수정된 소스 내용 Modified source

New JPA Transaction 마법사는 DataSource Name 을 필수로 받습니다. 이 필드에는 radio 속성이 없어서 Configuration Type 을 XML 로 고르든 Java 로 고르든 입력받습니다. 같은 파일 :18~:21 의 txtPath·txtFileName 이 radio="XML", txtConfigPackage·txtClassName 이 radio="Java" 로 경로를 한정하는 것과 다릅니다.

egovframework.dev.imp.codegen.template.templates/eGovFrameTemplates/transaction/jpa.xml:27:				<textfield name="txtDataSourceName" label="DataSource Name: "

그런데 두 출력 템플릿의 처리가 갈립니다. XML 경로는 이 값을 쓰지만 Java 경로는 파일 전체 115줄에서 한 번도 참조하지 않습니다 (txtDataSourceName 0건, Qualifier 0건). 사용자가 필수로 입력한 값이 Java Config 를 고르는 순간 버려집니다.

egovframework.dev.imp.codegen.template.templates/eGovFrameTemplates/transaction/jpa.vm:53:		<property name="dataSource" ref="${txtDataSourceName}" />

같은 템플릿 트리의 다른 Java Config 템플릿은 @Qualifier 로 지정 빈을 주입합니다. 특히 transaction 마법사는 jpa 마법사와 같은 XML/Java 쌍 구조인데, 그쪽 Java 템플릿은 이 값을 살립니다.

egovframework.dev.imp.codegen.template.templates/eGovFrameTemplates/transaction/transaction-java.vm:37:    public DataSourceTransactionManager txManager(@Qualifier("${txtDatasourceName}") DataSource dataSource) {
egovframework.dev.imp.codegen.template.templates/eGovFrameTemplates/idGeneration/sequenceId-java.vm:14:    public EgovSequenceIdGnrServiceImpl ${txtIdServiceName}(@Qualifier("${txtDatasourceName}") DataSource dataSource) {
egovframework.dev.imp.codegen.template.templates/eGovFrameTemplates/idGeneration/tableId-java.vm:15:    public EgovTableIdGnrServiceImpl ${txtIdServiceName}(@Qualifier("${txtDatasourceName}") DataSource dataSource#if(${chkStrategy}),

@Qualifier 가 없으면 스프링은 타입으로 후보를 찾고 후보가 여럿이면 파라미터명으로 폴백합니다. 파라미터명이 dataSource 라서 DataSource 빈이 둘 이상이고 그중 하나의 이름이 dataSource 이면 사용자가 마법사에서 다른 이름을 지정했더라도 예외 없이 dataSource 가 주입됩니다. dataSource 라는 이름의 빈이 없으면 NoUniqueBeanDefinitionException 이 납니다. 빈이 하나뿐이면 입력값만 조용히 무시됩니다.

AS-IS

    public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {

    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory, DataSource dataSource) {

TO-BE

    public LocalContainerEntityManagerFactoryBean entityManagerFactory(@Qualifier("${txtDataSourceName}") DataSource dataSource) {

    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory, @Qualifier("${txtDataSourceName}") DataSource dataSource) {

변수명 표기가 마법사마다 다릅니다. 형제 셋의 XML 은 ${txtDatasourceName}(소문자 s)를 선언하지만 jpa.xml 은 ${txtDataSourceName}(대문자 S)입니다. 형제 표기를 그대로 가져오면 미정의 참조가 되어 생성물에 @Qualifier("${txtDatasourceName}") 가 리터럴로 박히므로 jpa.vm 과 같은 표기를 썼습니다. 실제로 넣어 본 결과는 아래 검증에 붙였습니다.

jpa.xml 에는 radio 없는 필수 필드가 하나 더 있습니다(txtPointCutName, :87). 이 값도 jpa-java.vm 이 쓰지 않지만 이번에는 건드리지 않았습니다. 형제 transaction-java.vm 도 이 값을 쓰지 않습니다. XML 에서 이 이름은 같은 파일 안의 aop:pointcut id= 와 aop:advisor pointcut-ref= 를 잇는 내부 식별자인데, Java Config 는 포인트컷 객체를 직접 넘기므로 이름이 가리킬 대상이 없습니다. DataSource Name 은 다른 마법사가 만든 외부 빈을 가리키는 참조라 사정이 다릅니다.

egovframework.dev.imp.codegen.template.templates/eGovFrameTemplates/transaction/jpa.vm:41:		<aop:pointcut id="${txtPointCutName}" expression="${txtPointCutExpression}" />
egovframework.dev.imp.codegen.template.templates/eGovFrameTemplates/transaction/jpa.vm:42:		<aop:advisor advice-ref="${txtAdviceName}" pointcut-ref="${txtPointCutName}" />
egovframework.dev.imp.codegen.template.templates/eGovFrameTemplates/transaction/jpa-java.vm:107:		return new DefaultPointcutAdvisor(pointcut, txAdvice(txManager));

변경한 파일은 transaction/jpa-java.vm 하나이고 import 1줄과 주입 지점 2줄입니다. 마법사에서 Configuration Type 을 Java 로 고를 때 생성되는 .java 만 달라지고 XML 경로는 그대로입니다. egovframework.dev.imp.templates 아래 이 파일의 사본이 바이트 단위로 같으니, 함께 맞추는 편이 낫다면 알려주시면 반영하겠습니다.

JUnit 테스트 JUnit tests

  • JUnit 테스트 JUnit tests
  • 수동 테스트 Manual testing

저장소에 들어 있는 벨로시티(egovframework.dev.imp.templates/lib/velocity-1.6.2.jar)로 operation/TemplateCodeGen.java:37 과 같은 Map → VelocityContext → merge 흐름을 태워 DataSource Name 에 기본값이 아닌 egovDataSource 를 넣고 두 경로를 같은 입력으로 렌더했습니다.

수정 전

transaction/jpa.vm: 생성물에서 "egovDataSource" 참조 1건
    22:		<property name="dataSource" ref="egovDataSource" />
transaction/jpa-java.vm: 생성물에서 "egovDataSource" 참조 0건
    FAIL: required 입력값 "egovDataSource" 이 생성 코드 어디에도 없다
NG

수정 후

transaction/jpa.vm: 생성물에서 "egovDataSource" 참조 1건
    22:		<property name="dataSource" ref="egovDataSource" />
transaction/jpa-java.vm: 생성물에서 "egovDataSource" 참조 2건
    39:    public LocalContainerEntityManagerFactoryBean entityManagerFactory(@Qualifier("egovDataSource") DataSource dataSource) {
    60:    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory, @Qualifier("egovDataSource") DataSource dataSource) {
OK: 두 경로 모두 입력값을 반영한다

형제 표기(소문자 s)를 그대로 썼다면 이렇게 됩니다.

[...]
transaction/jpa-java.vm: 생성물에서 "egovDataSource" 참조 0건
    FAIL: required 입력값 "egovDataSource" 이 생성 코드 어디에도 없다
    FAIL: 미해석 벨로시티 참조 2건이 생성물에 그대로 남았다
      39:    public LocalContainerEntityManagerFactoryBean entityManagerFactory(@Qualifier("${txtDatasourceName}") DataSource dataSource) {
      60:    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory, @Qualifier("${txtDatasourceName}") DataSource dataSource) {
NG

XML 경로의 출력은 세 경우 모두 같습니다.

egovframework.dev.imp.templates 의 TemplateCodeGenTest·CrudCodeGenTest 는 그 모듈 안에 따로 있는 사본에서 XML .vm 만 골든파일로 대조하므로 이번 변경과 겹치지 않습니다.

테스트 브라우저 Test Browser

  • Chrome
  • Firefox
  • Edge
  • Safari
  • Opera
  • Internet Explorer
  • 기타 Others

이클립스 플러그인이라 브라우저로 확인할 대상이 아닙니다.

테스트 스크린샷 또는 캡처 영상 Test screenshots or captured video

화면 변경이 아니라 생성되는 .java 의 내용 변경입니다. 달라지는 줄은 위 렌더 결과의 주입 지점 두 줄과 import 한 줄입니다.

…리던 문제 수정

transaction/jpa.xml 은 "DataSource Name:" 을 required 로 받고 radio 속성이 없어
XML·Java 두 출력 경로 모두에서 입력된다. XML 경로의 jpa.vm:53 은 이 값을
<property name="dataSource" ref="${txtDataSourceName}" /> 로 쓰지만 Java 경로의
jpa-java.vm 은 어디에서도 참조하지 않고 DataSource 를 타입으로만 받았다.

@qualifier 가 없으면 스프링이 타입으로 후보를 찾다가 파라미터명 dataSource 로 폴백한다.
DataSource 빈이 둘 이상이고 그중 하나의 이름이 dataSource 이면, 사용자가 마법사에서
다른 이름을 지정했더라도 예외 없이 dataSource 가 주입된다.

같은 폴더의 transaction-java.vm:37·sequenceId-java.vm:14·tableId-java.vm:15 은
@qualifier 로 지정 빈을 주입한다. 다만 변수명 표기가 달라서, 형제들이 쓰는
txtDatasourceName 이 아니라 jpa.xml·jpa.vm 과 같은 txtDataSourceName 을 썼다.
@eGovFrameSupport
eGovFrameSupport merged commit 992badd into eGovFramework:main Sep 18, 2026
1 check passed
@wantaekchoi
wantaekchoi deleted the fix/jpa-vm-datasource-name branch September 18, 2026 04:54
swanpark8538 added a commit that referenced this pull request Sep 18, 2026
egovframework.dev.imp.templates 의 eGovFrameTemplates 사본은 플러그인 원본과 57개
파일이 어긋나 있어 #153·#154 와 그 후속 jpa.xml 수정도 반영되지 않았다. ant/build.xml 과
같은 규칙(사본 삭제 후 복사, model 전체와 NamingUtils)으로 사본을 다시 채운다. Java 5개는
저작권 헤더만 바뀐다.

사본이 바뀌면 TemplateCodeGenTest·CrudCodeGenTest 의 골든파일이 옛 출력이라 28건이
깨지므로 같은 입력으로 다시 생성한 결과로 교체한다. 템플릿에 새로 생긴 변수와 jta·jpa 가
새로 선언한 체크박스는 마법사 기본값을 값 파일에 추가해 미해석 참조가 남지 않게 했다.

플러그인에서 사라진 템플릿을 가리키던 테스트 5건은 9d3f8d5 와 같은 기준으로 정리한다.
jeus.vm → jndiDatasource.vm, transaction/datasource.vm → transaction.vm,
dailyRollingFile.vm → timeBasedRollingFile.vm 으로 마법사가 실제로 쓰는 템플릿에 맞추고,
대응 템플릿이 없는 egovDb·egovJdbc 어펜더 테스트는 골든·값 파일과 함께 제거한다.
대소문자만 다르던 DailyRollingFile.properties·jndiDataSource.xm 도 테스트가 참조하는
이름으로 맞춘다.

Refs: #153, #154
@swanpark8538

Copy link
Copy Markdown
Collaborator

Velocity 템플릿 오류 수정 감사합니다.

전자정부 표준프레임워크에 기여해 주셔서 감사합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants