inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

프로젝션(SELECT)

엔티티를 상속 받는 DTO 만들어도 되나요?

693

시큐웨어

작성한 질문수 6

1

=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)

[질문 내용]
 
 

안녕하세요. 영한님..

영한님 강의 너무 재밌게 잘 보고 있고 쉽고 간결한 설명에 매일 감탄 하며 공부중인 직장인입니다.

질문드리기전에 상황을 설명하면 이렇습니다.

(이해하기 쉬우시게 한글로 적겠습니다)

'병원' , '환자' 라고 하는 두 엔티티가 있습니다.

환자는 병원을  참조하고 있습니다(FK)

 

@Entity
@Getter @Setter
@Builder @EqualsAndHashCode(of = "id")
@AllArgsConstructor @NoArgsConstructor
public class 병원 {

@Id @GeneratedValue
private Long id;

private String name;

. . . .

// 환자 수
@Transient
    private Integer 환자수;
}

 

@Entity
@Getter @Setter
@EqualsAndHashCode(of = "id")
@AllArgsConstructor
@NoArgsConstructor
public class 환자 {

// 환자 아이디
@Id @GeneratedValue
@Column(name = "PAT_ID")
private Long id;

// 병원
@ManyToOne
@JoinColumn(name = "HOSP_ID")
private 병원 병원;

. . . .
}

 

위와 같이 두 엔티티가 존재하는데

병원 리스트를 검색하면서 각 병원에서 수용중인 환자 수를 같이 하고 불러오고 싶습니다.

 

이를테면 환자수가 1명이상인 병원목록을 불러온다했을때 

이걸 SQL로 작성하면

SELECT h.*,
( SELECT COUNT(*) FROM patient WHERE hosp_id = h.hosp_id ) as '환자수'
FROM hospital h
WHERE ( SELECT COUNT(*) FROM patient WHERE hosp_id = h.hosp_id ) > 1;

(사실 이게 효율적인 SQL인지도 모르겠습니다만, 전 이렇게 보통 씁니다..)

처럼 작성할 수 있을건데요

 

이럴때 세가지 질문이 있습니다.

1. 병원 엔티티 클래스에 '환자수' 라는게 있는게 일단 맞는지 부터가 문제입니다.  병원 리스트를 조회할때  환자수가 몇명인지 정보도 같이 필요한 페이지도 있고 필요가 없는 페이지도 있습니다.  

단, 환자수 정보가 필요할때는 '몇명 이상의 환자가 있는 병원 목록'과 같이 (위 SQL과 같이) where 절에 조건도 같이 붙게 됩니다.

환자수는 DTO로 따로 빼는게 맞을까요?

 

2.  (1번질문에서 따로 빼는게 좋겠다고 하였을때)

환자수를 포함하는 병원DTO를 만든다고 했을때 사실 그 DTO는 병원의 모든 필드가 필요 합니다.

그래서 하려면  아래처럼 병원을 상속받는 식이 되어야 할텐데 이렇게 DTO 클래스가 엔티티 클래스를 상속받아도 문제가 없고, 이렇게 사용하는게 일반적으로 현업에서도 많이 있는 일인가요?


public class 병원출력DTO extends 병원 {

private Integer 환자수;
}

 

3. 제가 하고자하는 것 ( 엔티티에 있는 모든 정보 + 서브쿼리를 통한 추가정보를 같이 불러오고 서브쿼리를 이용한 WHERE절 ) 이 굉장히 일반적으로 많이 쓰이는 것이라 분명 JPA 프로그래밍으로 충분히 쉽게 하는 방법이 이미 있을것 같은데 지식의 끊이 짧다보니

어떤 방법을 써야하는지 감을 못잡겠습니다.

 

SELECT h.*,
( SELECT COUNT(*) FROM patient WHERE hosp_id = h.hosp_id ) as '환자수'
FROM hospital h
WHERE ( SELECT COUNT(*) FROM patient WHERE hosp_id = h.hosp_id ) > 1;

이런 것을 하기위해 제가 뭘 찾아보고 공부하면 되는지 키워드나 팁를 알려주실수 있을까요 (QueryDsl을 활용하면 될것 같긴한데.. )

java JPA

답변 1

3

김영한

안녕하세요. 시큐웨어님

1,2 완전히 별도의 DTO로 뽑아야 합니다. 엔티티에는 순수한 데이터가 들어가야지 어떤 특정 계산의 결과값이 들어가면 안됩니다. 추가로 엔티티를 상속받지 말고, DTO를 만들어주세요. 엔티티와 DTO를 잘 분리해서 개발하는 것이 핵심 포인트입니다.

3. JPQL도 서브쿼리를 지원합니다. 단 from 절의 서브쿼리는 지원하지 않습니다. 해당 쿼리의 경우 JPQL의 new 명령어를 사용해서 DTO로 결과를 뽑으시면 됩니다.

감사합니다.

벌크연산에서 member.getAge 호출 시 영속성 컨텍스트에서 데이터를 가져오는건가요?

0

54

2

inheritance startegy 선택시 고려사항

0

36

1

Entity 동등성 비교

0

38

1

실무 조언 관련 질문입니다.

0

64

1

H2데이터베이스 파일 생성

0

76

2

서브쿼리 강의에서 ALL 예시 관련 질문드립니다.

0

66

2

수정또는 삭제시 영속성 엔티티에 값이 무조건 있어야 하나요?

0

62

1

JPQL 메소드와 락

0

62

1

Delivery @OneToOne

0

70

1

17강 4~5분대 테이블 값 조회가 안됩니다.

0

104

2

UnsupportedOperationException 발생

0

97

3

H2 Database 연결이 안됩니다.

0

101

2

연관관계 매핑 질문드립니다.

0

93

2

h2데이터베이스 실행오류

0

114

2

persistence.xml

0

119

2

양방향 연관관계에서 연관관계의 주인(mappedBy)을 왜 꼭 정해야 하나요?

0

87

1

영속성 컨텍스트

0

74

1

JPA 프록시

0

105

1

Native Query와 MyBatis

0

81

1

영속성 컨텍스트는 어떤 메모리에 저장되는건가요?

0

97

1

임베디드 타입 예시 코드 관련 질문

0

125

3

명시적 조인에서 별칭을 주면 왜 객체에 접근할 수 있나요

0

100

3

인텔리제이 패키지 커서 단축키 질문

0

112

2

혹시 현재는 ID 데이터 타입이 String이면 안되나요?

0

151

1