inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

JPA 연관관계시 PK id가 숫자가 이어짐

382

유요한

작성한 질문수 49

0

JPA 연관관계를 맺어서 게시글과 댓글을 구현하는데 각 테이블이 1번으로 시작하는게 아니라 이어지는 상황이 생겨서 이게 정상적인가 의문이 들어서 질문을 드립니다. 기능은 제대로 돌아가는데 등록, 수정, 삭제 잘되는데 제가 알기론 id는 auto_increment 기능이면 각자 테이블에서 1번 부터 시작해서 자동증가로 알고있는데 여기는 이어지다 보니 의문이 생겨서

 

코드

@Entity(name = "board")
@ToString
@Table
@Getter
@NoArgsConstructor
public class BoardEntity extends BaseEntity{
    @Id @GeneratedValue
    @Column(name = "board_id")
    private Long boardId;
    private String title;
    private String contents;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "member_id")
    private MemberEntity member;

    @OneToMany(mappedBy = "boardEntity", cascade = CascadeType.ALL)
    // 댓글 정렬
    @OrderBy("id asc")
    private List<CommentEntity> comments = new ArrayList<>();

    @Builder
    public BoardEntity(Long boardId,
                       String title,
                       String contents,
                       MemberEntity member,
                       List<CommentEntity> comments) {
        this.boardId = boardId;
        this.title = title;
        this.contents = contents;
        this.member = member;
        this.comments = comments;
    }
}

@Entity(name = "comment")
@Table
@Getter
@NoArgsConstructor
public class CommentEntity extends BaseTimeEnity{
    @Id @GeneratedValue
    @Column(name = "comment_id")
    private Long id;
    private String comment;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "board_id")
    private BoardEntity boardEntity;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "member_id")
    private MemberEntity memberEntity;

    @Builder
    public CommentEntity(Long id, String comment, BoardEntity boardEntity, MemberEntity memberEntity) {
        this.id = id;
        this.comment = comment;
        this.boardEntity = boardEntity;
        this.memberEntity = memberEntity;
    }
}

@RequiredArgsConstructor
@Service
@Transactional
public class CommentService {
    private final CommentRepository commentRepository;
    private final MemberRepository memberRepository;
    private final BoardRepository boardRepository;

    // 댓글 작성
    public ResponseEntity<?> save(Long boardId,
                                  CommentDTO commentDTO,
                                  String memberEmail) {
        MemberEntity findMember = memberRepository.findByMemberEmail(memberEmail);
        BoardEntity findBoard = boardRepository.findById(boardId)
                .orElseThrow(EntityNotFoundException::new);


        List<CommentEntity> commentEntities = new ArrayList<>();
        if(findMember != null) {
            CommentEntity commentEntity = CommentEntity.builder()
                    .comment(commentDTO.getComments())
                    .boardEntity(findBoard)
                    .memberEntity(findMember)
                    .build();
            CommentEntity saveComment = commentRepository.save(commentEntity);
            commentEntities.add(saveComment);

            findBoard = BoardEntity.builder()
                    .boardId(findBoard.getBoardId())
                    .title(findBoard.getTitle())
                    .contents(findBoard.getContents())
                    .member(findMember)
                    .comments(commentEntities)
                    .build();
            boardRepository.save(findBoard);

            CommentDTO commentDTO1 = CommentDTO.toCommentDTO(saveComment);
            return ResponseEntity.ok().body(commentDTO1);
        } else {
            return ResponseEntity.notFound().build();
        }
    }

    // 댓글 삭제
    public String remove(Long boardId,
                         Long commentId,
                         String memberEmail) {
        BoardEntity findBoard = boardRepository.findById(boardId)
                .orElseThrow(EntityNotFoundException::new);

        CommentEntity findComment = commentRepository.findById(commentId)
                .orElseThrow(EntityNotFoundException::new);

        MemberEntity findMember = memberRepository.findByMemberEmail(memberEmail);

        boolean equalsEmail =
                findMember.getMemberEmail().equals(findComment.getMemberEntity().getMemberEmail());
        boolean equalsId = findComment.getBoardEntity().getBoardId().equals(findBoard.getBoardId());

        if(equalsEmail && equalsId) {
            commentRepository.deleteById(findComment.getId());
            return "댓글을 삭제했습니다.";
        } else {
            return "해당 이메일의 댓글이 아닙니다.";
        }
    }

    // 댓글 수정
    public ResponseEntity<?> update(Long boardId,
                                    Long commentId,
                                    CommentDTO commentDTO,
                                    String memberEmail) {
        BoardEntity findBoard = boardRepository.findById(boardId)
                .orElseThrow(EntityNotFoundException::new);

        CommentEntity findComment = commentRepository.findById(commentId)
                .orElseThrow(EntityNotFoundException::new);

        MemberEntity findMember = memberRepository.findByMemberEmail(memberEmail);

        boolean equalsEmail =
                findMember.getMemberEmail().equals(findComment.getMemberEntity().getMemberEmail());
        boolean equalsId =
                findComment.getBoardEntity().getBoardId().equals(findBoard.getBoardId());

        List<CommentEntity> commentEntities = new ArrayList<>();
        if(equalsEmail && equalsId) {
            findComment = CommentEntity.builder()
                    .id(findComment.getId())
                    .comment(commentDTO.getComments())
                    .boardEntity(findBoard)
                    .memberEntity(findMember)
                    .build();
            CommentEntity saveComment = commentRepository.save(findComment);
            commentEntities.add(saveComment);

            findBoard = BoardEntity.builder()
                    .boardId(findBoard.getBoardId())
                    .contents(findBoard.getContents())
                    .title(findBoard.getTitle())
                    .member(findBoard.getMember())
                    .comments(commentEntities)
                    .build();
            boardRepository.save(findBoard);

            CommentDTO returnComment = CommentDTO.toCommentDTO(saveComment);
            return ResponseEntity.ok().body(returnComment);
        } else {
            return ResponseEntity.badRequest().body("일치하지 않습니다.");
        }
    }
}

 

jpa mysql springboot

답변 1

0

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴이에요. JPA 연관관계를 맺어서 게시글과 댓글을 구현하고 계시는데, 각 테이블의 id가 숫자가 이어지는 상황이 생겼다고 하셨네요.

JPA에서는 @GeneratedValue 어노테이션을 사용하여 자동으로 id 값을 생성할 수 있습니다. 기본적으로는 auto_increment 기능으로 각 테이블마다 1번부터 시작해서 자동으로 증가하는 값을 할당합니다. 따라서, 보통은 각 테이블의 id 값이 숫자가 이어지게 됩니다.

그런데, 여러 테이블이 연관관계를 맺을 때는 연관되는 테이블의 id 값이 다른 테이블의 외래키로 사용됩니다. 이 때 연관 테이블의 id 값은 자동증가로 생성되지 않기 때문에 숫자가 이어질 수 있습니다.

제공해주신 코드를 보니 @ManyToOne과 @OneToMany 어노테이션을 사용하여 연관관계를 설정하고 계신데, 이런 경우에는 주 테이블의 id 값은 순차적으로 증가하고, 연관된 테이블의 외래키로 사용됩니다. 그래서 주 테이블의 id 값은 이어진 숫자가 될 수 있어요. 그리고 연관된 테이블의 id 값은 주 테이블과는 별개로 생성되기 때문에 순차적인 값이 아닐 수 있습니다.

큰 문제가 없으면서 기능도 정상적으로 동작한다면, 이렇게 id 값이 이어지는 것은 당신의 코드에서 의도한 동작일 가능성이 높습니다. 부가적으로, 데이터베이스에서 이어진 숫자 값이 중요한 요소라면, 다른 방법을 사용하여 숫자를 이어지지 않게 할 수도 있습니다.

더 자세한 도움이 필요하시면 언제든지 말씀해주세요. 좋은 하루 되세요!

inheritance startegy 선택시 고려사항

0

11

0

FOREIGN KEY 정리하기, 영상대로 SQL코드 복붙해도 안되요.

0

19

1

Entity 동등성 비교

0

14

1

패키지 구분에 대해 궁금한게 있습니다

0

20

2

스프링부트 서버 에러나요

0

22

1

코드를 첨부해야하는 이유가 있나요?

0

26

2

간단한 오타 제보입니다.

0

25

1

큰 범위 조회 시 EXPLAIN의 rows 값이 정확하지 않은 이유가 궁금합니다.

0

39

2

실제 FK제약조건을 설정하지 않는이유

0

41

2

조회속도 개선에서 더 개선하는 방법이 궁금합니다.

0

34

2

라이브 운영중인 환경의 테이블에 인덱스 추가시 고려사항

0

40

2

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

0

31

2

도메인 모델에서 관계와 규칙을 구분하는 방법

0

41

2

16 강의 메세지 retryCount의 의도

0

25

2

JPA Repository 질문이 있습니다!

1

35

2

페이지네이션 처리를 쿼리에서 하는 방식 질문

1

37

1

UserService, CertificationService 책임 분리 기준 질문

0

28

1

비동기 스레드풀 분리 이유와 Virtual Thread 전환 시 고려사항

0

38

1

수강기간 연장

0

28

1

Build 관련 문제 (테스트 관련 문제)

0

43

2

BCNF 질문

0

51

2

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

0

41

1

sdk 설정 오류

0

50

2

consumer에서 에러가 발생할 경우 데이터 유실 문의

0

39

2