Departmentdepartment=newDepartment();department.setName("deptA");em.persist(department);Employeeemployee=newEmployee();employee.setUsername("empA");employee.setDepartment(department);em.persist(employee);em.flush();em.clear();EmployeefindEmployee=em.find(Employee.class,employee.getId());//SELECT 실행 (조인을 통해서 한꺼번에 가져온다.)System.out.println("findEmployee.getDepartment().getClass() : "+findEmployee.getDepartment().getClass());System.out.println("=============================");findEmployee.getDepartment().getId();//SELECT 실행하지 않음System.out.println("=============================");findEmployee.getDepartment().getName();//SELECT 실행하지 않음System.out.println("=============================");tx.commit();
@Entity@DatapublicclassParent{@Id@GeneratedValue(strategy=GenerationType.IDENTITY)privateLongid;privateStringname;@OneToMany(mappedBy="parent",cascade=CascadeType.ALL)privateList<Child>childs=newArrayList<>();//연관관계 편의 메소드publicvoidaddChild(Childchild){childs.add(child);child.setParent(this);}}@Entity@DatapublicclassChild{@Id@GeneratedValue(strategy=GenerationType.IDENTITY)privateLongid;privateStringname;@ManyToOne@JoinColumn(name="parent_id")Parentparent;}
테스트
Childchild1=newChild();Childchild2=newChild();Parentparent=newParent();parent.addChild(child1);parent.addChild(child2);em.persist(parent);//INSERT 3번 실행//em.persist(child1);//em.persist(child2);em.flush();em.clear();System.out.println("=============================");ParentfindParent=em.find(Parent.class,parent.getId());//SELECT 실행 (Parent 한정)System.out.println("=============================");tx.commit();//DELETE 실행
고아 객체
고아 객체
부모 엔티티와 연관관계가 끊어진 자식 엔티티
고아 객체 삭제
고아 객체를 자동으로 삭제하는 것
참조가 제거된 엔티티는 다른 곳에서 참조하지 않는 고아 객체로 취급된다.
참조하는 곳이 하나일 때 사용해야 한다.
특정 엔티티가 개인 소유할 때만 사용한다.
@OneToOne와 @OneToMany만 사용할 수 있다.
고아 객체 삭제 기능을 활성화 했을 때 부모 객체를 제거하면 자식 객체도 함께 제거된다.
CascadeType.REMOVE처럼 동작한다.
관련 어노테이션
@xxxToyyy
orphanRemoval = true 옵션을 사용하면 고아 객체 삭제 기능을 사용할 수 있다.
엔티티 정의
@Entity@DatapublicclassParent{@Id@GeneratedValue(strategy=GenerationType.IDENTITY)privateLongid;privateStringname;@OneToMany(mappedBy="parent",cascade=CascadeType.ALL,orphanRemoval=true)privateList<Child>childs=newArrayList<>();//연관관계 편의 메소드publicvoidaddChild(Childchild){childs.add(child);child.setParent(this);}}@Entity@DatapublicclassChild{@Id@GeneratedValue(strategy=GenerationType.IDENTITY)privateLongid;privateStringname;@ManyToOne@JoinColumn(name="parent_id")Parentparent;}
테스트
Childchild1=newChild();Childchild2=newChild();Parentparent=newParent();parent.addChild(child1);parent.addChild(child2);em.persist(parent);//INSERT 3번 실행//em.persist(child1);//em.persist(child2);em.flush();em.clear();System.out.println("=============================");ParentfindParent=em.find(Parent.class,parent.getId());//SELECT 실행 (Parent 한정)System.out.println("=============================");findParent.getChilds().remove(0);//SELECT 실행 (Child 한정)System.out.println("=============================");tx.commit();//DELETE 실행
공통 코드
EntityManagerFactoryemf=Persistence.createEntityManagerFactory("hello");//애플리케이션 전체 공유 (persistence.xml 참조)EntityManagerem=emf.createEntityManager();//한번 쓰고 버려야함, 쓰레드간 공유하지 않음EntityTransactiontx=em.getTransaction();//조회를 제외한 DML 작업시 필수로 사용tx.begin();try{//실행 내용}catch(Exceptione){e.printStackTrace();tx.rollback();}finally{em.close();}emf.close();