김영환님의 강의 자바 ORM 표준 JPA 프로그래밍 - 기본편 보면서 공부한 내용입니다.
📝 일대다 단방향 매핑
💡 정리
- 엔티티가 관리하는 외래키가 다른 테이블에 있음
- 연관관계 관리를 위해 추가로 UPDATE SQL을 실행함
✅ 결론 : 다대일 양방향 매핑을 사용하자!
📝 일대일 관계
📝 다대다 관계
💡 한계
- 실무에서 사용X
- 연결 테이블이 연결만 하고 끝나지 않음 (추가 데이터가 들어갈 수 있는데 중간 테이블에 추가 정보를 넣을 수 없음)
📝 상속관계 매핑
📝 구현 방법
1. JOINED (각각 테이블로 변환)
2. SINGLE_TABLE (통합 테이블로 변환)
3. TABLE_PER_CLASS (서브타임 테이블로 변환)
💡 어노테이션
- @Inheritance(strategy=InheritanceType.XXX)
- @DiscriminatorColumn(name="DTYPE")
✅ 테이블에 DTYPE 컬럼이 생기면서 Entity명이 들어감- @DiscriminatorValue("XXX")
✅ DTYPE에 들어가는 Entity명을 변경함
📝 Mapped Superclass
📝 프록시
- em.find() : 데이터베이스를 통해서 실제 엔티티 객체 조회
- em.getReference() : 데이터베이스 조회를 미루는 가짜(프록시)엔티티 객체 조회
✅ 즉, 디비에 쿼리가 안날라오는데 객체가 조회되는 것
// 프록시
Member member = new Member();
member.setUsername("hello");
em.persist(member);
em.flush();
em.clear();
Member findMember = em.getReference(Member.class, member.getId());
System.out.println("findMember.getClass() = " + findMember.getClass()); // 가짜 클래스
System.out.println("findMember.getId() = " + findMember.getId());
System.out.println("findMember.getUsername() = " + findMember.getUsername());
// 실제 가져다쓰는 시점에 내부적으로 영속성 컨텍스트에 요청해서 실제 레퍼런스를 가지게됨
// => 처음에 실제 가져올 때는 db에 접근하여 레퍼런스 생성함
📝 프록시 특징
// 1번
Member m1 = em.find(Member.class, member1.getId());
System.out.println("member = " + m1.getClass());
Member reference = em.getReference(Member.class, member1.getId());
System.out.println("reference = " + reference.getClass());
System.out.println("a == a : " + (m1 == reference)); // 항상 true가 되어야함
// 2번
Member reference = em.getReference(Member.class, member1.getId());
// 프록시가 한 번 실행되면 프록시로 계속 반환됨
System.out.println("member = " + m1.getClass());
Member m1 = em.find(Member.class, member1.getId()); // proxy로 반환됨
System.out.println("reference = " + reference.getClass());
=System.out.println("a == a : " + (m1 == reference)); // 항상 true가 되어야함
Member m1 = em.getReference(Member.class, member1.getId());
System.out.println("member = " + m1.getClass());
em.detach(m1); // 영속성 컨텍스트에서 관리안한다고 표시
//em.close(); // 영속성 컨텍스트 종료
System.out.println("getUsername =" + m1.getUsername());
💡 프록시 확인
- 프록시 인스턴스의 초기화 여부 확인
✅ PersistenceUnitUtil.isLoaded(Object entity)- 프록시 클래스 확인 방법
✅ entity.getClass().getName() 등- 프록시 강제 초기화
✅ org.hibernate.Hibernate.initialize(entity)