릴레이션(관계형 데이터베이스)를 객체(도메인 모델)로 매핑 하려는 이유
하지만, 객체를 릴레이션에 맵핑하려니 문제들이 발생한다.
ORM 이 해결해야하는 문제점과 해결책은 아래와 같다.
해결방법 : 매핑정보에 상속정보를 넣어준다. (@OneToMany
, @ManyToOne
)
해결방법 : 매핑정보에 방향정보를 넣어준다. (@JoinColumn
, @MappedBy
)
해결방법 : 매핑/조회 정보로 참조탐색 시점을 관리한다.(@FetchType
, fetchJoin()
)
해결방법 : 크기가 큰 멤버 객체는 테이블을 분리하여 상속으로 처리한다. (@embedded
)
해결방법 : PK 를 객체 Id로 설정하고 EntityManager는 해당 값으로 객체를 식별하여 관리 한다.(@Id
,@GeneratedValue
)
ORM이 문제점만 있던게 아닌 얻은 것도 있었다.
1차 캐시
2차 캐시
2차 캐시 적용 방법
@Cacheable
적용 후 설정 추가sharedCache.mode
설정비영속
> 영속
> 준영속
| 삭제
)비영속(new/transient) - 엔티티 객체가 만들어져서 아직 저장되지 않은 상태로, 영속성컨텍스트와 전혀 관계가 없는 상태
영속(managed) - 엔티티가 영속성 컨텍스트에 저장되어, 영속성 컨텍스트가 관리할 수 있는 상태
준영속(detached) - 엔티티가 영속성 컨텍스트에 저장되어 있다가 분리된 상태로, 영속성컨텍스트가 더 이상 관리하지 않는 상태
삭제(removed) - 엔티티를 영속성 컨텍스트와 데이터베이스에서 삭제하겠다고 표시한 상태
(영속성 컨텍스트에 저장된 상태)
> flush() > (DB에 쿼리가 전송된 상태)
> commit() > (DB에 쿼리가 반영된 상태)
persist() -> save()
merge -> update()
Item item = new Item(); // 1
item.setItemNm("테스트 상품");
EntityManager em = entityManagerFactory.createEntityManager(); // 2
EntityTransaction transaction = em.getTransaction(); // 3
transaction.begin();
em.persist(item); // 4-1
em.flush(item). // 4-2 (DB에 SQL 보내기/commit시 자동수행되어 생략 가능함)
transaction.commit(); // 5
em.close(); // 6
// 1. 영속성 컨텍스트에 담을 상품 엔티티 생성
// 2. 엔티티 매니저 팩토리로부터 엔티티 매니저를 생성
// 3. 데이터 변경 시 무결성을 위해 트랜잭션 시작
// 4. 영속성 컨텍스트에 저장된 상태, 아직 DB에 INSERT SQL 보내기 전
// 5. 트랜잭션을 DB에 반영, 이 때 실제로 INSERT SQL 커밋 수행
// 6. 엔티티 매니저와 엔티티 매니저 팩토리 자원을 close() 호출로 반환
generationType.IDENTITY
Team teamA = new Team();
teamA.setName("TeamA");
em.persist(teamA);
Team teamB = new Team();
teamB.setName("TeamB");
em.persist(teamB);
Member member_A = new Member();
member_A.setName("memberA");
member_A.setTeam(teamA);
em.persist(member_A);
// em.flush();
Member findMember = em.find(Member.class, member_A.getId());
Team findTeam= findMember.getTeam();
System.out.println(findTeam.getName());
// flush가 있는 경우
create member
create team
insert team // flush로 인해 쓰기지연이 발생하지 않음
insert member // flush로 인해 쓰기지연이 발생하지 않음
print "TeamA" (memberA.getTeam())
// flush가 없는 경우
create member
create team
print "TeamA" (memberA.getTeam()) // 쓰기 지연이 발생하더라도 영속성 컨텍스트에서 조회해옴
insert team // 쓰기 지연이 발생한 부분
insert member // 쓰기 지연이 발생한 부분