inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

173만명의 커뮤니티!! 함께 토론해봐요.

강의자료와 실제 생성 테이블이 다르고, Address가 값 객체일 수 없다고 생각합니다.

미해결

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

[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 안녕하세요. 김영한님의 강의를 잘 보고 있습니다. 강의를 보던도중, 문득 의문점이 들어서 여쭤보고자 질문을 작성하게 되었습니다. 질문의 테마는 값 타입 컬렉션과 기본키라고 할 수 있겠네요. 기본 지식 테이블은 기본키가 있을수도, 없을수도 있다. 제가 배운대로는, 테이블은 기본키가 존재할 수도 있고 존재하지 않을 수도 있다고 배웠습니다. 그리고 기본키를 두는 이유는 기본키가 겹치지 않도록 해서, 데이터 중복을 막고, 조회 시 효율 증가를 위해서라고 생각했습니다. 김영한님의 강의에서 말하는 값타입은 주소가 다르더라도 안에 있는 값이 모두 같다고 하신걸로 이해했습니다. 그래서 자바 객체가 값타입으로 들어가는 경우에는 equals를 통해서 같은지를 비교한다는 것도요!! 김영한님의 강의 중 예제로 들어주셨던 Member의 favoriteFoods, addressHistory는 값 타입을 데이터베이스 테이블로 변환한 예시로 이해했습니다. 그리고 강의 내용에서 JPA를 이용해서 Table 구조를 생성하는 걸로 이해했습니다. 여기까지가 제가 이해한 내용입니다. 저는 그래서 해당 구조로 데이터베이스를 만들어준다고 인지했고, FAVORITE_FOOD, ADDRESS는 각각 중복값이 들어갈 수없다고 생각했습니다. 문제상황 하지만 테이블의 생성 내용을 보면, 기본키 설정 부분이 빠져 있습니다. 외래키 매핑만 되어 있고 실제로 기본키 부분이 빠져있습니다. 제가 만든, ADDRESS 테이블을 예시로 들면, 이는, FAVORITE_FOOD 도 동일합니다. 정말 중복값이 들어갈 수 없는지 테스트해보았습니다. 테스트를 위한 코드는 다음과 같습니다. Address address = new Address("newCity", "street", "10000"); Member member1 = new Member(); member1.setName("member1"); member1.setHomeAddress(address); member1.getFavoriteFoods().add("치킨"); member1.getFavoriteFoods().add("치킨"); member1.getFavoriteFoods().add("치킨"); member1.getFavoriteFoods().add("피자"); member1.getFavoriteFoods().add("족발"); Address oldAddress = new Address("oldCity3", "street", "10000"); member1.getAddressList().add(new Address("oldCity", "street", "10000")); member1.getAddressList().add(new Address("oldCity2", "street", "10000")); member1.getAddressList().add(new Address("oldCity3", "street", "10000")); member1.getAddressList().add(new Address("oldCity3", "street", "10000")); member1.getAddressList().add(new Address("oldCity3", "street", "10000")); em.persist(member1); 결과값은 다음과 같습니다. 값을 보게되면, FAVORITE_FOOD의 경우는 Set 자료구조 사용으로 중복값이 들어갈 수 없는 것이고, ADDRESS의 경우는 중복값이 들어갈 수 있었습니다. 만약 값의 변경이 일어나는 경우에는 어떻게 될까? 하는 고민이 생겨, 중복으로 들어있는 내용의 값을 변경해보았습니다. Address address = new Address("newCity", "street", "10000"); Member member1 = new Member(); member1.setName("member1"); member1.setHomeAddress(address); member1.getFavoriteFoods().add("치킨"); member1.getFavoriteFoods().add("치킨"); member1.getFavoriteFoods().add("치킨"); member1.getFavoriteFoods().add("피자"); member1.getFavoriteFoods().add("족발"); Address oldAddress = new Address("oldCity3", "street", "10000"); member1.getAddressList().add(new Address("oldCity", "street", "10000")); member1.getAddressList().add(new Address("oldCity2", "street", "10000")); member1.getAddressList().add(new Address("oldCity3", "street", "10000")); member1.getAddressList().add(new Address("oldCity3", "street", "10000")); member1.getAddressList().add(new Address("oldCity3", "street", "10000")); em.persist(member1); em.flush(); em.clear(); Member findMember = em.find(Member.class, member1.getId()); System.out.println("================== Start 2 =================="); findMember.getAddressList().remove(oldAddress); findMember.getAddressList().add(new Address("newCity1", "street", "10000")); tx.commit(); 결과값은 다음과 같습니다. 중복값을 한번에 지워준다면, 그래도 결과적으로는 ADDRESS값을 중복이 없는 값객체로 쓸 수 있겠다고 생각했지만, 모두 지우지 않고 중복값을 하나만 지웠습니다. 물론 List의 특성 상 중복 값 한개만 지우는게 당연하지만요. 가설 목표하던 테이블 구조로 실제로 만들어지지 않았다고 생각했습니다. -> 기본키가 없다. 왜냐하면 생성하고자 하는 테이블 구조와 생성된 테이블 구조가 다르기 때문입니다. 음식에서 중복이 생기지 않는 이유는 Set의 특성 때문이지 테이블 때문이 아니라고 생각이 들었습니다. 값 객체의 특성 상 중복을 허용하는 경우는 없다. 좋아하는 음식의 경우 같은 음식이 두번 있을 이유는 없지만, 이전의 주소의 경우는 같은 주소에 두번 이사갈 수 있다. 그렇다면 음식과 다르게 주소의 경우는 중복이 가능하고, 값을 추적할 수 있어야 하므로 Entity로 사용하는게 맞지 않을까요? 이 부분은 김영한님깨서 설명해주신 부분과 일치하지만, 결론까지 도달한게 맞는지 궁금합니다. 두서 없이 길게 적은 것 같은데, 제가 생각한 가설이 맞는지가 궁금합니다. 그리고 나아가 가설까지 도달하는 방식에 문제가 있거나 고칠점이 있다고 피드백도 부탁드립니다. 읽어주셔서 감사합니다.

  • 값타입
  • java
  • 값타입컬렉션
  • JPA
  • 기본키
이국준 댓글 3 좋아요 5 조회수 823

기본키와 관련하여 질문드릴게요!.

미해결

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

@Entity @Getter @Setter @NoArgsConstructor (access = AccessLevel. PROTECTED ) public class Bbs { @Id @GeneratedValue (strategy = GenerationType. SEQUENCE ) @Column (name = "BBS_NO" ) private Long bbsNo ; //bbs 기본키 private String bbsTitle ; private String bbsContent ; private String bbsDate ; @ColumnDefault ( "0" ) private Integer bbsHit ; private String bbsNotice ; private String bbsSecret ; @ManyToOne (fetch = FetchType. LAZY ) @JoinColumn (name = "MEMBER_ID" ) private Member member ; @OneToMany (mappedBy = "bbs" ) List<Comment> comments = new ArrayList<>() ; public void addMember (Member member){ this . member =member ; member.getBbs().add( this ) ; } public Bbs (String bbsTitle , String bbsContent , String bbsDate , Integer bbsHit , String bbsNotice , String bbsSecret , Member member) { this . bbsTitle = bbsTitle ; this . bbsContent = bbsContent ; this . bbsDate = bbsDate ; this . bbsHit = bbsHit ; this . bbsNotice = bbsNotice ; this . bbsSecret = bbsSecret ; this . member = member ; } public void updateBbs (Long bbsNo , String bbsTitle , String bbsContent , String bbsDate , Integer bbsHit , String bbsNotice , String bbsSecret) { this . bbsTitle = bbsTitle ; this . bbsContent = bbsContent ; this . bbsDate = bbsDate ; this . bbsNotice = bbsNotice ; this . bbsSecret = bbsSecret ; } } 위에 코드가 bbs기본키 전략이고. @Entity @Getter public class Comment { @Id @GeneratedValue (strategy = GenerationType. SEQUENCE ) @Column (name = "COMMENT_NO" ) private Long commentId ; //comment 기본키 private String content ; @ColumnDefault ( "0" ) private int commentCnt ; // 대댓글시 정렬을 위해 사용 @ColumnDefault ( "0" ) private int commentGroup ; private String Date ; @ColumnDefault ( "0" ) private int commentSequence ; @ColumnDefault ( "0" ) private int level ; @ManyToOne (fetch = FetchType. LAZY ) @JoinColumn (name = "BBS_NO" ) private Bbs bbs ; @ManyToOne (fetch = FetchType. LAZY ) @JoinColumn (name = "MEMBER_ID" ) private Member member ; public Comment () { } public Comment (String content , int commentCnt , int commentGroup , String date) { this . content = content ; this . commentCnt = commentCnt ; this . commentGroup = commentGroup ; this . Date = date ; } public void addMember (Member member){ this . member =member ; member.getComments().add( this ) ; } public void addBbs (Bbs bbs){ this . bbs =bbs ; bbs.getComments().add( this ) ; } } 이게 코맨트(댓글) 기본키 전략입니다. 위에 사진을 보면 bbs_no이랑 commemt_no이랑 기본키가 같이 올라갑니다..... 제가 원하는건 bbs_no 도 1부터 증가하고 comment_no도 1부터 증가하게 하고싶은데 따로 기본키 설정을 해주었는데 왜 같이 올라가는지 잘 모르겠습니다. 강의나,JPA 기본키 전략을 다시 보아도 해결책을 찾이 못해 질문 드립니다.

  • 기본키
  • JPA
  • java
조인태 댓글 1 좋아요 0 조회수 221

Primary Key 선정 기준

미해결

데이터베이스 중급(Modeling)

안녕하세요, 강의 잘 듣고 있습니다 Primary Key 지정할 때 Unique와 Not Null 두가지가 중요하다고 말씀해 주셨는데요 1. 레코드 최대 수가 int 형 범위 이내이면 굳이 Primary Key 선정에 대해 고민을 안하고 모든 테이블 Primary Key를 id (int형 자동증가)로 설정해도 되나요? 2. 실무에서 id(int 형 자동증가) 로 쓰는 경우가 많은 가요? 3. 수강신청시스템의 경우 학번으로 primary key 지정 vs id(int형 자동증가) 지정 어떤 장단점이 있는지 궁금합니다. 감사합니다!

  • PrimaryKey
  • DBMS/RDBMS
  • 주식별자
  • 기본키
  • 데이터 엔지니어링
와우런 댓글 2 좋아요 1 조회수 1420

인기 태그

인프런 TOP Writers

주간 인기글