Hibernate保存自我引用父/子 [英] Hibernate saving self Reference parent/child

查看:168
本文介绍了Hibernate保存自我引用父/子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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

Java类

  @ManyToOne 
@JoinColumn(name =checker_id)
私人讲师检查器;

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

方法

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

lecturers.add(讲师);
// TODO自动生成的方法存根

}

然后,我设立了一个DAO和服务层来执行CRUD操作。创建方法是这样的:

  Session session = sessionFactory.getCurrentSession(); 

transaction = session.beginTransaction();

//创建新讲师
讲师讲师1 =新讲师();
lecturer1.setName(name);
lecturer1.setEmail(email);

讲师讲师2 =新讲师();
lecturer2.setName(name);
lecturer2.setEmail(email);

//创建新检查器
讲师检查器= new Lecturer();
checker.setName(name);
checker.setEmail(email);
checker.setChecker(checker);


列表< Lecturer> lecturer = 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)与一个或更多的孩子(讲师)并将匹配保存到数据库。我在问我应该如何去挽救这段关系。我是否应该分别创建父母和孩子,然后将使用该ID的父母与从下拉列表中选择的孩子进行匹配?我不确定如何确保检查器与其相应讲师之间的关系得以保存。

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

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

我应该得到我已经添加的检查器名称,但它不会回来。



我将不胜感激继续。

解决方案

首先,您的addLecturer()方法有一个错误。它不应该将孩子的讲师列表设置为当前的讲师列表:

  public void addLecturer(讲师讲师){
if(lecturer == null){
lecturers = new ArrayList< Lecturer>(); //确定:延迟初始化
}
lecturer.setChecker(this); //确定:将孩子的父母设置为
lecturer.setLecturers(lecturers); //这一行应该被删除:孩子的孩子不应该和这位讲师的孩子一样b
$ b lecturers.add(讲师); //确定:将孩子添加到孩子列表中
}

当你得到讲师,您可以获得以下检查员:

 检查器:com.professional.project.domain.Lecturer@439942 

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

  @Override 
public String toString(){
返回名称;
}


I'm using Spring 3.2, Hibernate 4 and MySQL. I have a self referencing class called Lecturers which has annotations implementing a parent/child one to many relationship. I have a problem with implementing a controller and form for saving a parent and child from the same table. It's a self-referencing class.

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

The Java class

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

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

And the class also has this method

@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

}

I then set up a DAO and Service layer for implementing a CRUD operations. The create method is this:

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

My requirement is now to provide a form that will be used to match a parent (Checker) to one or more children (Lecturers) and save the match to the database. I'm asking how I should go about saving the relationship. Should I create the parent and children separately, then match a parent using the id to a children selected from say a drop down list? I'm not sure how to make sure the relationship between a checker and its respective lecturers is saved.

I then created a main class for testing the relationship and to see if it works. Inserting data into the db works but when I want to list it I get this:

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

I should get the name of the checker back which I already added but it's not coming back.

I would appreciate some help on how to proceed.

解决方案

First of all, your addLecturer() method has a bug. It shouldn't set the lecturers list of the child to the current lecturer's list:

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
}

When you get a lecturer, you obtain the following as the checker :

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

The above is just the result of the call to the default toString() method on the checker. To get its name, call getName() on the checker. If you want the toString() method to return the name, then implement it that way:

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

这篇关于Hibernate保存自我引用父/子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆