문제
Code
@Entity
@Getter
public class Member {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name", nullable = false)
private String userName;
private Long age;
}
@Transactional
void test() {
Member member = new Member();
member.setName("김이름");
member.setAge(23L);
em.persist(member);
System.out.println("김이름의 id = " + member.getId()); //
}
의문점
JPA는 em.persist()
를 통해 객체를 영속 상태로 만든다.
그리고, 트랜잭션이 커밋되는 시점에 변경을 감지하여 새로 생성된 객체를 DB에 반영한다.
EntityTransaction의 commit이나 flush를 통해 트랜잭션 커밋을 수행할 수 있다.
또는, @Transactional 어노테이션을 설정하면 하나의 메서드가 종료되면 트랜잭션 커밋이 이루어진다.
AUTO_INCREMENT는 DB에 insert SQL을 실행한 이후에 ID 값을 알 수 있다.
따라서, em.persist(member)
를 통해 한 명의 회원 객체를 영속 상태로 만든다고 해도, 트랜잭션 커밋이 이루어지지 않는다면 id 값을 참조하여도 null 값인 걸 알 수 있다.
하지만, 위 코드에서는 em.persist(member)
코드 직후에도 id 값이 정상적으로 참조되는 것을 확인했다.
이유
IDENTITY 전략
엔티티의 기본 키 매핑을 할 때, IDENTITY 전략을 사용하면 바로 id 값을 참조할 수 있다.
왜냐하면, IDENTITY 전략은 em.persist()
시점에 즉시 insert SQL 실행하고, DB에서 식별자를 조회하기 때문이다.
JPA 공부를 제대로 하지 않고, 코드부터 작성해서 삽질을 엄청 한 것 같다. 하하;