【问题标题】:Hibernate retrieve wrong list of objects in one-to-many relationHibernate 在一对多关系中检索错误的对象列表
【发布时间】:2017-04-16 00:55:25
【问题描述】:

我是休眠新手。我必须表部门和老师。一个系可以有多名教师,但一名教师只能隶属于一个系。我有以下映射:

@Entity
@Table(name = "department")
public class Department {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @Column(name = "name")
    private String name;

    @Column(name = "description")
    private String description;

    @OneToMany (cascade=CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "department_id")
    private List<Teacher> teachers = new ArrayList<Teacher>();
}

@Entity
@Table(name = "teacher")
public class Teacher {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @Column(name = "fName")
    private String fName;

    @Column(name = "lName")
    private String sName;

    @Column(name = "degree")
    private String degree;

    @ManyToOne
    private Department department;
}

还有 getter 和 setter,为简单起见,我省略了它们。 我正在使用 MySql 数据库。当我尝试用新教师插入新部门时,一切正常。但是,我也希望能够获得分配给每个部门的教师的完整部门列表。目前在我的数据库中,我有 5 个部门和 13 个 教师。但是当我执行以下代码时:

    DepartmentDaoImpl ddi = new DepartmentDaoImpl();
    List<Department> departments = ddi.getAllDepartment();

    for (Department k : departments){
        printDepartmentData(k);
        List<Teacher> teachers = k.getTeachers();
        for (Teacher t : teachers){
            printTeacherName(t);
        }
    }

还有我的 getAllDepartments 实现:

@Override
public ArrayList getAllDepartment() throws SQLException {
    Session session = null;
    ArrayList<Department> result = null;
    try{
        session = HibernateUtil.getSessionFactory().openSession();
        result = (ArrayList)session.createCriteria(Department.class).list();
    }catch(Exception ex){
        ex.printStackTrace();
    }finally{
        if(session != null && session.isOpen()){
            session.close();
        }
    }
    return result;
}

Sql 创建表:

CREATE TABLE teacher (
id INTEGER PRIMARY KEY auto_increment,
fName varchar(30),
lName VARCHAR(30),
degree VARCHAR(100),
department_id INTEGER
);
CREATE TABLE department(
id INTEGER PRIMARY KEY auto_increment,
name VARCHAR(100),
description VARCHAR(5000) 
);

我得到了 13 个部门实例。我得到了第一个部门的 5 个实例(我分配了 5 位老师),每个都分配了相同的 5 位老师,第二个部门的两个实例(我分配了两个老师)每个都分配了两个相同的老师,所以上。 有人可以弄清楚,如何解决它?我需要获得 5 个部门实例,其中
相应的教师人数。

【问题讨论】:

  • 你能展示一下DepartmentDaoImpl.getAllDepartment()的实现吗?
  • 尝试删除@JoinColumn(name = "department_id")并重新运行,然后会发生什么?
  • @mthmulders 添加到帖子中
  • @Angga 然后我得到空的教师列表,但只有五个部门实例
  • 然后看我的回答,你的问题是你将 department_id 称为部门本身的 FK

标签: java hibernate one-to-many


【解决方案1】:

由于您配置了与fetch = FetchType.EAGER 的一对多关系,hibernate 对两个表执行连接。你看到的结果就是这个join造成的。

确保您在DepartmentTeacher 中都有正确的equals()hashCode() 方法。如果这不能解决问题,请尝试使用Set 而不是List

【讨论】:

  • 转换为 Set 有帮助。但它是休眠的正确方法吗?对我来说,这种方法似乎是一种解决方法。
  • 不,这是正确的方法。如果您查看 Hibernate 教程,您会发现他们也使用 Set 方法
【解决方案2】:

进行以下更改并测试它

   @OneToMany (cascade=CascadeType.ALL, fetch = FetchType.EAGER, mappedBy="department")
    private List<Teacher> teachers = new ArrayList<Teacher>();

【讨论】:

  • 如果我理解正确,我应该删除 JoinColumn 注释吗?如果是这样,我会得到相同的结果。
  • 而且你必须添加 mappedBy="department"
  • 你能发布你的 getTeachers() 和 getDepartment() 方法吗
  • 我有 getTeacherById(int id), getAllTeachers() 可以返回表中的所有教师,对于部门也是如此。发布哪一个?
  • 没有,在 Teacher 类中,您需要为私有 Department 部门提供 getter 和 setter 方法,同样在 Department 类中,您需要为私有 List 教师提供 getter 和 setter
【解决方案3】:

尝试更改为:

@OneToMany (mappedBy="department", cascade=CascadeType.ALL, fetch = FetchType.EAGER)
private Set<Teacher> teachers = new HashSet<Teacher>();

并改变它:

@ManyToOne
private Department department;

到:

@Collumn(name = "department")
private Integer department;

【讨论】:

  • 如果像你说的将JoinColumn设置为“id”,每个部门我只会得到一个老师。这位教师通过教师表中的 id (这是主键)添加到部门。我添加了我的SQL来发布,可能会更清楚。
  • 对不起,我误导了 mappedBy 和 JoinColumn。现在修复了,这项工作来自我,但我在没有获取的情况下测试它,并且在教师实体中没有多对一
  • 已编辑,以教师内部的部门注释为例
【解决方案4】:

在你的 dao 中试试这个,它会有所帮助

result = (ArrayList) session.createCriteria (Department.class)。 setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();

【讨论】:

    猜你喜欢
    • 2018-11-09
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 2020-12-26
    • 1970-01-01
    • 1970-01-01
    • 2012-02-20
    • 2011-09-30
    相关资源
    最近更新 更多