Spring/JPA
[JPA] OSIV
[JPA] OSIV
2022.12.31Open Session In View의 약자이다. JPA가 영속성 컨텍스트를 관리하기 위해서는 먼저 데이터베이스 커넥션을 획득해야한다. 데이터베이스의 트랜잭션이 시작될 때 JPA의 영속성 컨텍스트가 데이터베이스 커넥션을 획득하는데.. 언제 반환하는걸까? OSIV가 켜져 있는 경우 최초의 데이터베이스 커넥션을 획득하고 API의 응답이 끝날 때 까지 영속성 컨텍스트와 데이터베이스 커넥션을 유지한다. 즉, 트랜잭션이 끝나도 데이터베이스 커넥션을 반환하지 않는다. 지연 로딩은 영속성 컨텍스트가 살아있어야 가능하고, 영속성 컨텍스트는 데이터베이스 커넥션이 있어야 관리된다. 따라서 OSIV가 켜져 있으면 지연 로딩이 가능하다. 그런데... 데이터베이스 커넥션을 계속 들고 있으면 사용자가 많은 애플리케이션인 경우 데..
[JPA] JPQL (2)
[JPA] JPQL (2)
2022.12.28경로 표현식 점을 찍어 상태에 접근하는 방법을 객체 그래프 탐색이라고 부른다. 객체 그래프 탐색으로 필드에 접근하는 요소에 따라 상태 필드 / 단일 값 연관 필드 / 컬렉션 값 연관 필드로 구분된다. 상태 필드는 단순히 값을 저장하기 위한 필드를 의미한다. 연관 필드는 연관관계를 위한 필드로, 엔티티 또는 컬렉션을 대상으로 하는 탐색을 의미한다. 상태 필드는 경로 탐색의 끝으로, 더 이상 탐색할 수 없다. (chaining 불가능) 단일 값 연관 필드로 탐색을 수행하면 묵시적 내부 조인이 발생한다. 따라서 쿼리 튜닝이 어려우니.. 조심해서 사용해야 한다. 컬렉션 값 연관 필드로 탐색 수행 시 더 이상 탐색할 수 없다. 경로 탐색의 끝이 아님에도 탐색이 불가능하니, 꼭 탐색이 필요한 경우 FROM 문법으로..
[JPA] JPQL (1)
[JPA] JPQL (1)
2022.12.27JPA를 사용하면 기본적인 SQL은 알아서 작성되기 때문에 개발할 때 매우 편하다. 하지만 복잡한 SQL은 개발자가 직접 작성해야 하는데, sql을 작성하는 기술 중 하나가 JPQL이다. JPA는 엔티티 객체를 중심으로 개발하기 때문에 검색 시에도 테이블 대신 엔티티 객체를 대상으로 검색할 수 있어야 한다. 데이터베이스에 있는 모든 데이터를 객체로 변환하는 방법은 너무 비효율적이다. 어쩔 수 없이 SQL이 사용된다. JPA는 SQL을 추상화한 언어인 JPQL이라는 객체지향 쿼리 언어를 제공한다. 문법은 SQL과 유사하지만 JPQL은 객체를 대상으로 쿼리를 날리고 SQL은 데이터베이스 테이블을 대상으로 쿼리를 날린다는 차이점이 있다. JPQL을 실행하면 해당 JPQL을 분석해서 적절한 SQL을 만들어 데이..
[JPA] 값 타입
[JPA] 값 타입
2022.12.26값 타입은 복잡한 객체를 단순화하기 위해 도입된 개념이다. JPA는 데이터 타입을 두 가지로 분류한다. 1. Entity @Entity 애너테이션으로 지정하는 객체를 의미하고, 데이터가 변해도 식별자로 추적할 수 있다. PK를 사용해 데이터를 찾고 데이터를 추적할 수 있다고 생각하면 된다. 2. 값 타입 자바의 Primitive 타입과 객체를 의미한다. 식별자가 없으니 값이 변경돼도 추적할 수 없고, 생명 주기를 엔티티에 의존한다. 값 타입은 다시 세 가지로 분류된다. 기본 값 타입 : Primitive 타입과 래퍼클래스, String을 의미한다. 임베디드 타입 : 사용자가 임의로 만든 객체를 의미한다. 컬렉션 값 타입 : ArrayList처럼 기본 값 또는 임베디드 타입을 넣어서 사용하는 객체를 의미한..
[JPA] 영속성의 전이와 고아 객체
[JPA] 영속성의 전이와 고아 객체
2022.12.24부모 엔티티를 영속 상태로 만들때 자식 엔티티도 함께 영속 상태로 만드는 등 특정 엔티티를 영속 상태로 만들때 연관된 엔티티도 함께 영속 상태로 만드는 작업을 영속성의 전이라고 한다. @OneToMany 애너테이션에 cascade 속성을 CascadeType.ALL으로 설정하면 영속성의 전이를 사용할 수 있다. 연관관계의 매핑과는 아무런 상관 없고 그냥 엔티티를 영속화할 때 관련된 엔티티를 함께 영속화할 수 있어 좀 더 편하게 개발할 수 있다는 의미를 가진다. 해당 엔티티가 단일 엔티티에 종속적인 경우 사용하면 좋지만, 엔티티가 복잡하게 엮여있는 경우 의도하지 않은 결과가 발생할 수 있으니 조심해서 사용하자. 영속성의 전이와 비슷한 개념으로 고아 객체 개념이 있다. 부모 엔티티와 연관관계가 끊어진 자식 ..
[JPA] 프록시와 연관관계
[JPA] 프록시와 연관관계
2022.12.24em.find 메서드를 사용하면 데이터베이스를 통해 실제 엔티티 객체를 조회하고, em.getReference 메서드를 사용하면 데이터베이스 조회를 미루는 프록시 엔티티를 조회한다. 여기서 프록시는 실제 엔티티 클래스를 상속받아서 만들어지고, 실제 클래스와 겉으로 보기에는 차이가 없다. 프록시에는 클래스의 값인 id와 name은 없지만 클래스를 가리키는 target을 가진다. getId() 또는 getName() 메서드가 프록시에 호출되면 target에 있는 getId()나 getName() 을 대신 호출하는 방식으로 동작한다. getReference 메서드를 사용하면 member의 프록시를 가져온다. 그 후 getName() 메서드를 호출하는데, 아직 target은 초기화되지 않아 실제 Entity를 ..
[JPA] 상속관계 매핑
[JPA] 상속관계 매핑
2022.12.23객체에는 상속관계가 있지만 관계형 데이터베이스에는 상속 개념이 없다. 대신 슈퍼타입과 서브타입이라는 개념이 상속과 유사하고 상속과 유사하게 사용할 수 있다. 위와 같은 데이터베이스 논리 모델을 물리 모델으로 구현할 때 사용하는 전략으로는 세 가지가 있다. 1. Join Item Album Movie Book 테이블을 각각 만들고 join으로 데이터베이스를 구성하는 방식이다. insert를 두 번 하고 조회는 PK FK를 통해 join해서 조회한다. 상속하는 클래스에 @Entity 애너테이션과 함께 @Inheritance(strategy = InheritanceType.JOINED) 애너테이션을 사용해서 구현한다. DTYPE으로 테이블을 구별할 때는 @DiscriminatorColumn 애너테이션을 사용한..
[JPA] 다양한 연관관계 매핑
[JPA] 다양한 연관관계 매핑
2022.12.22연관관계 매핑에 대한 기본 지식을 쌓았으니, 설계 시 만날 수 있는 다양한 연관관계들에 대해 살펴보자. 다대일 [N : 1] 연관관계 매핑의 기본이다. 테이블에서 FK를 가진 요소를 기준으로 매핑하고 그래프 객체 탐색이 필요한 경우 양방향으로 확장한다. 일대다 [1 : N] 다대일의 반대이다. @JoinColumn 애너테이션을 사용하지 않으면 JoinTable 방식이 사용되니 주의하자. (성능이 저하되고 운영이 어려워진다) 데이터베이스에서 외래 키는 다(多) 쪽에 위치한다. 다대일에서와 다르게 외래 키를 관리하는 엔티티가 Team에서의 List members이고, List를 변경하면 데이터베이스가 변경된다. 객체와 테이블의 차이 때문에 외래 키를 반대편 테이블이 관리하게 되는 특이한 구조가 됐다. -_-..
[JPA] 연관관계 매핑
[JPA] 연관관계 매핑
2022.12.22객체가 지향하는 패러다임과 관계형 데이터베이스가 지향하는 패러다임이 달라 객체 설계 시 테이블 설계에 맞춰서 설계하면 객체 그래프를 탐색할 때 문제가 생긴다. 테이블은 외래 키를 사용해 연관된 테이블을 찾고, 객체는 참조를 사용해 연관된 객체를 찾는다. 두 패러다임의 불일치 때문에 객체지향적으로 코드를 작성할 수 없다. 객체의 참조와 데이터베이스 테이블의 FK를 매핑해 패러다임의 불일치를 해결하자. 단방향 연관관계 Member와 Team을 묶는다고 생각해보자. Team에는 여러 Member가 속할 수 있다. (Member가 N, Team이 1인 상황이다) Member에 Team의 외래 키를 필드로 가지는 방식으로 설계하면 위에서 언급한 문제가 발생한다. 위와 같은 방식으로 설계하고 싶다. 이 때 @Man..
[JPA] 객체와 테이블 매핑
[JPA] 객체와 테이블 매핑
2022.12.22JPA가 영속성 컨텍스트 개념을 사용해 동작하는건 알겠는데, 자바 객체와 데이터베이스 테이블은 어떻게 매핑되는걸까? JPA에서 가장 중요한 부분은 자바 객체인 엔티티와 데이터베이스의 테이블을 정확하게 매핑하는 작업이다. JPA에서는 @Entity 애너테이션을 사용해서 엔티티를 관리한다. @Entity 애너테이션이 붙은 클래스는 데이터베이스 테이블과 매핑될 수 있다. 예전에는 xml 등 설정 파일을 사용해 매핑 정보를 작성했는데, 애너테이션을 사용하는 편이 좀 더 쉽고 직관적이다. @Entity 애너테이션의 속성으로 name을 지정해 JPA에서 사용할 엔티티 이름을 지정할 수 있고, @Table 애너테이션의 속성으로 name을 지정해 매핑할 테이블 이름을 지정할 수 있다. 엔티티 클래스는 public 또는..
[JPA] 영속성 컨텍스트
[JPA] 영속성 컨텍스트
2022.12.21자바 객체와 관계형 데이터베이스를 어떻게 매핑해서 사용해야 할까? 실제로 JPA는 내부적으로 어떻게 동작하는걸까? JPA의 작동 원리를 제대로 이해하기 위해서는 영속성 컨텍스트에 대해 이해해야 한다. 영속성 컨텍스트는 엔티티를 영구적으로 저장하는 환경으로, 눈에 보이지 않는 논리적인 개념이다. EntityManager를 생성하면 이에 대응하는 PersistenceContext 가 생성된다. 엔티티를 처음 만들면 엔티티는 비영속 상태이다. persist 메서드를 사용하면 엔티티가 영속 상태가 되어 영속성 컨텍스트에 관리된다. 즉, em.persist() 메서드는 단순히 데이터베이스에 값을 저장하는게 아니고, 엔티티를 영속화함을 의미한다. 그런데 왜 이런 매커니즘을 도입했을까? 객체와 데이터베이스 사이에 영..
[JPA] 도입
[JPA] 도입
2022.12.21Java Persistence API의 약자로 자바 진영의 ORM 기술 표준을 의미한다. JPA는 인터페이스이고, 인터페이스를 구현한 여러 구현체가 있는데 그 중 하이버네이트를 가장 많이 사용한다. 객체는 객체대로, 데이터베이스는 데이터베이스대로 설계하고 ORM 프레임워크가 객체와 데이터베이스간 차이를 해결해 데이터베이스를 자바 객체를 다루는 것 처럼 사용할 수 있도록 한다. 아예 밑바닥부터 구현되는건 아니고, JDBC API도 적절하게 사용한다. Persistence 클래스는 yml, xml 등 설정 정보를 읽고 EntityManagerFactory 클래스를 만든다. 그리고 필요할 때 마다 EntityManager를 만들어서 사용하는 방식으로 동작한다. EntityManager는 JPA에서 애플리케이션..