Hibernate保存自我引用父/子

时间:2013-04-20 14:31:55

标签: mysql spring hibernate

我正在使用Spring 3.2,Hibernate 4和MySQL。我有一个名为Lecturers的自引用类,它具有实现父/子一对多关系的注释。我有一个问题,实现一个控制器和表单来保存同一个表中的父和子。这是一个自我引用的课程。

我的数据库:

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`)

Java类

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

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

该课程也有这个方法

@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

}

然后我设置了一个DAO和服务层来实现CRUD操作。 create方法是:

  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);

我的要求是提供一个表单,用于将父(Checker)与一个或多个子(Lecturers)匹配,并将匹配保存到数据库。我问我应该如何保存这段关系。我应该单独创建父项和子项,然后使用id将父项与从下拉列表中选择的子项匹配?我不确定如何确保检查员与其各自讲师之间的关系得到保存。

然后我创建了一个主类来测试关系并查看它是否有效。将数据插入数据库可以工作,但是当我想列出它时,我得到了这个:

Name: Mark
Email: ma@msn.com
Checker: com.professional.project.domain.Lecturer@439942
ID: 22

我应该知道我已经添加的检查器的名称,但它没有回来。

我很感激有关如何继续的一些帮助。

1 个答案:

答案 0 :(得分:1)

首先,你的addLecturer()方法有一个bug。它不应该将孩子的讲师名单设置为当前讲师的名单:

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
}

当您找到讲师时,您将获得以下作为检查员:

Checker: com.professional.project.domain.Lecturer@439942

以上只是在检查器上调用默认toString()方法的结果。要获取其名称,请在检查器上调用getName()。如果你想让toString()方法返回名字,那就按照这样的方式实现:

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