inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

다대일 양방향 연관관계를 사용할 경우 질문이 있습니다.

186

treesheep

작성한 질문수 3

0

## 다대일 양방향 연관관계를 사용할 경우 질문이 있습니다
 아래와 같이 Reply 엔티티를 생성할 때 Board엔티티의 List<Reply> replies에 추가를 해주어야 하기 떄문에,
 엔티티 생성시 필요한 엔티티에 대한 select문은 getReferenceById를 사용해서 없앨 수 있었고 Reply엔티티 생성도 할 수 있었다.
````agsl
    @Transactional
    public Reply addReply(Long memberId, Long boardId, String content) {

        Member member = memberRepository.getReferenceById(memberId); //엔티티 생성에 불필요한 select문 없다.
        Board board = boardRepository.getReferenceById(boardId);
        System.out.println("===================");
        Reply reply = Reply.createReply(member, board, content);
        System.out.println("===================");
        return replyRepository.save(reply);
    }
````
 다만 다대일 양방향 연관관계의 경우 댓글을 저장할 때마다, Board에 대한 Select쿼리가 발생한다.
 
````agsl
    public static Reply createReply(Member member, Board board, String content) {
        Reply reply = new Reply();
        reply.member = member;
        reply.board = board;
        reply.content = content;
        reply.likeCount = 0;
        reply.isDeleted = false;
        log.info("board select 발생 넣기 --");
        board.addReply(reply);
        log.info("board select 발생 넣기 --");
        return reply;
    }
````

이렇게 댓글을 저장할 때 마다 board에 대한 select쿼리가 발생하다 보니 다대일 양방향 관계를 하지 말아야 하는 생각이 드는데요..
지금 프로젝트에서는 양방향 연관관계의 장점은 영속성 전이와 orphanremoval을 사용헤서 게시글 삭제시 댓글이 모두 삭제되는 이점을 얻는다는 것이 있습니다.
물론 board삭제할 경우 replyrepository에서 boardId를 통한 댓글 삭제가 가능할 것으로 생각 되는데요.

댓글을 작성할 때마다 Board select쿼리가 나가는 것은 성능상의 이슈로 봐야 할까요?? -> 다대일 단방향 연관관계로 바꾸는게 맞을까요?
아니면 양방향 연관관계의 경우 JPA를 사용하지 않을시 객체지향적 코드를 보장한다는 이야기를 들었는데 Board조회시 조인하여 Reply 컬렉션을 조회할 수 있다는 것이 장점으로 느껴지긴 합니다
(단방향 연관관계일 경우 reply 컬렉션 조회 메서드를 따로 작성해서 해결해야 함.)
어떤 선택을 해야할 지 질문드립니다!!
어떤 선택을 해야 할까요?

아래는 발생 쿼리 로그입니다.
```agsl
===================
2024-02-03T14:15:00.936+09:00  INFO 2612 --- [    Test worker] cos.blog.web.model.entity.Reply          : board select 발생 넣기 --
2024-02-03T14:15:00.937+09:00 DEBUG 2612 --- [    Test worker] org.hibernate.SQL                        : 
    select
        b1_0.board_id,
        b1_0.content,
        b1_0.created_time,
        b1_0.last_modified_time,
        b1_0.member_id,
        b1_0.title 
    from
        board b1_0 
    where
        b1_0.board_id=?
2024-02-03T14:15:00.938+09:00  INFO 2612 --- [    Test worker] p6spy                                    : #1706937300938 | took 0ms | statement | connection 74| url jdbc:h2:tcp://localhost/~/blog
select b1_0.board_id,b1_0.content,b1_0.created_time,b1_0.last_modified_time,b1_0.member_id,b1_0.title from board b1_0 where b1_0.board_id=?
select b1_0.board_id,b1_0.content,b1_0.created_time,b1_0.last_modified_time,b1_0.member_id,b1_0.title from board b1_0 where b1_0.board_id=31;
2024-02-03T14:15:00.939+09:00  INFO 2612 --- [    Test worker] cos.blog.web.model.entity.Reply          : board select 발생 넣기 --
===================
2024-02-03T14:15:00.940+09:00 DEBUG 2612 --- [    Test worker] org.hibernate.SQL                        : 
    insert 
    into
        reply
        (board_id, content, created_time, is_deleted, last_modified_time, like_count, member_id, reply_id) 
    values
        (?, ?, ?, ?, ?, ?, ?, default)
2024-02-03T14:15:00.942+09:00  INFO 2612 --- [    Test worker] p6spy                                    : #1706937300942 | took 0ms | statement | connection 74| url jdbc:h2:tcp://localhost/~/blog
insert into reply (board_id,content,created_time,is_deleted,last_modified_time,like_count,member_id,reply_id) values (?,?,?,?,?,?,?,default)
insert into reply (board_id,content,created_time,is_deleted,last_modified_time,like_count,member_id,reply_id) values (31,'replyreply','2024-02-03T14:15:00.939+0900',false,'2024-02-03T14:15:00.939+0900',0,12,default);
===================
```

java jpa

답변 1

1

김영한

안녕하세요. 이원준님

이 부분은 선택인데요. 최적화를 하려면 다대일 단방향으로 변경해야 합니다.

하지만 일반적으로 이 정도 조회는 다음과 같은 이유로 전체적으로 보면 성능에 크게 문제가 되지는 않습니다.

  1. 이 로직은 댓글이 달릴 때 사용되는데요. 일반적으로 게시물을 보는 사용자가 10이라면 게시물에 답글을 다는 사용자는 1이 안됩니다.

  2. PK를 기준으로 데이터 1건을 DB에서 조회하는 것은 매우 빠릅니다.

감사합니다.

inheritance startegy 선택시 고려사항

0

11

0

Entity 동등성 비교

0

14

1

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

0

41

1

H2데이터베이스 파일 생성

0

52

2

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

0

49

2

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

0

48

1

JPQL 메소드와 락

0

53

1

Delivery @OneToOne

0

57

1

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

0

89

2

UnsupportedOperationException 발생

0

82

3

H2 Database 연결이 안됩니다.

0

89

2

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

0

82

2

h2데이터베이스 실행오류

0

105

2

persistence.xml

0

103

2

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

0

77

1

영속성 컨텍스트

0

62

1

JPA 프록시

0

90

1

Native Query와 MyBatis

0

63

1

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

0

84

1

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

0

112

3

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

0

91

3

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

0

106

2

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

0

137

1

양방향 연관관계 시 연관관계 주인을 설정하는 이유

0

68

1