인프런 커뮤니티 질문&답변

치훈이님의 프로필 이미지
치훈이

작성한 질문수

자바 ORM 표준 JPA 프로그래밍 - 기본편

insert 관련 질문입니다.

작성

·

231

1

안녕하세요 영환님!

최근에 우아한 토크 콘서트 영상을 보다가 하나 의문점이 있어서 질문드립니다. (영한님 영상도 재밌게 잘봤습니다ㅎㅎ)

이동욱님이 발표하신 영상 중 save시엔 연관관계에 있는 엔티티의 ID만 있으면 된다는 내용이 있었습니다.

지금까지는 save시에 연관관계에 있는 엔티티가 존재하면 해당 엔티티의 ID로 먼저 엔티티를 조회해오고 save를 할때 조회된 엔티티를 넘겨줬었는데요(아래와 같이)

영상에 나온 소스코드를 보니 아래와 같이 생성자에 직접 아이디를 넘겨주고 엔티티를 생성한 후 설정을 하더라구요(아래와 같이)

실제로 save시에 ID만으로 엔티티를 생성 후 저장을 해보니 이상없이 잘 저장은 됩니다.

근데 여기서 드는 의문이..

JPA는 DB 중심이 아닌 객체중심의 사고방식을 가지고 사용을 해야하고 PK(id) 또한 직접 설정하는게 아닌 repository 조회를 통하여 가져와야 된다고 알고 있었습니다.

그래서 엔티티 생성시에 setter는 만들지 않았고 id또한 절대 외부에서 값을 설정할 수 없게 해왔었는데요

저 영상을 보고 난 후 많이 혼란스럽네요ㅠㅠ

직접 id만으로 엔티티를 생성 후 save를 하자니 뭔가 예전의 레거시 코드를 작성하는것 같고(mybatis...)

아니면 상황에 따라 적절한 방법을 선택해서 사용을 해야 되는 걸까요..?

조언부탁드립니다!

감사합니다.

답변 3

1

치훈이님의 프로필 이미지
치훈이
질문자

두분다 답변 감사합니다 ^^ 많은 도움 되었습니다!

상황에 맞게 적절한 방법을 선택해서 사용하면 되겠네요

감사합니다(__)

1

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 치훈이님

유창님이 좋은 글을 남겨주셨네요.

모든 것에는 정석이 있고, 또 성능 최적화를 할 때는 때때로 정석을 깨는 트래이드 오프가 있습니다.

중요한건 성능을 위해서 정석을 희생할 때는 그에 따른 문제가 뭔지 인식하고 사용하는 것이 중요합니다.

감사합니다.

1

"JPA는 DB 중심이 아닌 객체중심의 사고방식을 가지고 사용을 해야하고"
> JPA는 ORM으로서 객체와 RDBMS 맵핑 작업을 대신해주는 기술로서 사용을 해야하는게 아니라 사용할 수 있다 라고 봐야할 것 같습니다.

"PK(id) 또한 직접 설정하는게 아닌 repository 조회를 통하여 가져와야 된다고 알고 있었습니다."
>
이동욱님 예제를 보면 customerId 는 AdItem 테이블에서 조회한 값입니다.

"그래서 엔티티 생성시에 setter는 만들지 않았고 id또한 절대 외부에서 값을 설정할 수 없게 해왔었는데요"
> 보통 setter 를 두지 않는 이유는 여기 저기서 객체(엔티티)의 값을 변경할 수 있게 되어 객체의 일관성을 보장할 수 없기 때문입니다. 그리고 setter 를 사용하는 경우 소스코드의 의도를 알기가 힘든 경우가 발생합니다. 간단한 예제를 드리면 Customer의 이름을 변경할 경우 setName() 보다는 changeName() 이 더욱 의도가 분명해보이죠.

"직접 id만으로 엔티티를 생성 후 save를 하자니 뭔가 예전의 레거시 코드를 작성하는것 같고(mybatis...)"
> 직접 Id 만으로 Entity 생성하여 save 하는 경우와 연관관계 Entity 를 가지고 생성하여 save 하는 경우 Hibernate가 생성하는 쿼리는 다를까요?

"상황에 따라 적절한 방법을 선택해서 사용을 해야 되는 걸까요..?"
> 저도 그렇게 생각합니다!

이동욱님의 예제에 대해 추가적으로 설명을 드린다면

이동욱님의 의견은 "상황에 따라 ORM / 전통적 Query 방식을 골라 사용하기" 입니다. 저 의견은 프로그래밍에서 일맥상통하는 핵심입니다. 현실의 문제들이 있고 그 문제를 해결하는 기술들이 있습니다. 우리는 여러 조건 상황에서 알맞는 기술을 적용하여 문제를 해결해야합니다.

이동욱님 예제의 업무요건을 유추하면 첫번째는 "AdItem(광고) 테이블에서 특정기간, 특정주문유형에 해당하는 AdItem에 대해 주문유형, 거래일자, 고객 별 합계를 조회한다" 인것 같습니다. 그리고 AdItem 은 Customer 와 연관관계에 있습니다.

AdItem 합계를 조회할 때 Customer 의 정보 중에서는 Id 외에는 불필요한 정보라고 설명합니다. 이 경우에 AdItem 합계를 조회할 때 Customer 전체를 조회한다면 쿼리 시간이 14초 걸립니다. Customer Id 만 조회하는 경우는 2.5초 입니다.

두번째 업무요건은 "조회된 AdItem 합계 정보로 AdBond(광고계약) 을 생성한다" 인것 같고, 마찬가지로 AdBond는 Customer와 연관관계에 있습니다. AdBond를 DB 테이블에 저장하기 위해서는 외래키로 연관관계의 Customer 의 Id 만 있으면 됩니다. 사전 작업으로 14초 걸리는데 ORM 기술을 사용하기 위해 해당 시간을 수용해야할까요?

저도 잘 모르지만 혼란스러워 하시는 부분에 도움이 됐으면 합니다. 감사합니다.

치훈이님의 프로필 이미지
치훈이

작성한 질문수

질문하기