inflearn logo
강의

Khóa học

Chia sẻ kiến thức

Spring DB Phần 2 - Kỹ thuật sử dụng truy cập dữ liệu

JdbcTemplate - Tham số đặt tên 3

KeyHolder가 데이터베이스에 따라 다르게 동작할까요?

Đã giải quyết

820

shanePark

5 câu hỏi đã được viết

1

안녕하세요 :)
 
    @Override
public Item save(Item item) {
String sql = "insert into item(item_name, price, quantity)" +
" values (:itemName,:price,:quantity)";

BeanPropertySqlParameterSource param = new BeanPropertySqlParameterSource(item);

KeyHolder keyHolder = new GeneratedKeyHolder();
template.update(sql, param, keyHolder);

long id = keyHolder.getKey().longValue();
item.setId(id);
return item;
}
 
save 메서드를 강의대로 했을때 저는 InvalidDataAccessApiUsageException 이 발생 하더라고요.
 
org.springframework.dao.InvalidDataAccessApiUsageException: The getKey method should only be used when a single key is returned. The current key entry contains multiple keys: [{id=7, item_name=productE, price=50000, quantity=20}]
 
그래서 id 를 받아 오는 부분을
```java
Long id = (Long) keyHolder.getKeys().get("id");
```
key를 받아오고 id 를 빼는 식으로 변경 했더니 잘 동작 합니다.
혹시나 해서 테이블을 확인 했는데 primary key 설정도 되어 있는 상태 입니다.
강의를 회사에 일찍 출근해서도 듣고 집에 퇴근하고 와서도 듣다보니 연속성을 위해 PostgresDB를 따로 구축해두고 사용하고 있는데 .. 혹시나 해서 H2 로 변경 해서 테스트 해 보니 getKey() 만 해도 정상적으로 동작 되었습니다.
KeyHolder의 getKey가 DB에 따라 상이하게 동작하는걸까요..?
 
update 파라미터를 우연히 보았더니 keyColumn 을 파라미터로 받길래
 
혹시나 해서 "id" 를 넣었더니, 이 때에도 getKey()가 정상적으로 동작 하였습니다.
 
우연히 해결을 하기는 했는데 KeyHolder의 작동 원리에 대한 이해가 없다보니 궁금하네요..
 
1. DB 에 테이블을 등록할 때 제가 뭔가 누락한게 있어서 그럴까요? 아니면 단순히 Postgres 를 사용해서 그런 걸까요?
2. DB에 따라 getKey()가 안될 수 있다면, getKeys() 후에 원하는 key를 받아오는 것과 update 할 때에 key column을 명시해 주는 것 중 어느쪽이 더 명확할까요? 혹은 더 나은 방법이 있을까요?
 
감사합니다
 

spring

Câu trả lời 2

2

OR

저도 마찬가지로 postgresql로 진행하다가 같은 문제를 만나서, getKeys() 로 맵을 받은 후, 그곳에서 id를 가져오는 방식을 사용했습니다.

혹시나 해서 질문란을 오니 역시나 훌륭한 답변이 있었군요. 전 이 글을보고 key column을 명시해 주는 방향이 낫다고 생각해서 이 방법으로 변경하였습니다.

왜냐하면 그렇게 해야 아주 조금이라도 서버-DB간 주고 받는 데이터가 줄어들지 않나 싶었습니다.

key column을 명시하지 않은 경우:

  • 서버에 쿼리 날릴 때 키 컬럼 어레이 부분을 보내지 않음.

  • 하지만 DB에서 보내오는 keyHolder 값에 모든 컬럼의 값이 포함. (id, item_name, price, quantity)

key column을 명시한 경우:

  • 서버에 쿼리 날릴 때 키 컬럼 어레이 new String[]("id)를 포함.

  • 대신 DB에서 보내오는 keyHolder 값에 id 컬럼 값만 포함.

엔티티의 컬럼 값이 늘어날수록, 두 경우의 데이터 전송량의 차이는 더 늘어날 것 같습니다.

2

yh

안녕하세요. shane님

이 부분은 저도 정확히 잘 모르겠습니다. 혹시 아시는 분 있으면 답변 부탁드려요.

감사합니다.

1

YG K

https://shanepark.tistory.com/383

후에 블로그에 작성해 두셨네요

0

yh

공유 감사합니다^^

RepositoryTest의 패키지 위치가 domain인 이유

0

30

2

REQUIRES_NEW 해결 방법에 대해서 질문있습니다!!

0

30

1

update()에 사용하는 setter 질문드립니다.

0

47

1

SQL 중심적 개발의 문제점에 대한 질문

0

72

1

혹시 Containing 을 안쓰신 이유가 있을까요?

0

84

2

[공유] 스프링부트 4.x 버전 mybatis 연동

0

174

1

@repository 어노테이션

0

89

3

ItemService

0

58

1

논리 커밋, 물리 커밋 질문드립니다.

0

54

1

내부 트랜잭션 커밋은 필수인가요?

0

57

1

프록시 커넥션 객체를 반환할 때 생성하는건가요?

0

54

1

Transaction readOnly 성능 개선 (김영한님의 대한 감사인사)

2

178

2

JPQL 대신 네이티브 쿼리를 사용해야 하는 경우

0

77

1

@EventListener(ApplicationReadyEvent.class) 관련

0

88

1

트랜잭션 동기화 매니저와 데이터 소스

0

76

1

DB 관련 강의 개설 계획은 없으신건가요?

0

133

2

물리 트랜잭션 과 논리트랜잭션 용어를 맞게 이해한걸까요

0

94

1

스프링 3 버전 이상 rollbackFor 변경된듯요

1

112

1

트랜잭션 전파 질문.

0

87

1

프로젝트 오픈 에러

0

126

1

외부 트랜잭션에서 isNewTransaction이 false로 나오는거에 대해 질문드립니다

0

83

2

같은 스레드를 사용하면 트랜잭션 동기화 매니저는 같은 커넥션을 반환

0

73

1

h2 인메모리 테스트중 예약어 충돌날 경우 대처방법

0

102

1

커스텀aop와 트랜잭션을 같이 사용할때 우선순위에 관한 질문

0

98

2