jdbc 탬플릿으로 findById로 조회 시 정상적으로 반환은 되지만 AUTO_INCREMENT 한 컬럼이 null인 상황입니다.
안녕하세요. 질문 제목에 관해 말씀드리겠습니다.
상황은 이러합니다.
member table에 jdbc 탬플릿으로 잘 저장하고 잘 조회하나 테스트하는 중으로 테이블은 아래와 같습니다.
CREATE TABLE member
(
member_id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(45),
login_id VARCHAR(45),
password VARCHAR(45),
email VARCHAR(45) UNIQUE
);
레포지토리는 아래와 같습니다.
package com.boaz.sketch2fashion.repository.member; import com.boaz.sketch2fashion.domain.Member; import com.boaz.sketch2fashion.repository.member.MemberRepository; import com.boaz.sketch2fashion.repository.member.dto.MemberSaveDTO; import com.boaz.sketch2fashion.repository.member.dto.MemberUpdateDTO; import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.support.GeneratedKeyHolder; import org.springframework.jdbc.support.KeyHolder; import org.springframework.stereotype.Repository; import javax.sql.DataSource; import java.security.Signature; import java.util.List; import java.util.Map; @Slf4j @Repository public class JdbcMemberRepository implements MemberRepository { private final NamedParameterJdbcTemplate template; public JdbcMemberRepository(DataSource dataSource) { this.template = new NamedParameterJdbcTemplate(dataSource); } @Override public Member save(Member member) { String sql = "insert into member(name, login_id, password, email) values(:name, :loginId, :password, :email)"; KeyHolder keyHolder = new GeneratedKeyHolder(); SqlParameterSource param = new BeanPropertySqlParameterSource(member); template.update(sql, param, keyHolder); long key = keyHolder.getKey().longValue(); member.setId(key); return member; } @Override public Member findById(Long id) { String sql = "select * from member where member_id = :id"; Map<String, Object> param = Map.of("id", id); Member member = template.queryForObject(sql, param, memberRowMapper()); return member; } @Override public Member findByLoginId(String loginId) { String sql = "select * from member where login_id = :loginId"; Map<String, Object> param = Map.of("loginId", loginId); Member member = template.queryForObject(sql, param, memberRowMapper()); return member; } @Override public void update(Long id, MemberUpdateDTO memberUpdateDTO) { String sql = "update member set name = :name, login_id = :loginId, password = :password, email = :email where id = :id"; SqlParameterSource param = new MapSqlParameterSource() .addValue("name", memberUpdateDTO.getName()) .addValue("loginId", memberUpdateDTO.getLoginId()) .addValue("password", memberUpdateDTO.getPassword()) .addValue("email", memberUpdateDTO.getEmail()); template.update(sql, param); } @Override public void delete(Long id) { String sql = "delete from member where id = :id"; Map<String, Object> param = Map.of("id", id); template.update(sql, param); } private RowMapper<Member> memberRowMapper() { return BeanPropertyRowMapper.newInstance(Member.class); } }
테스트 코드는 아래와 같습니다.
@Test void findById() { // given Member memberA = new Member("a", "a", "a", "a"); // when Member saveMember = memberRepository.save(memberA); log.info("{}", saveMember.getId()); Member findMember = memberRepository.findById(saveMember.getId()); log.info("{}", saveMember.getId()); log.info("{}", findMember.getId()); // then assertThat(saveMember).isEqualTo(findMember); }
memberA를 저장하고 findById로 찾아서 saveMember와 findMember의 내용물이 같은지 확인하는 코드입니다.
memberA를 저장하면 pk는 1이 될 것이라고 생각하여 findById(saveMember.getId());로 H2 DB에서 pk가 1인 행을 찾아 findMember로 반환하여 isEqualTo를 하려고 했습니다.
결과 이미지
saveMember의 getId 1로 findMember를 찾았는데 findMember의 getId는 null입니다.

따라서 테스트가 실패합니다.
테스트 환경
H2 스프링 내장 DB, jdk 17
항상 질문 답변 해주셔서 정말 감사합니다.
답변 1
RepositoryTest의 패키지 위치가 domain인 이유
0
36
2
REQUIRES_NEW 해결 방법에 대해서 질문있습니다!!
0
31
1
update()에 사용하는 setter 질문드립니다.
0
49
1
SQL 중심적 개발의 문제점에 대한 질문
0
75
1
혹시 Containing 을 안쓰신 이유가 있을까요?
0
86
2
[공유] 스프링부트 4.x 버전 mybatis 연동
0
183
1
@repository 어노테이션
0
91
3
ItemService
0
59
1
논리 커밋, 물리 커밋 질문드립니다.
0
54
1
내부 트랜잭션 커밋은 필수인가요?
0
57
1
프록시 커넥션 객체를 반환할 때 생성하는건가요?
0
55
1
Transaction readOnly 성능 개선 (김영한님의 대한 감사인사)
2
180
2
JPQL 대신 네이티브 쿼리를 사용해야 하는 경우
0
80
1
@EventListener(ApplicationReadyEvent.class) 관련
0
89
1
트랜잭션 동기화 매니저와 데이터 소스
0
77
1
DB 관련 강의 개설 계획은 없으신건가요?
0
133
2
물리 트랜잭션 과 논리트랜잭션 용어를 맞게 이해한걸까요
0
94
1
스프링 3 버전 이상 rollbackFor 변경된듯요
1
113
1
트랜잭션 전파 질문.
0
87
1
프로젝트 오픈 에러
0
126
1
외부 트랜잭션에서 isNewTransaction이 false로 나오는거에 대해 질문드립니다
0
84
2
같은 스레드를 사용하면 트랜잭션 동기화 매니저는 같은 커넥션을 반환
0
74
1
h2 인메모리 테스트중 예약어 충돌날 경우 대처방법
0
105
1
커스텀aop와 트랜잭션을 같이 사용할때 우선순위에 관한 질문
0
98
2





