fix: primitive float 필드가 sqlTypes 표기 불일치로 JDBC 배치 쓰기에서 SQLException 이 나는 문제 수정 - #362
Open
wantaekchoi wants to merge 1 commit into
Open
fix: primitive float 필드가 sqlTypes 표기 불일치로 JDBC 배치 쓰기에서 SQLException 이 나는 문제 수정#362wantaekchoi wants to merge 1 commit into
wantaekchoi wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
수정 사유 Reason for modification
수정된 소스 내용 Modified source
EgovJdbcBatchItemWriter로 primitivefloat필드가 있는 VO 를 쓰면java.sql.SQLException이 납니다.sqlTypes 를 만드는 쪽은
Class.getSimpleName()을 씁니다. primitive 필드는"int"·"double"·"long"처럼 소문자 이름이 나오고, primitivefloat도"float"이 나옵니다.받는 쪽 분기는 이렇습니다.
primitive 를 받는 분기 여섯 개(
int·double·byte·short·boolean·long)는 모두 소문자 이름으로 비교하는데, 73줄만 wrapper 이름인"Float"로 비교합니다. 그래서 산출값"float"은 어느 분기에도 걸리지 않고 80줄의throw new SQLException()으로 떨어집니다. 메시지도 원인도 없는 예외라 로그만 보면 무엇이 문제인지 알 수 없습니다.죽은 경로가 아닙니다.
params를 설정한 정상 쓰기 흐름에서 산출과 소비가 한 메서드 안에 이어져 있고,getSqlTypeArray를 부르는 운영 코드는 이 한 곳뿐입니다.같은
EgovReflectionSupport안의 읽기 경로는 primitivefloat을 지원 대상으로 봅니다.AS-IS / TO-BE
} else if (sqlTypes[i].equals("long")) { ps.setLong(i + 1, (Long) reflector.invokeGettterMethod(item, params[i], methodMap)); - } else if (sqlTypes[i].equals("Float")) { + } else if (sqlTypes[i].equals("float") || sqlTypes[i].equals("Float")) { ps.setFloat(i + 1, (Float) reflector.invokeGettterMethod(item, params[i], methodMap));"Float"를"float"으로 바꾸지 않고"float"을 OR 로 더했습니다.setValues는 공개 메서드라 sqlTypes 를 직접 넘기는 호출자가 있을 수 있고, wrapperFloat필드는 수정 전에도 정상 동작하기 때문입니다. 치환하면 그 동작이 사라집니다.영향 범위
운영 코드는 이 한 줄입니다.
else if조건을 넓히기만 해서 기존에 매치되던 입력의 동작은 바뀌지 않고, 그동안SQLException으로 떨어지던"float"만ps.setFloat으로 들어갑니다. 나머지 분기와 산출부는 손대지 않았습니다.JUnit 테스트 JUnit tests
EgovMethodMapFloatSqlTypeTest를 3건 추가했습니다. sqlTypes 를 손으로 만들지 않고 실제getSqlTypeArray산출값을 그대로 소비부에 넘깁니다.primitiveFloatIsSetLikeSiblingPrimitives— 128·129줄에서assertEquals("double", sqlTypes[0])·assertEquals("float", sqlTypes[1])로 산출 표기를 먼저 확정하고, 형제double과 같은 자리에서ps.setFloat이 호출되는지 봅니다.wrapperFloatIsStillSet— 161줄assertEquals("Float", sqlTypes[0]). wrapper 경로가 그대로인지 확인합니다.primitiveFloatIsSetThroughWriter(181줄) —setValues를 직접 부르지 않고EgovJdbcBatchItemWriter.write()를 경유합니다.PreparedStatement대역은 형제 테스트EgovJdbcBatchWriteReflectionTest:155의FakePsHandler를 그대로 씁니다.수정한 한 줄을
sqlTypes[i].equals("Float")로 되돌리면 두 건이 실패합니다.두 건 모두 같은 자리에서 던져집니다.
수정본으로 되돌린 뒤 모듈 전체입니다.
테스트 브라우저 Test Browser
테스트 스크린샷 또는 캡처 영상 Test screenshots or captured video
화면이 없는 실행환경 모듈이라 첨부하지 않았습니다.