2013-04-20 3 views
0

Spring 3.2, Hibernate 4 및 MySQL을 사용하고 있습니다. 나는 부모/자식 1 대 다수 관계를 구현하는 주석을 가진 Lecturers라는 자체 참조 클래스를 가지고있다. 같은 테이블에서 부모와 자식을 저장하기위한 컨트롤러와 폼을 구현하는 데 문제가 있습니다. 자기 참조 클래스입니다.Hibernate saving self 참조 parent/child

내 DB :

CREATE TABLE `lecturers` (
`lecturer_id` BIGINT(10) NOT NULL AUTO_INCREMENT, 
`name` VARCHAR(255) NULL DEFAULT NULL, 
`email` VARCHAR(255) NULL DEFAULT NULL, 
`checker_id` BIGINT(20) NULL DEFAULT NULL, 
PRIMARY KEY (`lecturer_id`), 
FOREIGN KEY (`checker_id`) REFERENCES `lecturers` (`lecturer_id`) 

자바 클래스

@ManyToOne 
@JoinColumn(name="checker_id") 
private Lecturer checker; 

@OneToMany(cascade = CascadeType.ALL, mappedBy="checker", orphanRemoval=true) 
private List<Lecturer> lecturers = new ArrayList<Lecturer>(); 

그리고 클래스는 내가 다음을 구현하는 DAO 및 서비스 계층을 설정

@Transient 
public void addLecturer(Lecturer lecturer) { 
    if(lecturers == null) { 
     lecturers = new ArrayList<Lecturer>(); 
     //lecturers = new HashSet<Lecturer>(); 
    } 
    lecturer.setChecker(this); 
    lecturer.setLecturers(lecturers); 
    //lecturer.setLecturers(lecturers); 

    lecturers.add(lecturer); 
    // TODO Auto-generated method stub 

} 

이 방법이 있습니다 CRUD 작업. 작성 방법은 이것이다 :

Session session = sessionFactory.getCurrentSession(); 

    transaction = session.beginTransaction(); 

// Create new lecturers 
    Lecturer lecturer1 = new Lecturer(); 
    lecturer1.setName(name); 
    lecturer1.setEmail(email); 

    Lecturer lecturer2 = new Lecturer(); 
    lecturer2.setName(name); 
    lecturer2.setEmail(email); 

     // Create new checker 
    Lecturer checker = new Lecturer(); 
    checker.setName(name); 
    checker.setEmail(email); 
    checker.setChecker(checker); 


    List<Lecturer> lecturers = new ArrayList<Lecturer>(); 
    lecturers.add(lecturer1); 
    lecturers.add(lecturer2); 
    lecturer1.setChecker(checker); 
    lecturer2.setChecker(checker); 

    checker.addLecturer(lecturer1); 
    checker.addLecturer(lecturer2); 

    checker.setLecturers(lecturers); 

    session.save(checker); 


    session.save(lecturer1); 
    session.save(lecturer2); 

내 요구 사항은 하나 이상의 자녀 (강사)로 부모 (검사)와 일치하고 데이터베이스에 경기를 저장하는 데 사용되는 양식을 제공하는 지금이다. 나는 관계를 저장하는 것에 대해 어떻게해야하는지 묻습니다. 부모와 자식을 따로 생성해야합니까? 그런 다음 드롭 다운 목록에서 선택한 자식에게 ID를 사용하여 부모를 일치 시키시겠습니까? 나는 체커와 각자의 강사 들간의 관계가 어떻게 구속되는지를 확신 할 수 없다.

그런 다음 관계를 테스트하고 작동하는지 확인하기위한 기본 클래스를 만들었습니다. DB를 작품에 데이터를 삽입하지만 난 그것을 나열 할 때이 얻을 :

Name: Mark 
Email: [email protected] 
Checker: [email protected] 
ID: 22 

내가 이미 추가 된 검사기 다시 이름을 얻어야한다을하지만 돌아 오지 않을거야.

진행 방법에 대한 도움을 주시면 감사하겠습니다.

답변

1

우선 addLecturer() 메소드에 버그가 있습니다. 단지입니다 위의

Checker: [email protected] 

: 당신이 강사를 얻을 때

public void addLecturer(Lecturer lecturer) { 
    if (lecturers == null) { 
     lecturers = new ArrayList<Lecturer>(); // OK : lazy initialization 
    } 
    lecturer.setChecker(this); // OK : set the parent of the child to this 
    lecturer.setLecturers(lecturers); // this line should be removed : the child's children shouldn't be the same as this lecturer's children 

    lecturers.add(lecturer); // OK : ad the child to the list of children 
} 

, 당신이 (가) 검사로 다음을 얻을 : 그것은 현재 강사의 목록에 아이의 강사 목록을 설정하지 말아야 검사기의 기본 toString() 메소드 호출 결과. 이름을 얻으려면 검사기에서 getName()으로 전화하십시오. toString() 메서드가 이름을 반환하도록하려면 다음과 같이 구현하십시오.

@Override 
public String toString() { 
    return name; 
} 
+0

toString() 메서드를 사용해 주셔서 감사합니다. 이제 이름을 반환합니다. addLecturer 메서드를 약간 변경했습니다. 게으른 초기화 부분을 명확하게 설명해 주시겠습니까? 초기화 할 수있는 더 좋은 방법이 있습니까? 그리고 제가 물어볼 수 있다면, 저의 컨트롤러와 저장 장치에 그것을 구현할 수있는 방법이 있습니까? – user2259555

+0

사실, 목록이 건설 시간 ('private리스트 lecturers = new ArrayList ();')에서 열정적으로 초기화되므로 null을 검사 할 필요가 없습니다. 메서드의 마지막 두 줄을 유지하십시오. –