0

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

例如,我有两个表:

1) employee
columns:
id
name

2) phone_number
columns:
employee_id(FK)
phone_number_type
phone_number

employee 和 phone_number 与(phone_number 中的employee_id 列充当 FK)具有一对多映射

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

@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; 
}

班级电话号码

@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;
}

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

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

他们是否需要做任何额外的事情来返回电话号码。我的最终目标是在视图中以表格格式显示员工和电话号码。

谢谢

当我制作“fetch = EAGER”时,我尝试调试,但没有看到值。如何确保它正在提取电话数据?

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

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

我将 phone_number 更改为:

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


    @EmbeddedId
    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name = "EMPLOYEEID")
    private Employee 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")
    private 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); 
4

5 回答 5

2

我遇到了同样的问题。通过允许休眠创建一个用作参考的新表来解决它

@OneToOne(fetch = FetchType.LAZY)
@JoinTable(name = "employee_phonenumber", 
    joinColumns = @JoinColumn(name = "empid"), 
    inverseJoinColumns = @JoinColumn(name = "phoneid"))
private Set<PhoneNumber> phonenumbers = new HashSet<PhoneNumber>(0);
于 2019-02-10T13:16:58.490 回答
1
  • 使用HQL它可以实现如下:

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

  • 作为替代方案,您可以使用EAGER loading. 但是,要非常小心并考虑影响。它可能会影响性能,因为它会加载所有相关实体。


没有必要,@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
    private Integer id;


    @ManyToOne(fetch=FetchType.EAGER)
    private Employee employee;

}

于 2013-09-17T20:26:07.117 回答
0

我最终添加了另一个名为“id”的列,它是员工的主键,这似乎解决了我遇到的问题。虽然我不特别喜欢它的解决方案。

于 2013-10-10T22:22:31.633 回答
0

您是否尝试过将 fetch 类型更改为 eager ?

FetchType.LAZY
to
FetchType.EAGER

您可以通过设置打开调试以显示正在执行的底层 sql 语句

<property name="show_sql">true</property>

在休眠配置中。用它来检查。

于 2013-09-17T19:46:11.487 回答
0

要填充 Phonenumber,您需要调用 employee.getPhonenumbers().size()。换句话说,phonenumber 集合仅在第一次访问时才会填充,而不是在加载employee 对象时填充。这种按需访问方式称为延迟加载,是 @OneToMany 和 @ManyToMany 关联的默认设置。

于 2016-03-03T17:49:17.127 回答