JPA

반응형
· JPA
엔티티의 동등성 비교 영속성 컨텍스트 내부에는 엔티티 인스턴스를 보관하기 위한 1차 캐시가 있다. 이 1차 캐시는 영속성 컨텍스트와 생명주기를 같이 한다. 영속성 컨텍스트를 통해 데이터를 저장하거나 조회하면 1차 캐시에 엔티티가 저장된다. 이 1차 캐시 덕분에 변경 감지 기능도 동작하고, 이름 그대로 1차 캐시로 사용되서어 데이터베이스를 통하지 않고 데이터를 바로 조회할 수도 있다. 영속성 컨텍스트를 더 정확히 이해하기 위해서는 1차 캐시의 가장 큰 장점인 애플리케이션 수준의 반복 가능한 읽기를 이해해야 한다. 같은 영속성 컨텍스트에서 엔티티를 조회하면 다음 코드와 같이 항상 같은 엔티티 인스턴스를 반환한다. 단순이 동등성 비교 수준이 아니라 정말 주소값이 같은 인스턴스를 반환한다. Member memb..
· JPA
JPA 표준 예외 정리 JPA 표준 예외들은 javax.persistence.PersistenceException의 자식 클래스다. 그리고 이 예외 클래스는 RuntimeException의 자식이다. 따라서 JPA 예외는 모두 언체크 예외다. JPA 표준 예외는 크게 2가지로 나눌 수 있다. 트랜잭션 롤백을 표시하는 예외 트랜잭션 롤백을 표시하지 않는 예외 트랜잭션 롤백을 표시하는 예외는 심각한 예외이므로 복구해선 안 된다. 이 예외가 발생하면 트랜잭션을 강제로 커밋해도 트랜잭션이 커밋되지 않고 대신에 javax.persistence.RollbackException 예외가 발생한다. 반면에 트랜잭션 롤백을 표시하지 않는 예외는 심각한 예외가 아니다. 따라서 개발자가 트랜잭션을 커밋할지 롤백할지를 판단하면..
· JPA
엔티티 그래프란? 엔티티를 조회할 때 연관된 엔티티들을 함께 조회하려면 글로벌 fetch 옵션을 FetchType.EAGER로 설정하거나 OneToMnay 관계에 경우는 JPQL에서 페치 조인을 사용하면 된다. 글로벌 fetch 옵션은 애플리케이션 전체에 영향을 주고 변경할 수 없는 단점이 있기 때문에 보통 LAZY를 사용하고, 엔티티를 조회할 때 연관된 엔티티를 함께 조회할 필요가 있으면 JPQL의 페치 조인을 사용한다. 그러나 JPQL을 사용할때는 다른곳에서 요청하는 데이터에 맞게 여러개를 생성해야 한다. 모두 같은 엔티티를 조회하지만 sql이 모두 다른 경우가 많을 경우 너무 많은 메소드를 생성해야 한다. JPA 2.1에 추가된 엔티티 그래프 기능을 사용하면 엔티티를 조회하는 시점에 함께 조죄할 연..
· JPA
모든 엔티티를 대상으로 언제 어떤 사용자가 삭제를 요청했는지 모두 로그를 남겨야 하는 요구사항이 있다고 가정하자. 이때 애플리케이션 삭제 로직을 하나씩 찾아서 로그를 남기는 것은 너무 비효율적이다. JPA 리스너 기능을 사용하면 엔티티의 생명주기에 따른 이벤트를 처리할 수 있다. 이벤트 종류 PostLoad 엔티티가 영속성 컨텍스트에 조회된 직후 또는 refresh를 호출한 후(2차 캐시에 저장되어 있어도 호출된다) PrePersist persist() 메소드를 호출해서 엔티티를 영속성 컨텍스트에 관리하기 직전에 호출된다. 식별자 생성 전략을 사용한 경우 엔티티에 식별자는 아직 존재하지 않는다. 새로운 인스턴스를 merge 할 때도 수행된다. PreUpdate flush나 commit을 호출해서 엔티티를..
· JPA
컨버터를 사용하면 엔티티의 데이터를 변환해서 데이터베이스에 저장할 수 있다. 예를 들어 회원의 VIP여부를 데이터베이스에는 "Y", "N"으로 저장하고 엔티티에서는 boolean 타입으로 변환해서 사용할 수 있다. @Entity public class Member { ... @Convert(converter = VipConverter.class) private boolean isVip; } @Converter public class VipConverter implements AttributeConverter { // 엔티티의 데이터를 데이터베이스 컬럼에 저장할 데이터로 변환 @Override public String convertToDatabaseColumn(Boolean attribute) { retu..
· JPA
스프링은 컨테이너는 트랜잭션 범위의 영속성 콘텍스트 전략을 기본으로 사용한다. 트랜잭션이 같으면 같은 영속성 콘텍스트가 콘텍스트가 공유되고 트랜잭션이 끝나면 영속성 콘텍스트가 닫히는 것이다. 그럼 트랜잭션이 끝나고 엔티티에 지연 로딩으로 연결된 다른 엔티티를 불러오면 어떻게 될까? 보통 트랜잭션은 비즈니스 로직이 있는 서비스단에서 시작하고 종료한다. public class Member { ... @ManyToOne(fetch = FetchType.LAZY); private Team team; } Member member = memberService.getMember(1); // 트랜잭션 종료, 준영속 상태 member.getTeam(); // 종료 후 지연로딩으로 연결된 team 정보 조회 당연히 영속성..
· JPA
순수하게 J2SE 환경에서 JPA를 사용하면 개발자가 직접 엔티티 매니저를 생성하고 트랜잭션도 관리해야 한다. 하지만 스트링이나 J2EE 컨테이너 환경에서 JPA를 사용하면 컨테이너가 제공하는 전략을 따라야 한다. 스프링 컨테이너의 기본 전략 스프링 컨테이너는 트랜잭션 범위의 영속성 컨텍스트 전략을 기본으로 사용한다. 이 전략은 이름 그대로 트랜잭션의 범위와 영속성 컨텍스트의 생존 범위가 같다는 뜻이다. 트랜잭션을 시작할 때 영속성 컨텍스트를 생성하고 트랜잭션이 끝날 때 영속성 컨텍스트를 종료한다. 그리고 같은 트랜잭션 안에서는 항상 같은 영속성 컨텍스트에 접근한다. 스프링 프레임워크를 사용하면 보통 비즈니스 로직을 시작하는 서비스 계층에 @Transactional 어노테이션을 선언해서 트랜잭션을 시작한..
· JPA
Spring Data JPA는 org.springframework.data.jpa.domain.Specification 클래스로 다양한 검색조건을을 조립해서 새로운 검색조건을 만들 수 있다. 본래에 JpaRepository 상속받을때 JpaSpecificationExecutor을 상속받으면 된다. public interface JpaSpecificationExecutor { T findOn(Specification spec); List findAll(Specification spec); Page findAll(Specification spec, Pageable pagaable); List findAll(Specification spec, Sort sort); long count(Specification ..
· JPA
Spring Data JPA Spring Data JPA는 Spring Data 프로젝트 하위 프로젝트 중 하나다. Spring Data 프로젝트는 JPA, 몽고 DB, NEO4J, REDIS, HADOOP, GEMFIRE 같은 다양한 데이터 저장소에 대한 접근을 추상화해서 개발자 평의를 제공하고 지루하게 반복하는 데이터 접근 코드를 줄여둔다. Spring Data JPA는 스프링 프레임워크에서 JPA를 편리하게 사용할 수 있도록 지원하는 프로젝트다. Spring Data JPA는 애플리케이션을 실행할 때 basePackage에 있는 리포지토리 인터페이스들을 찾아서 해당 인터페이스를 구현한 클래스를 동적으로 생성한 다음 스프링 빈으로 등록한다. 그래서 JpaRepository만 상속받고 구현체를 구현하지..
· JPA
객체지향 쿼리와 관련된 다양한 고급 주제를 알아보자. 벌크 연산 엔티티를 수정하려면 영속성 콘텍스트의 변경 감지 기능이나 병합을 사용하고, 삭제하려면 EntityManager.remove() 메서드를 사용한다. 하지만 이 밥벙으로 수백 개 이상의 엔티티를 하나씩 처리하기에는 시간이 너무 오래 걸린다. 이때 여러 건을 한 번에 수정하거나 삭제하는 벌크 연산을 사용하면 된다. // 재고가 10개 미만인 상품의 가격을 10% 상승 String sql = "UPDATE product p SET p.price = p.price * 1.1 WHERE p.stockAmount < :stockAmount"; int resultCount = em.createQuery(sql).setParameter("stockAmoun..
반응형
Beekei
'JPA' 카테고리의 글 목록 (2 Page)