본문 바로가기

dev/JPA

(11)
JPA Eager Lazy Loading JPA에서 즉시(Eager) 로딩과 지연(Lazy) 로딩이라는 기술을 지원하고 있습니다. 연관관계에 있는 엔티티를 조회하는 기술로 즉시 로딩은 엔티티를 조회할 때 해당 엔티티와 연관된 엔티티를 바로 조회하고 지연 로딩은 연관된 엔티티를 실제 사용할 때 조회합니다. 직원 엔티티가 직급 엔티티를 즉시 로딩하는 것으로 설정하고 직원 엔티티 조회했을 때 직급 엔티티가 바로 확인되는 것을 통해서 즉시 로딩된 것을 확인할 수 있습니다. 반대로 직원 엔티티가 직급 엔티티를 지연 로딩하는 것으로 설정하고 직원 엔티티를 조회했을 때 직급 엔티티가 프록시 객체인 것을 통해서 지연 로딩된 것을 확인할 수 있습니다. 지연 로딩은 프록시 객체를 통해 실제 데이터가 필요한 경우에 호출이 되기 때문에 유용하지만 연관된 엔티티를 계..
JPA QueryDSL Paging JPA에서 QueryDSL로 페이징 하는 것은 어렵지 않습니다. 예제 페이징 코드를 보게 되면 employee 엔티티를 페이징 조회하고 있습니다. employee 엔티티 아이디를 오름차순으로 정렬하고(86라인) pageNum으로 페이지 시작 위치를 설정하고(87라인) pageRow로 페이지 로우 수를 설정한 뒤 조회합니다.(88~89라인) 예제 페이징 코드를 DB 쿼리로 비유하면 select * from employee order by id asc offset pageNum limit pageRow 와 비슷하다고 할 수 있습니다. 해당 코드를 json으로 조회하면 정상적으로 결과를 확인할 수 있습니다.
JPA QueryDSL 집계 쿼리 JPA에서 QueryDSL로 집계 쿼리를 사용하는 방법입니다. 예제 집계 코드를 보게 되면 각 팀의 인원을 조회하고 있습니다. employee 엔티티와 team 엔티티를 join 하고(66라인) team 엔티티 id로 집계한 다음에(67라인) team 이름과 팀의 인원을 조회합니다.(64라인) 해당 조회 결과를 메타 클래스에 저장할 수 없기에 stream을 활용하여 TeamDto 클래스에 매핑한 뒤 저장합니다.(63, 69~74라인) 예제 집계 코드를 DB 쿼리로 비유하면 select team.id, count(*) from team join employee on team.id = employee.team_id group by team.id 와 비슷하다고 할 수 있습니다. 해당 코드를 json으로 조회했..
JPA Insert Batch JPA에서 batch를 사용하면 대량의 데이터를 효율적으로 추가할 수 있습니다. 예제 batch 코드를 보게 되면 데이터베이스에 저장할 batch 사이즈 변수 cnt를 선언합니다.(81라인) 여기서 설정한 값 5는 앞에서 생성한 employee 테이블의 기본키 sequence의 increment와 일치하기 위해서 5로 설정했습니다. 직원 DTO 리스트를 파라미터로 받아서 루프를 실행합니다.(83~104라인) 직원 DTO의 속성값들을 하나씩 읽어서 Employee 엔티티 객체에 저장합니다.(84~93라인) Employee 엔티티 객체를 영속성 컨텍스트에 저장하고 cnt를 1씩 증가합니다.(95라인) 5건마다 영속성 컨텍스트에 있는 데이터를 데이터베이스에 저장하고 초기화합니다.(98~101라인) 코드를 실행..
JPA ID SEQUENCE JPA에서 테이블 기본키가 sequence인 경우 매핑하는 방법입니다. 직원 엔티티 클래스의 기본키를 sequence로 매핑하기 위해서 @SequenceGenerator 어노테이션을 통해 sequence 생성기를 등록합니다.(26~31라인) name 속성은 엔티티에서 사용할 sequence 생성기 이름입니다. sequence 속성은 데이터베이스에 등록한 sequence 이름입니다. initialValue 속성은 sequence 초기값입니다. allocationSize 속성은 sequence 호출할 때마다 증가하는 숫자입니다. @GeneratedValue 어노테이션의 strategy 속성을 sequence로 설정하고, generator 속성에 앞에서 생성한 sequence 생성기 이름을 설정합니다.(35라..
JPA Infinite Recursion 예외 처리 JPA에서 양방향 참조인 엔티티를 조회해서 json으로 리턴하는 경우 다음과 같이 Infinite Recursion 예외가 발생할 수 있습니다. 로그 화면이 작아서 잘 안 보이지만 양방향 참조인 엔티티를 json으로 리턴할 때 무한 재귀 현상이 발생하고 있습니다. 현재 직원 엔티티와 팀 엔티티가 서로 참조하고 있습니다. 이 문제를 해결하기 위해서는 직원 엔티티에 @JsonBackReference 어노테이션을 추가하고 팀 엔티티에 @JsonManagedReference 어노테이션을 추가하면 됩니다. @JsonBackReference 어노테이션은 연관관계 주인 엔티티에 선언되고 직렬화에서 제외됩니다. @JsonManagedReference 어노테이션은 연관관계 주인이 아닌 엔티티에 선언되고 직렬화에 포함됩니..
Spring Boot JPA QueryDSL 스프링 부트에서 JPA를 사용할 때 복잡한 검색 쿼리를 작성하는 방법이 여러 가지가 있는데 그중에서 QueryDSL을 사용하는 방법입니다. pom.xml에 QueryDSL 라이브러리들을 추가합니다. QueryDSL 디펜던시 버전 정보를 확인합니다. 엔티티의 메타 모델 클래스를 생성하는 플러그인을 pom.xml에 추가합니다. mvn compile을 하면 outputDirectory에 메타 모델 클래스가 생성됩니다. 예제 코드를 보게 되면 직원 엔티티가 팀 엔티티와 직급 엔티티와 join 하고 employeeSearchParam의 아이디와 직원 엔티티의 아이디가 같은 데이터를 조회하고 있습니다. JPQL은 문자열 기반이어서 오타로 인해 예외가 발생할 수 있고 Creteria는 코드 기반이지만 코드가 복잡하다..
Spring Boot JPA ID IDENTITY 스프링 부트 JPA에서 테이블 기본키가 AUTO INCREMENT인 경우 매핑하는 방법입니다. PostgreSQL에서 예제로 만든 직급 테이블입니다. PostgreSQL에서 AUTO INCREMENT을 지원하는 타입은 serial입니다. serial 타입의 기본키를 매핑하려면 즉 기본키가 데이터베이스로부터 생성되는 경우라면 @GeneratedValue 어노테이션을 사용해야 합니다. @GeneratedValue 어노테이션의 strategy 속성값을 GenerationType.IDENTITY으로 해야 합니다. GenerationType.IDENTITY 전략은 데이터를 추가한 다음에 기본키 값을 알 수 있습니다. 직급 엔티티를 추가했을 때 기본키 생성이 제대로 되는지 확인하기 위해서 코드를 작성합니다. 컨트롤..