EntityManagerFactory
EntityManager
EntityManager entityManager = emf.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Customer customer = new Customer(); // 비영속상태
customer.setId(1L);
customer.setFirstName("firstName");
customer.setLastName("lastName");
entityManager.persist(customer); // 비영속 -> 영속 (영속화)
transaction.commit(); // entityManager.flush() 호출.
persist()메소드를 호출하여 customer객체를 영속화와 동시에 쓰기 지연 저장소에 INSERT쿼리 저장.
이후 transaction.commit으로 쓰기 지연 저장소의 INSERT쿼리가 실행되어 DB저장까지 이루어 진다.
entityManager.find(Customer.class, 1L);
위의 저장 코드가 실행된 이후, 영속성 콘텍스트 안에는 1L이라는 id를 갖는 customer가 1차 캐시 내부에서도 존재한다. 따라서 entityManger.find(~, 1L)을 호출하면 DB에서 조회하는 것이 아닌, 1차캐시에서 해당 엔티티를 조회한다. → 조회속도가 빨라지는 이점이 있다.
EntityManager entityManager = emf.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Customer customer = new Customer(); // 비영속상태
customer.setId(1L);
customer.setFirstName("firstName");
customer.setLastName("lastName");
entityManager.persist(customer); // 비영속 -> 영속 (영속화)
transaction.commit(); // entityManager.flush() 호출.
entityManger.clear(); // 영속성 콘텍스트를 비운다 -> 1차캐시도 비워진다.
Customer dbCustomer = entityManager.find(Cusotmer.class, 1L); // 1차캐시에 1L이라는 id를 갖는 엔티티가 없으므로, db까지 들어가서 조회한다.
EntityManager entityManager = emf.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Customer customer = new Customer(); // 비영속상태
customer.setId(1L);
customer.setFirstName("firstName");
customer.setLastName("lastName");
entityManager.persist(customer); // 비영속 -> 영속 (영속화)
transaction.commit(); // entityManager.flush() 호출.
--------------------------- // 하나의 트랜잭션 종료.
transaction.begin();
Customer cacheCustomer = entityManager.find(Cusotmer.class, 1L);
cacheCustomer.setFirstName("updatedFirstName");
transaction.commit();
하나의 customer를 만들고 저장을 할 때, 다시말해 처음 영속성 컨텍스트에 저장될 때, 스냅샷이라는 것이 생성된다.
이후 해당 엔티티를 조회하여 필드값을 바꾼 이후 commit을 한다.
이때 따로 update메소드를 호출하지 않아도, transaction이 커밋되는 시점(flush가 호출되는 시점)에 스냅샷과 커밋시점의 엔티티를 비교하여 변경된 내용이 있다면, 자동적으로 update Query가 수행된다. 이것을 dirty checking이라 하는데, 쉽게 말해 commit 시점에 상태 변화를 검사하는 것이다.
주의해야 할 점은, 상태 변화를 검사하는 대상은 영속 상태여야 한다.
비영속, 준영속은 dirty checking의 대상이 되지 못한다.
기본적으로 더티체킹에 의해 생성되는 update Query는 모든 필드를 업데이트 하는데, 변경된 필드만 업데이트 하고 싶을 경우에는 아래와 같이 엔티티 클래스에 DynamicUpdate 어노테이션을 붙여주면 된다.
@Entity
@Getter
@Setter
@NoArgsConstructor
@DynamicUpdate
@Table(name = "customers")
public class Customer {
@Id
private long id;
private String firstName;
private String lastName;
.
.
.
EntityManager entityManager = emf.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Customer customer = new Customer();
customer.setId(1L);
customer.setFirstName("FirstName");
customer.setLastName("LastName");
em.persist(customer);
transaction.commit();
transaction.begin();
Customer entity = em.find(Customer.class, 1L);
em.remove(entity);
transaction.commit(); // flush -> DELETE ..
entityManager의 remove()메소드를 호출하여 영속성 컨텍스트에서 제거한 이후, 쓰기 지연 저장소에 DELETE문을 저장. → 이후 커밋 시 해당 쿼리 수행된다.