JPA

    프록시 객체와 영속성 컨텍스트

    프록시 객체와 영속성 컨텍스트 JPA 의 프록시 객체가 어떻게 초기화 되고, getReference() 를 사용할 때, 영속성 컨텍스트에 값이 존재하는 경우와 하지 않는 경우에는 어떻게 동작하는지 배워보자. em.find vs em.getReference em.find // em.find() 시점에 조회 쿼리가 나간다. // findMember : Member@9361 Member findMember = em.find(Member.class, member.getId()); System.out.println("username : " + findMember.getUsername()); System.out.println("id : " + findMember.getId()); 아래는 조회 쿼리이다. select..

    다양한 연관관계 매핑과 설정에 따른 트레이드 오프

    연관관계 방향 설정에 따른 트레이드 오프 연관관계 매핑 다양한 연관관계 매핑이 존재하며, 실무에서 어떤 연관관계 매핑을 사용할 것인지에 따라서 객체의 설계가 달라진다. 다대일(N:1) 다대일(N:1) 연관관계 매핑은, @ManyToOne 을 사용하는 곳을 연관관계 주인으로 설정하는 것을 말한다. 실무에서 가장 자주 사용되고 추천하는 방식이라고 한다. 이 방식의 장점은 객체의 형태를 최대한 관계형 데이터베이스와 유사하게 가져가기 때문에 유지보수성이 좋다는 점이다. 단점은, Member 에서 Team 으로 참조할 일이 없더라도 다대일 연관관계 매핑을 사용하기 위해서, 참조 변수를 두는 점이다. 객체지향적으로 조금 손해 보더라도, 객체를 관계형 데이터베이스와 유사하게 가져갔을 때의 장점이 더 크기 때문에 실무..

    테이블과 컬럼에 대한 명세를 엔티티에 자세하게 적는것이 좋은지?

    테이블과 컬럼에 대한 명세를 엔티티에 자세하게 적는것이 좋은지? 테이블과 컬럼에 대한 명세를 엔티티에 자세하게 적는것이 좋은지, 아니면 @Column 같은 애노테이션은 생략해도(생략 가능할 경우) 좋은지에 대한 개인적인 의견이 들어간 글입니다. 테이블과 컬럼에 대한 명세를 엔티티에 자세하게 적는것이 좋다고 생각 그 이유는 엔티티에 테이블 및 컬럼에 대한 명세를 자세하게 적으면, 데이터베이스의 테이블 명세를 직접 까보지 않아도(Ex. DBeaver 에 들어가서 테이블을 열어서 명세 확인) 엔티티단에서 바로 확인할 수 있다는 장점이 있기 때문입니다. 자세하게 적는다 : 엔티티를 보고 테이블 명세를 정확하게 파악할 수 있어야 하는 정도 MyBatis 를 사용해보신 분들은 알겠지만, SI 에서 VO, DTO 와..

    AllocationSize 를 통한 성능 최적화

    AllocationSize 를 통한 성능 최적화 TABLE 이나 SEQUENCE 전략을 사용할 때, @SequenceGenerator 에 allocationsize 옵션을 설정하여 INSERT 에 관한 성능 최적화를 할 수 있다. allocationsize 의 기본값은 50인데 왜 50으로 설정이 되었을지 테스트를 통해서 배워보자. Test @SequenceGenerator( name = "MEMBER_SEQ_GENERATOR", sequenceName = "MEMBER_SEQ", initialValue = 1, allocationSize = 50) @NoArgsConstructor @Getter @Setter @Entity public class Member { @Id @GeneratedValue(st..

    기본키 매핑 전략에 따른 INSERT QUERY 실행 시점

    기본키 매핑 전략에 따른 INSERT QUERY 실행 시점 JPA 의 기본키 생성 전략 중, IDENTITY 와 SEQUENCE 전략을 사용할 때, 실제 언제 INSERT QUERY 가 나가고 어떻게 영속성 엔티티에 들어가서 관리되는지 확인해보자. IDENTITY @DisplayName("IDENTITY 전략 테스트") @SpringBootTest class IdentityStrategyTest { @Value("${persistence.unitname}") private String persistenceUnitName; @DisplayName("em.persist() 시 INSERT 쿼리가 나가는지 테스트") @Test void insertQueryIsWorkAtPersist() throws Excep..

    EntityManager 를 쓰레드간 공유하면 안되는 이유

    EntityManager 를 쓰레드간 공유하면 안되는 이유 EntityManager 를 쓰레드간 공유하면 안되는 이유에 대해서 배워보자. Test 테스트할 주제는 EntityManager 를 하나로 사용하고 있는 상태에서 서로 다른 Thread 두 개를 생성하고 ThreadA 는 데이터베이스에서 데이터를 읽어와 1차 캐시에 저장하는 역할을 하고, ThreadB 에서는 데이터 조회와, 데이터 수정 작업을 담당하게끔 코드를 짜서 테스트할 것이다. 포인트는 ThreadB 에서 데이터를 읽어올 때, 1차 캐시에 존재하는 데이터를 읽어올지, 데이터베이스로부터 값을 조회해올지가 포인트다. @DisplayName("1차 캐시 테스트") @SpringBootTest class FirstCacheTest { @Value..

    JPA 는 과연 1차 캐시를 통해서 Repeatable Read 를 지원할까?

    JPA 는 과연 1차 캐시를 통해서 Repeatable Read 를 애플리케이션 레벨에서 지원할까 ? 이번 주제는 JPA 는 과연 1차 캐시를 통해서 Repeatable Read 를 애플리케이션 레벨에서 지원하는지에 대해 테스트한 결과를 정리한 내용이다. Repeatable Read Repeatable Read 는 트랜잭션 고립 레벨2(Transaction Isolation Level)에 속한다. MySQL InnoDB 에서 기본으로 채택하고 있는 격리 수준 선행 트랜잭션이 읽은 데이터는 트랜잭션이 종료될 때가지 후행 트랜잭션이 갱신하거나 삭제하는 것은 불허함으로써 같은 데이터를 두 번 쿼리했을 때 일관성 있는 결과를 리턴 Insert 는 가능 Phantom Read 현상은 여전히 발생 위와 같은 특징을..