1. 문제 발생
- 상황:
- SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(jdbcTemplate) 후에 simpleJdbcInsert.executeAndReturnKey(new MapSqlParameterSource(parameters))를 실행하여 테이블에 parameters에 들어있는 값들을 삽입하였습니다.
- 물론, table을 생성할 때 default 예약어로 "createAt"이라는 속성값에 default current_timestamp를 설정해두었기에, 위 parameters에는 "createAt"에 대한 값을 넣지 않았습니다.
- 결과:
- executeAndReturnKey 메소드로 받아온 기본키 값을 활용해 createAt을 찾고자, "select createAt from 테이블 where id = ? "명령을 쿼리로 작성하였습니다.
- 이후 JdbcTemplate.queryForMap 메소드를 통하여 실행한 결과값인 Map<String, Object> 값에 get("createAt")을 적용해 출력해보았는데 null이 반환됨을 알 수 있었습니다.
2. 원인 추론
- 단순히 default 예약어가 작동하지 않는다고 예상하였습니다.
3. 해결 방안
(1) 값을 직접 넣어주기
simpleJdbcInsert.executeAndReturnKey(new MapSqlParameterSource(parameters))에 들어가는 parameters에 직접 key-value를 넣어줌으로써 해결하는 방법 밖에 없습니다.
- 원인 정리
테이블에 col1, col2라는 속성이 있고, col1 속성에 default 예약어를 설정되어 있다고 가정하겠습니다.
이후, simpleJdbcInsert.executeAndReturnKey(new MapSqlParameterSource(parameters))에 인수로 들어가는 parameters에 (col2, val2)만 넣었다면? (col1은 default 예약어가 있으니 제외)
→ insert into mytable (col1, col2) values (val1, val2); (X)
→ insert into mytable values (val1, val2); (O)
무슨 차이인지 이해하셨나요?
executeAndReturnKey 메소드는 insert할 때 컬럼명을 명시하지 않았기 때문에, default 예약어를 사용할 수 없게 됩니다.
즉, simpleJdbcInsert.executeAndReturnKey 사용 시, 테이블에는 default 값이 적용이 되지 않습니다.
(2) SimpleJdbcInsert.usingColumns(String... columnNames)
simpleJdbcInsert.usingColumns(String... columnNames) 사용해 명시적으로 사용할 컬럼을 지정할 수 있다.
즉, usingColumns("name", "title", "content") 과 같이 넣어주면, INSERT INTO 테이블(name, title, content) values(?,?,?);이 실행된다. 그 외 들어가지 않은 값들은 default 예약어가 적용된다. (default가 없으면 안됨)
4. 결과
- simpleJdbcInsert.executeAndReturnKey 메소드를 사용할 때, 비어있는 컬럼에 대해 default 값이 적용되지 않는다. (null을 임의로 채우기 때문)
- simpleJdbcInsert.usingColumns(String... columnNames) 메소드로 INSERT 문에 명시적으로 컬럼을 제한할 수 있다.
'트러블슈팅' 카테고리의 다른 글
[트러블슈팅] langchain-google-genai 사용 중에 protoc >= 3.19.0 오류 (0) | 2025.06.12 |
---|---|
[트러블슈팅] 'mysql'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는 배치 파일이 아닙니다. 해결 (0) | 2025.05.21 |