문서의 선택한 두 판 사이의 차이를 보여줍니다.
양쪽 이전 판 이전 판 다음 판 | 이전 판 | ||
wiki:spring:jpa [2022/07/04 19:13] dhan |
wiki:spring:jpa [2023/01/13 18:44] (현재) |
||
---|---|---|---|
줄 1: | 줄 1: | ||
====== Spring에 JPA 적용하기 ====== | ====== Spring에 JPA 적용하기 ====== | ||
<WRAP left notice 80%> | <WRAP left notice 80%> | ||
- | * description : | + | * description : JPA 관련 내용 기술 |
* author | * author | ||
* email : hylee@repia.com | * email : hylee@repia.com | ||
줄 217: | 줄 217: | ||
즉시 로딩(EAGER), | 즉시 로딩(EAGER), | ||
| | ||
- | 실무에서 가급적 지연 로딩만 사용 | + | 실무에서 가급적 |
| | ||
즉시 로딩은 JPQL에서 N+1 문제 발생 | 즉시 로딩은 JPQL에서 N+1 문제 발생 | ||
줄 230: | 줄 230: | ||
실무에서 즉시 로딩을 사용하지 마라!, JPQL fetch 조인이나, | 실무에서 즉시 로딩을 사용하지 마라!, JPQL fetch 조인이나, | ||
즉시 로딩은 상상하지 못한 쿼리가 나간다. | 즉시 로딩은 상상하지 못한 쿼리가 나간다. | ||
- | + | | |
영속성 전이(CASCADE) | 영속성 전이(CASCADE) | ||
영속성 전이는 연관관계를 매핑하는 것과 아무 관련이 없음 | 영속성 전이는 연관관계를 매핑하는 것과 아무 관련이 없음 | ||
줄 239: | 줄 239: | ||
소유자가 하나일때 사용 | 소유자가 하나일때 사용 | ||
| | ||
- | 고아 객체 | + | 고아 객체(삭제는 언제나 조심해서 사용) |
orphanRemoval = true | orphanRemoval = true | ||
연결고리가 없어졌을때 삭제 됨 | 연결고리가 없어졌을때 삭제 됨 | ||
참조하는 곳이 하나일 때 사용해야 됨 | 참조하는 곳이 하나일 때 사용해야 됨 | ||
특정 엔티티가 개인 소유할 때 사용 (@OneToOne, @OneToMany만 가능) | 특정 엔티티가 개인 소유할 때 사용 (@OneToOne, @OneToMany만 가능) | ||
+ | |||
+ | CASCADE.ALL, | ||
+ | 부모 엔티티를 통해서 자식의 생명 주기를 관리할 수 있음(DDD의 Aggregate Root개념을 구현할 때 유용) | ||
+ | |||
+ | 실전: | ||
+ | |||
+ | ===== 값 타입 ===== | ||
+ | |||
+ | 자바 기본값 타입은 공유가 불가능(복사) | ||
+ | 래퍼 클래스는 공유가 가능하지만 변경할 방법이 없음 | ||
+ | |||
+ | 임베디드 타입(클래스 생성 -> 복합값을 가짐) | ||
+ | 재사용 가능 | ||
+ | 높은 응집도를 가짐 | ||
+ | 엔티티가 생명 주기를 조절 | ||
+ | 객체와 테이블을 아주 세밀하게 매핑하는 것이 가능( find-grained) | ||
+ | 잘 설계한 ORM 애플리케이션은 매핑한 테이블의 수보다 클래스의 수가 더 많다. | ||
+ | |||
+ | 동일한 타입을 중복으로 사용하면 중복필드로 오류가 남 | ||
+ | @AttributeOverrides, | ||
+ | |||
+ | |||
+ | 임베디드 타입은 복사해서 사용해야 됨 (= < | ||
+ | 공유로 인한 사이드 이펙트는 주의해야 한다. | ||
+ | 대신 불변 객체(immutable object)로 설계하거나 생성자로만 값을 설정하고, | ||
+ | 변경하려면 new를 기존 값을 가져오고, | ||
+ | |||
+ | 실전: 임베디드 타입은 사용할 경우 불변 객체로 해서 사용하면 주석을 꼭 만들자!! | ||
+ | |||
+ | 기본 값타입이 인스턴스가 달라도 값이 같으면 같다. | ||
+ | |||
+ | 값 비교시 | ||
+ | 동일성(identity) 비교: 인스턴스의 참조 값 비교, == | ||
+ | 동등성(equivalence) 비교: 인스턴스의 값 비교, equals() | ||
+ | |||
+ | 객체 비교시 equals() override하여 전체 값을 일일이 동등성 비교를 해야 됨. (툴에서 자동으로 제공하는 것으로 사용, hashCode도 함께...) | ||
+ | |||
+ | 값타입 컬렉션(@ElementCollection, | ||
+ | 엔티티로 컬렉션이 아닌 값타입으로 컬렉션을 사용 | ||
+ | 데이터베이스로 봐서는 테이블이 분리된 것임 | ||
+ | 테이블이 분리되었어도 생명주기가 엔티티에 의해 관리가 됨 즉 영속성 전이, 고아 객체 제거 기능을 필수로 가지는 것과 같음 | ||
+ | 값 타입 컬렉션도 지연 로딩 전략을 사용함 | ||
+ | |||
+ | 수정시에는 세터가 아닌 new를 사용하여 통으로 교체(side effect를 원천적으로 없앰) | ||
+ | |||
+ | 값 타입은 엔티티와 다르게 식별가 개념이 없다. | ||
+ | 값은 변경하면 추적이 어렵다. | ||
+ | 값 타입 컬렉션에 변경 사항이 발생하면, | ||
+ | 값 타입 컬렉션에 있는 현재 값을 모두 다시 저장한다. | ||
+ | |||
+ | 값 타입 컬렉션을 매핑하는 테이블은 모든 컬럼을 묶어서 기본키를 구성해야 함(null X, 중복 x) | ||
+ | 실무에서는 값타입을 엔티티로 승격하여 사용(일대다 관계) | ||
+ | 값 타입 컬렉션은 단순한 값 저장시에만 사용 | ||
+ | |||
+ | ===== 객체 지향 쿼리 언어 ===== | ||
+ | * [[wiki: | ||
+ | |||
===== 적용파일 목록 ===== | ===== 적용파일 목록 ===== | ||
줄 426: | 줄 482: | ||
===== Builder 사용하기 ===== | ===== Builder 사용하기 ===== | ||
* [[https:// | * [[https:// | ||
- | | + | |
+ | ===== Troubleshooting ===== | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | |||
+ | ===== Ref ===== | ||
+ | [[wiki: | ||
{{tag> | {{tag> | ||
+ |