본문 바로가기
  • 실행력이 모든걸 결정한다
반응형

Spring 사전 준비52

[JPA] LazyInitializationException: could not initialize proxy 해결 지연 로딩으로 설정된 필드는 실제로 사용되는 시점에 로딩되는데, 영속성 컨텍스트에서 관리되지 않는 영역에서 사용될 때는 지연 로딩을 할 수 없기 때문에 LazyInitializationException 예외가 발생하는 것이다. 즉, 트랜잭션 영역 안에서 지연 로딩이 이루어지도록 하면 이 예외는 발생하지 않을 것이다. Hibernate.initialize() 메소드를 사용하면 지연 로딩으로 설정된 필드값을 강제로 로딩시킬 수 있다. User 엔티티에 있는 progress 필드를 강제 로딩 시킨다고 해보자. public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 기본 키 생성을 데이터베이스에 위임 private long i.. 2022. 12. 28.
[JPA] 2차 캐시 1. 캐시의 사용 이유 - 네크워크(외부 DB) 호출은 애플리케이션 서버의 내부 메모리에 접근하는 것보다 시간 비용이 훨씬 비싸기 때문에 캐시를 이용하는 것이 성능에 좋다. 2. 1차 캐시와 2차 캐시 1) 1차 캐시 - 1차 캐시는 영속성 컨텍스트 내부에 있는 캐시다. - 일반적으로 트랜잭션과 수명이 같고, OSIV를 키더라도 요청이 끝날 때까지만 유효하다. - 애플리케이션 전체로 보면 DB 접근 횟수를 획기적으로 줄이지는 못한다. 2) 2차 캐시 - 대부분의 JPA 구현체들이 지원하는 애플리케이션 범위의 캐시로, 공유 캐시라고도 한다. - 애플리케이션을 종료할 때까지 캐시가 유지된다. - 1차 캐시에 비해 DB 접근 횟수를 획기적으로 줄일 수 있기 때문에 성능을 더욱 더 향상시킬 수 있다. 동작 원리.. 2022. 8. 30.
[JPA] 트랜잭션과 Lock 1. 격리 수준 - 동시에 실행되는 트랜잭션들이 서로에게 영향을 미치지 않도록 설정하는 격리의 정도 - @Transactional 어노테이션으로 격리 수준을 지정할 수 있으며, 격리 수준의 종류는 아래 포스팅의 [2. isolation]에서 확인할 수 있다. https://kimcoder.tistory.com/477 [Spring] @Transactional의 속성 @Transactional은 Fallback 정책을 통해서 특정 트랜잭션 속성을 적용할 대상을 매우 유연하게 선정할 수 있도록 하는 어노테이션이다. Fallback 정책은 @Transactional 어노테이션의 작성 위치에 따른 설정 kimcoder.tistory.com - 보통 격리수준으로 READ COMMITTED을 기본으로 사용한다. -.. 2022. 8. 29.
[JPA] 성능 최적화 1. N+1 문제 1) N+1 문제란? - 처음 실행한 결과 수만큼 추가적인 SQL이 실행되어 성능에 안좋은 영향을 미치는 문제를 뜻한다. - 즉시 로딩과 지연 로딩일 때 모두 발생할 수 있다. 2) N+1 문제 해결 방법 (1) 페치 조인 - SQL 조인을 사용해서 연관된 엔티티를 함께 조회하는 방법이다. - 사용 방법은 https://kimcoder.tistory.com/493의 [2-7) JOIN FETCH]를 참고하자. (2) @BatchSize - org.hibernate.annotations.BatchSize 어노테이션을 적용해서 배치를 사용하는 방법이다. - 연관된 엔티티를 조회할 때 지정한 크기만큼 SQL의 IN절을 사용해서 조회한다. 만약 조회 건수가 100이고 배치 크기가 20이라면 총.. 2022. 8. 27.
[JPA] JPA 예외 처리 1. JPA 표준 예외 - JPA 예외는 모두 언체크 예외다. - JPA 표준 예외는 예외의 심각 정도에 따라 롤백이 필수가 될 수도 있고 선택이 될 수도 있다. 1) 반드시 롤백해야 하는 예외 - 트랜잭션을 강제로 커밋해도 javax.persistence.RollbackException 예외가 발생한다. javax.persistence.EntityExistsException : EntityManager.persist() 호출 시 이미 같은 엔티티가 존재할 경우 javax.persistence.EntityNotFoundException : 엔티티가 존재하지 않는 경우 javax.persistence.OptimisticLockException : 낙관적 락 충돌 시 javax.persistence.Pess.. 2022. 8. 25.
[JPA] 엔티티 그래프 1. 엔티티 그래프 소개 - JPA 2.1에 추가된 기능으로, 객체 지향 쿼리를 사용하지 않고도 엔티티를 조회하는 시점에 함께 조회할 연관된 엔티티를 선택할 수 있다. - 엔티티 그래프는 항상 조회하는 엔티티의 루트에서 시작해야 한다. - 글로벌 fetch 전략보다 우선 순위가 높다. - 영속성 컨텍스트에 이미 로딩되어 있는 엔티티에 대해서는 엔티티 그래프가 적용되지 않는다. 아직 초기화되지 않은 프록시에는 엔티티 그래프가 적용된다. - 엔티티 그래프는 정적으로 정의하는 Named 엔티티 그래프와 동적으로 정의하는 엔티티 그래프가 있다. 2. Named 엔티티 그래프 1) Named 엔티티 그래프 정의 - @NamedEntityGraph 어노테이션으로 정의한다. name 속성에는 엔티티 그래프의 이름을 .. 2022. 8. 25.
[JPA] JPA 리스너 - 엔티티의 생명주기에 따른 이벤트를 처리할 수 있는 기능이다. 1. 생명 주기에 따른 이벤트 1) PostLoad : DB로부터 엔티티가 영속성 컨텍스트에 조회된 직후 또는 refresh() 호출 직후 2) PrePersist : persist() 메소드를 호출하거나 새로운 인스턴스를 merge해서 엔티티를 영속성 컨텍스트에 저장하기 직전 3) PreUpdate : flush()를 호출해서 엔티티를 DB에 수정하기 직전 4) PreRemove : remove()를 호출해서 엔티티가 영속성 컨텍스트에서 삭제되기 직전 5) PostPersist : flush()를 호출해서 엔티티를 DB에 삽입한 직후 ※ 식별자 생성 전략이 IDENTITY면 persist()를 호출한 직후에 호출됨. 자세한 내용은 http.. 2022. 8. 24.
[JPA] Entity와 Table간의 데이터 타입 변환 Entity와 Table을 매핑할 때 서로 다른 데이터 타입으로 매핑하고 싶다면 어떻게 할까? 이러한 고민을 해결해주는 AttributeConverter을 설명한 뒤에 예제를 통해 적용 방법을 이해해보자. 1. AttributeConverter 인터페이스 public interface AttributeConverter { public Y convertToDatabaseColumn(X attribute); public X convertToEntityAttribute(Y dbData); } - X에는 엔티티의 필드 타입, Y에는 테이블의 컬럼 타입이 들어간다. - convertToDatabaseColumn() 메소드에는 엔티티의 필드를 테이블의 컬럼으로 변환하는 방법을 구현하면 되고, convertToEnt.. 2022. 8. 24.
[JPA] JPA와 컬렉션 1. 래퍼 컬렉션 - 원본 컬렉션을 감싸고 있는 내장 컬렉션을 래퍼 컬렉션이라고 부른다. - Hibernate에서 엔티티를 영속 상태로 만들면 그 안에 있는 컬렉션 타입은 래퍼 컬렉션 타입으로 변경된다. ※ org.hibernate.collection.internal.* 2. Collection, List 타입 - 엔티티가 영속 상태가 되면 org.hibernate.collection.internal.PersistenceBag 타입으로 변환된다. - 중복을 허용하고 순서를 보장하지 않는다. - 아래와 같이 ArrayList 타입으로 초기화해서 사용하면 된다. @OneToMany @JoinColumn private Collection members = new ArrayList(); ※ 위와 같은 일대다 단.. 2022. 8. 24.