본문 바로가기

Dev/JPA

RS) 기본키 매핑

기본 키 매핑 어노테이션

  • @Id (직접 할당)
    • 직접 할당하는 경우 @Id만 사용
  • @GeneratedValue (자동 생성)
    • GeneratedValue 전략 
      • IDENTITY : 데이터베이스에 위임, MYSQL
        • "나는 모르겠고, DB야 니가 알아서 해줘" 라는 의미의 전략
        • ID 값을 알 수 있는 시점이 DB에 값이 들어가야만 알 수 있다.
          • 영속성 컨텍스트에서 관리하려면(PK = ID)값이 있어야하는데, 이점이 문제가 된다.
          • 그래서 원래는 트랜잭션이 커밋되었을 때 INSERT 쿼리가 디비로 날라가야하는데 IDENTITY 타입의 전략에서만 예외적으로 em.persist 하는 순간 INSERT 쿼리가 날라가게 된다.
            	
                public class Member {
                    @Id
                    // GeneratedValue 전략이 IDENTITY 일 경우에만 예외적으로
                    @GeneratedValue(strategy = GenerationType.IDENTITY)
                    private Long id;
            
            	try{
                    Member member = new Member();
                    member.setUsername("C");
            
                    System.out.println("===================");
                    // em.persist 하는 순간 INSERT문이 날라간다.
                    // 영속성 컨텍스트에서 관리를 하려면 PK가 필요한데, IDENTITY 전략은 DB에 값이 들어가야만
                    // ID값을 확인할 수 있기 때문에..
                    em.persist(member);
                    System.out.println("===================");
                    
                    /* 실행결과 */
                    ===================
                    Hibernate: 
                        /* insert hellojpa.Member
                            */ insert 
                            into
                                Member
                                (id, age, description, roleType, testLocalDate, testLocalDateTime, name) 
                            values
                                (null, ?, ?, ?, ?, ?, ?)
                    ===================
      • SEQUENCE : 데이터베이스 시퀀스 오브젝트 사용, ORACLE
        • @SequenceGenerator 사용
        • Integer나 Int형의 타입은 사용하기 애매하다 → Long 타입을 사용하는 것을 추천
          @Entity
          @SequenceGenerator(name = “MEMBER_SEQ_GENERATOR",
          sequenceName = “MEMBER_SEQ", //매핑할 데이터베이스 시퀀스 이름
          initialValue = 1, allocationSize = 1)
          public class Member {
          @Id
          @GeneratedValue(strategy = GenerationType.SEQUENCE,
          	generator = "MEMBER_SEQ_GENERATOR")
          private Long id;
          • SEQUENCE 전략을 사용하는 것도 시퀀스를 사용하는 것이기 때문에 DB에 가봐야 값을 알 수 있다. 
            • em.persist 할때 영속성 컨텍스트에 넣어줘야하는데 그럴경우 PK가 필요하다.
            • 그래서 JPA는 em.persist 할 때 먼저 SEQUENCE 전략인 것을 확인하고 디비에서 시퀀스 값을 먼저 불러온다.
               try{
                      Member member = new Member();
                      member.setUsername("C");
              
                      System.out.println("===================");
                      em.persist(member);
              
                      System.out.println("member Id = "+ member.getId());
                      System.out.println("===================");
              
                      tx.commit(); // 커밋하는 순간 디비에 날라간다.
                      
                      /* 실행 결과 */
                      ===================
                      Hibernate: 
              	        // 영속성 컨텍스트에 넣기 위해 JPA는 전략이 시퀀스인 것을 확인하고 DB에서 시퀀스를 먼저 부른다.
                          call next value for MEMBER_SEQ 
                      member Id = 1
                      ===================
                      Hibernate: 
                          /* insert hellojpa.Member
                              */ insert 
                              into
                                  Member
                                  (age, description, roleType, testLocalDate, testLocalDateTime, name, id) 
                              values
                                  (?, ?, ?, ?, ?, ?, ?)​
      • TABLE : 키 생성용 테이블 사용, 모든 데이터베이스에서 시퀀스를 흉내내는 전략
        • 모든 데이터베이스에서 적용가능 하지만, 테이블을 직접 사용하다 보니까 성능이 안 좋다. 
        • TableGenerator 필요
      • AUTO : 바언에 따라 자동 지정
        • 설정하지 않으면 기본 값으로 AUTO로 설정 된다.
@Id @GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

권장하는 식별자 전략

  • 기본 키 제약 조건 : null 아님, 유일, 변하면 안된다.
  • 미래까지 조건을 만족하는 자연키를 찾기 어렵다. 대리키(대체키)를 사용하자
  • 주민등록번호같은 경우도 기본 키로 적절하지 않다.
  • 권장방법 : Long형 + 대체키 + 키 생성전략 사용

'Dev > JPA' 카테고리의 다른 글

RS) 연관관계 매핑 기초  (0) 2022.02.06
RS) 실전예제를 통한 문제점 분석  (0) 2022.02.06
RS) 필드와 컬럼 매핑  (0) 2022.02.03
RS) 객체 테이블 매핑  (0) 2022.02.02
RS) 준영속 상태  (0) 2022.02.01