Hibernate onetoMany映射检索链中的所有结果 [英] Hibernate onetoMany mapping retrieving all the results in a chain

查看:113
本文介绍了Hibernate onetoMany映射检索链中的所有结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有两张名为employee和phone_number的表,其中员工可以有多个号码。



我有两个表格:

  1)员工
列:
id
名称

2)phone_number
列:
employee_id(FK)
phone_number_type
phone_number

雇员和phone_number与一个到多个映射(phone_number中的employee_id列充当FK)



我已经在模型类中定义了以下注释。

  @Entity 
@Table(name =employee)
public class Employee
@Id
@GeneratedValue
私人整数ID;

@OneToMany(fetch = FetchType.LAZY,mappedBy =employee_id)
@JoinColumn(name =ID)
private设置< PhoneNumber> phonenumbers = new HashSet< PhoneNumber>(0);

public Set< PhoneNumber> getPhonenumbers(){
返回phonenumbers;
}

public void setPhoneNumbers(Set< PhoneNumber> phonenumbers){
this.phonenumbers = phonenumbers;

类PhoneNumber



<$ ($ name =phone_number)
public class PhoneNumber {

@ManyToOne(fetch = FetchType.LAZY)pre $ @Entity
@Table
@JoinColumn(name =employee_id)
私人雇员employeeid;

public Employee getEmployeeid(){
return this.employeeid;
}

public void setEmployeeid(Employee employeeid){
this.employeeid = employeeid;
}

我的问题是当我检索所有员工或特定员工时,检索他们的电话号码。目前,当我在调试模式下运行时,我看不到正在填充的电话号码。我在springmvc框架中运行hibernate,并通过以下代码检索员工:

  @Override 
@SuppressWarnings (未选中)
公共列表<雇员> getEmployees(){
// TODO自动生成的方法存根
return getCurrentSession()。createQuery(from Employees)。list();
}

他们需要做什么才能返回phone_numbers。我的最终目标是在视图中以表格格式显示员工和电话号码。



谢谢

<当我做了fetch = EAGER时,我试图调试,但是我没有看到值。

 列表< Employees>如何确保它正在提取电话数据? _employees = employeeService.getEmployees(); 
for(Employees o:_employees){
java.util.Set< PhoneNumber> a = o.getPhonenumbers();
}

我发现了我所犯的错误,但我正遇到另一个问题。
我的错误是employee_id字段是FK,但没有正确填充。但是,此列不是phone_number表中的主键。



我将phone_number更改为:

< pre $ @Entity
@Table(name =phonenumber)
public class Phonenumber {


@EmbeddedId
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name =EMPLOYEEID)
私人雇员employeeid;

但是,我现在遇到以下错误:
导致:org.hibernate.MappingException :Composite-id类必须实现Serializable:

我能够摆脱这个错误,但我遇到了另一个有趣的错误。

  @Entity 
@Table(name =phonenumber)它只是选择电话号码中的第一行。
public class Phonenumber implements Serializable {

@Column(name =key)
private String key;

@Column(name =value)
private String value;

@Id
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name =EMPLOYEEID)
私人员工雇员;

员工

  @Entity 
@Table(name =employee)
public class Employee {

@Id
@GeneratedValue
private Integer id ;

@OneToMany(mappedBy =employeeid,fetch = FetchType.EAGER)
private Set< Phonenumber> phonenumbers = new HashSet< Phonenumber>(0);


解决方案


  • 使用 HQL 可以如下实现:

    createQuery(from employee e left join fetch e.phonenumbers)


  • 您也可以使用 EAGER加载。但是,要非常小心并考虑其影响。
    它可能会影响性能,因为它会加载所有相关的实体。



    中不需要@ JoinColumn 因为通过 mappedBy 你说你想如何加入实体。在大多数情况下, @JoinColumn 用于单向关系,或者当您没有 mappedBy 时。



    请从Phonenumber的员工列删除@Id,并让 id 为主键。

      @Entity 
    @Table(name =phonenumber)
    public class Phonenumber implements Serializable {

    @Column(name =key)
    private String key;

    @Column(name =value)
    private String value;

    @Id
    @GeneratedValue
    私人整数ID;


    @ManyToOne(fetch = FetchType.EAGER)
    私人雇员雇员;

    }


    Say I have two tables called employee and phone_number where employee can have multiple numbers.

    I have two tables for example:

    1) employee
    columns:
    id
    name
    
    2) phone_number
    columns:
    employee_id(FK)
    phone_number_type
    phone_number
    

    employee and phone_number have one to many mappings with (employee_id column in phone_number acting as a FK)

    I have defined following annotations in the model classes.

    @Entity
    @Table(name="employee")
    public class Employee
    @Id
    @GeneratedValue
    private Integer id;
    
    @OneToMany(fetch = FetchType.LAZY, mappedBy="employee_id")
    @JoinColumn(name = "ID")
    private Set<PhoneNumber> phonenumbers = new HashSet<PhoneNumber>(0);
    
    public Set<PhoneNumber> getPhonenumbers() {
    return phonenumbers; 
    }
    
    public void setPhoneNumbers(Set<PhoneNumber> phonenumbers) {
    this.phonenumbers = phonenumbers; 
    }
    

    Class PhoneNumber

    @Entity
    @Table(name="phone_number")
    public class PhoneNumber {
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "employee_id")
    private Employee employeeid;
    
    public Employee getEmployeeid() {
    return this.employeeid;
    }
    
    public void setEmployeeid(Employee employeeid) {
    this.employeeid = employeeid;
    }
    

    My question is When I retrieve all the employees or a specific employee I also want to retrieve their phone numbers. Currently, when I run in debug mode I cannot see the phone number being populated. I am running the hibernate in springmvc framework and I am retrieving the employee through following code:

    @Override
    @SuppressWarnings("unchecked")
    public List<Employees> getEmployees() {
      // TODO Auto-generated method stub
      return getCurrentSession().createQuery("from Employees").list();
    }
    

    Is their anything extra I need to do to return the phone_numbers. My end goal is to display the employees and the phone number in a table format in the view.

    Thank you

    When I made the "fetch = EAGER" I tried to debug but I didnt see values. How do I make sure that it is pulling the phone data?

    List<Employees> _employees= employeeService.getEmployees();
            for (Employees o: _employees) {
                java.util.Set<PhoneNumber> a = o.getPhonenumbers();
            }
    

    I found the mistake that I had made but I am running into another issue. My mistake was that the employee_id field is the FK but it was not populated properly. However, this column is not the primary key in the phone_number table.

    I changed the phone_number to be following:

    @Entity
    @Table(name="phonenumber")
    public class Phonenumber {
    
    
        @EmbeddedId
        @ManyToOne(fetch=FetchType.EAGER)
        @JoinColumn(name = "EMPLOYEEID")
        private Employee employeeid;
    

    However, I am getting following error now: Caused by: org.hibernate.MappingException: Composite-id class must implement Serializable:

    I am able to get rid of this error but I am running into another interesting error. It is only selecting the first row in the phonenumber.

    @Entity
    @Table(name="phonenumber")
    public class Phonenumber implements Serializable {
    
        @Column(name="key")
        private String key;
    
        @Column(name="value")
        private String value;
    
        @Id
        @ManyToOne(fetch=FetchType.EAGER)
        @JoinColumn(name = "EMPLOYEEID")
        private Employee employee;
    

    Employee

    @Entity
    @Table(name="employee")
    public class Employee{
    
        @Id
        @GeneratedValue
        private Integer id;
    
        @OneToMany(mappedBy = "employeeid", fetch = FetchType.EAGER)
        private Set<Phonenumber> phonenumbers= new HashSet<Phonenumber>(0); 
    

    解决方案

    • Using HQL it could be achieved as follows:

      createQuery("from employee e left join fetch e.phonenumbers")

    • As alternative you could use EAGER loading. However, be very careful and consider implications. It could impact performance because it loads all related entities.


    There is no need in @JoinColumn because by means of mappedBy you said how you want to join entities. In most cases @JoinColumn used for uni-directional relationships or when you don't have mappedBy.

    Please remove @Id from employee column in Phonenumber and let id be primary key.

    @Entity
    @Table(name="phonenumber")
    public class Phonenumber implements Serializable {
    
        @Column(name="key")
        private String key;
    
        @Column(name="value")
        private String value;
    
        @Id
        @GeneratedValue
        private Integer id;
    
    
        @ManyToOne(fetch=FetchType.EAGER)
        private Employee employee;
    

    }

    这篇关于Hibernate onetoMany映射检索链中的所有结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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