Spring/JPA

EntityManger.persist()를 하고 ID값을 반환하는 과정

whyWhale 2021. 7. 2.

내가 알고 있던 persist() ,find()

JPA의 EntityManget. 객체에서 find메소드는  EntityManget.find( $Object.class, Obejct.getId() ) 으로 사용한다. 그러므로 find를 할 때 1차 캐시를 조회하고 DB로 가져와 영속성 컨텍스트에 올린다.

하지만 em.persist()를 하면 쓰기지연에 보관되고 식별자 값은 알아서 만들어주는 줄 알고 있었다.

 

 

Q. 보통 저장을 할때 em.persist($Object); 를 통해 Persistenc Context에 올려놓는다(1차 캐시)

   그런데 만약 Repository에서 em.persist( $Obejct )를 진행하고 반환 값이 $Obejct.getId()라면?

   식별자가 null인 경우는 어떻게 영속성 컨텍스트에 저장할까? 

 

 

JPA는 persist()가 호출되고 엔티티가 영속성 컨텍스트에 저장되기 위해 식별자가 반드시 필요하다.

 


영속성 컨텍스트에 올리기 위한 과정

 

  • Entity의 식별자가 GeneratedValue인지 확인한다.
  • GeneratedValue가 아니라면 식별자가 없으므로 영속성 컨텍스트에 저장 불가. javax.persistence.PersistenceException: org.hibernate.id.IdentifierGenerationException: ... 처럼 Exception이 터진다.
  • GeneratedValue 라면 하이버네이트의 경우는 JDBC3에서 제공하는 API의 Statement.getGeneratedKeys() 메서드를 사용하여 데이터를 저장함과 동시에 생성된 식별자 값을 얻어온다.



그러면 이 경우 쓰기지연은 발생할 것인가?  --> X

발생하지 않는다. em.persist()가 호출됨과 동시에 insert 쿼리를 날려서 DB에 저장했고, 다시 DB에서 ID값을 가져와서 영속성 컨텍스트에 저장했기 때문에 메소드. $Obejct.getId()가 반환될 수 있었던 것이다.

 

 

 

 

 

 

댓글