매번 연관된 객체들을 불러오는것보다 일단 가짜객체를 불러와두고 실제로 연관된 객체를 사용할시점에 쿼리를 날려서 불러오는게 성능상의 이점이 있다. 이때 사용하는 가짜 객체가 프록시다.
사용할시점에 쿼리를 날려서 불러오는 것을 지연로딩이라고한다.
@Access(AcessType.PROPERTY))
인 경우에만 초기화하지 않고@Access(AcessType.FIELD))
인 경우에는 초기화하러간다Member member = em.find(Member.class, 1l);
Team team = em.reference(Team.class, 2l);//sql을 실행해서 가져오지 않음
member.setTeam(team);//team의 id값만 필요하다
JPA의 데이터 타입을 나눠보면 1)엔티티타입
2)값타입
으로 나눌 수 있다
값 타입은 다음과 같이 나눌 수 있다
1) 기본값 타입(기본타입 + 래퍼클래스 + String)
2) 임베디드 타입(서로다른 1번의 종류들로 구성된)
ㄴ 새로운 값타입을 정의해서 사용할 수 있음
ㄴ entity에는 @Embedded를, 새로운값타입이 되는 class에는 @Embeddable을 쓴다
ㄴ 해당 타입은 기본생성자가 필수
3) 컬렉션 값 타입
@ElementCollection
@CollectionTable(name, joincolumns)
//입베디드 값 타입
member.setHomeAddress(new Address("통영", "해수욕장", "220-22"));
//기본값 타입 컬렉션
member.getFavoriteFoods().add("짬뽕");
member.getFavoriteFoods().add("짜장면");
member.getFavoriteFoods().add("국수");
//임베디드 값 타입 컬렉션
member.getAddressHistory().add(new Address("서울", "강남", "20-290"));
member.getAddressHistory().add(new Address("서울", "강북", "20-290"));
//
em.persist(member);
Address address1 = new Address("1", "2");
Address address2 = new Address("3", "4");
Address address3 = new Address("12", "123");
List<Address> addressList = new ArrayList<>();
addressList.add(address1);
addressList.add(address2);
addressList.add(address3);
Member member = new Member();
member.setAddressList(addressList);
em.persist(member);
//변경
em.flush();
address1 = new Address("213", "!23");
addressList.remove(0);
addressList.add(address1);
Hibernate: insert into member (member_id, name) values (default, ?)
Hibernate: insert into address (member_id, code, zip_code) values (?, ?, ?)
Hibernate: insert into address (member_id, code, zip_code) values (?, ?, ?)
Hibernate: insert into address (member_id, code, zip_code) values (?, ?, ?)
Hibernate: delete from address where member_id=?
Hibernate: insert into address (member_id, code, zip_code) values (?, ?, ?)
Hibernate: insert into address (member_id, code, zip_code) values (?, ?, ?)
Hibernate: insert into address (member_id, code, zip_code) values (?, ?, ?)
그렇기때문에 값타입 컬렉션이 매핑된 테이블에 데이터가 많다면 값타입 컬렉션 대신에 일대다 관계를 고려해야한다
member.getValues().remove(3) // 이런 건 당연히 된다.
member.getValues().add(4)
// 이런 것도 가능하다. JPA가 equals와 hashcode 메서드를 이용해서 비교 후 삭제한다.
member.getValues().remove( new Address("old1", "street", "10000") );
그래서 값 타입을 만들 땐 equals와 hashcode를 제대로 구현하도록 하자.