전체 글

전체 글

    JPA 캐시

    캐시 기본적으로 영속성 컨텍스트를 1차 캐시라고 한다. 애플리케이션 범위의 2차 캐시가 있다.(공유캐시) 영속성 컨텍스트에 존재하지 않으면 2차 캐시를 조회한다. 2차캐시에도 엔티티가 없으면 데이터베이스를 조회해서 2차 캐시에 보관한다. 2차 캐시는 자신이 보관하고 있는 엔티티를 복사해서 반환한다. 2차캐시에서 얻어온 객체는 영속성 컨텍스트가 다르면 동일성(a==b)를 보장하지 않는다. @Cacheable @Entity public class Member { .... } 애플리케이션 전체에 캐시를 어떻게 적용할지 shared-cache-mode 를 설정 해줘야 한다. (EntityManagerFactory) SharedCacheMode 설정 종류 ALL: 모든 엔티티를 캐시한다. NONE: 캐시를 사용하..

    JPA 락 처리

    락 제어 트랜잭션 격리수준 4가지 READ UNCOMMITTED = DIRTY READ, NON-REPEATABLE READ, PHANTOM READ 발생 READ COMMITTED = NON-REPEATABLE READ, PHANTOM READ 발생 REPEATABLE READ = PHANTOM READ 발생 SERIALIZABLE DIRTY_READ : 트랜잭션 1이 수정중이고, 커밋하지 않은 데이터를 트랙잭션2가 조회 가능한 것 NON-REPEATABLE READ: 트랜잭션 1이 A를 조회하고, 다른작업을 진행중에 트랜잭션 2가 A를 수정하여, 트랜잭션1이 다른작업 후 다시 A를 조회했을때 다른 테이터가 조회되는 것. PHANTOM_READ: 트랜잭션 1이 10살 이하 회원을 조회 하였을때 카운트가..

    JPA 성능 최적화

    JPA 성능최적화 N+1 문제 fetchType 이 Eager 로 설정 되어 있는 엔티티를 jpql로 조회할때 발생한다. @Entity public class Member { ... @OneToMany(mappedBy = "member", fetch = FetchType.EAGER) private List orders = new ArrayList(); } ... List members = em.createQuery("select m from Member m", Member.class) .getResultList(); //먼저 Member 들을 조회하는 쿼리를 수행 후 엔티티에 할당하는데 //할당하는 동중에 FetchType.Eager 를 발견하게 되고, 각 MemberId마다 Order조회 쿼리를 수행한..

    JPA 엔티티 그래프

    엔티티 그래프 엔티티 조회시점에 연관된 엔티티들을 함께 조회하는 기능이다. Named 엔티티 그래프 //둘 이상 정의하려면 @NamedEntityGraphs 사용. @NamedEntityGraph(name = "Order.withMember", attribueNodes = { @NamedAttributeNode("member") }) @Entity public class Order { .... @ManyToOne(fetch = FetchType.LAZY, optional = false) @JoinColumn(name = "MEMBER_ID") private Member member; ... } 사용 EntityGraph graph = em.getEntityGraph("Order.withMember"); ..

    JPA 엔티티 생명주기에 리스너 등록

    엔티티 생명주기에 리스너 등록하기 생명주기 종류 : prePersist, postPersist, postLoad, preRemove, postRemove.. 방법 엔티티에 직접 적용 @Entity public class Duck { @PrePersist public void prePersist(Duck duck) { log.info("prepersist"); } @PostPersist public void postPersist() { log.info("postpersist"); } .... } 별도의 리스너 등록 public class DuckListener { @PrePersist private void prePersist(Object obj) { log.info("prePersist"); } } @E..

    JPA Entity와 DB값 간 매핑

    Entity 값과 DB값 간 매핑 엔티티의 boolean 값을 DB에 저장시에는 Y, N 값으로 저장하고 싶을때 등 사용. @Entity public class aaa { ... @Convert(converter=BooleanToYnConverter.class) private boolean isExist; } @Converter //@Converter(autoApply = true) autoApply를 true로 설정하면 //모든 AttributeConverter로 설정한 타입 값을 가진 엔티티 필드 타입에 자동 적용된다. public class BooleanToYnConverter implements AttributeConverter { @Override public String convertToDat..

    JPA 지연로딩

    JPA 지연로딩 문제 jpa를 이용해서 엔티티의 연관 객체를 지연로딩(fetch = FetchType.LAZY)로 선택한 경우, 트랜잭션 범위 밖에서 로딩되지 않은 객체를 조회할 경우 exception 이 발생한다. 위 방법을 해결하기 위한 방법을 알아보자. 즉시로딩 설정 FetchType.EAGER 로 설정하면 즉시 로딩 전략으로 트랜젝션 밖인 프레젠테이션 계층 등에서 조회시 문제가 발생하지 않는다. 즉시로딩이지만, 사용하지 않는 프레젠테이션 계층에선 필요없는 데이터까지 조회하게 된다. em.find()를 이용하는 경우 문제가 발생하지 않지만, jpql을 사용하는 경우 N+1 문제가 발생한다. jpql을 이용해 select m from Member m 을 실행하면 Member만 가져온후, Member수..

    JPA @ManyToMany

    객체간 다대다 연관간계를 직접 매핑할 때 사용한다. 당연하지만 RDB 에는 직접 다대다 연관관계를 지정할 수 없기 때문에 중간 연결테이블이 있다. @Entity public class Category { @ManyToMany @JoinTable(name = "CATEGORY_ITEM", joinColumns = @JoinColumn(name = "CATEGORY_ID"), inverseJoinColumns = @JoinColumn(name = "ITEM_ID)) private List items = new ArrayList(); } @Entity public class Item { @ManyToMany(mappedBy = "items") private List categories = new ArrayLi..

    JPA @Inheritance

    @Inheritance JPA 를 사용하여 Entity를 정의할 때 상속구조를 사용하기 위해 선언한다. ex) @Entity @Inheritance(strategy = InheritanceType.SINGLE\_TABLE) @DiscriminatorColumn(name = "DTYPE") public abstract class Item { @GeneratedValue private long id; ...... } @Entity @DiscriminatorValue("B") public class Book extends Item { private String author; ..... } @Inheritance annotation 으로 상속하여 사용하는 부모 객체임을 선언한다. InheritanceType 종..

    JPA CASCADE 종류

    CascadeType.RESIST – 엔티티를 생성하고, 연관 엔티티를 추가하였을 때 persist() 를 수행하면 연관 엔티티도 함께 persist()가 수행된다. 만약 연관 엔티티가 DB에 등록된 키값을 가지고 있다면 detached entity passed to persist Exception이 발생한다. CascadeType.MERGE – 트랜잭션이 종료되고 detach 상태에서 연관 엔티티를 추가하거나 변경된 이후에 부모 엔티티가 merge()를 수행하게 되면 변경사항이 적용된다.(연관 엔티티의 추가 및 수정 모두 반영됨) CascadeType.REMOVE – 삭제 시 연관된 엔티티도 같이 삭제됨 CascadeType.DETACH – 부모 엔티티가 detach()를 수행하게 되면, 연관된 엔티티..