@OneToMany 在休眠中

Posted

技术标签:

【中文标题】@OneToMany 在休眠中【英文标题】:@OneToMany in hibernate 【发布时间】:2015-07-07 01:35:17 【问题描述】:

我有 2 个具有一对多关系的实体,即一个地址可以是多个员工。

mysql 数据库:

地址

address_id INT PK AutoIncr 城市 VARCHAR 国家/地区 VARCHAR

员工

id PK AutoIncr first_name VARCHAR last_name VARCHAR 电子邮件 VARCHAR registration_date 日期 employee_id INT FK

我在休眠中有以下实体,我想获取具有特定位置的所有员工的列表。

hibernate.cfg.xml

<mapping class="com.example.bean.EmployeeBean"/>
<mapping class="com.example.bean.AddressBean"/>

@Entity
@Table(name="ADDRESS")
public class AddressBean 

    @Id
    @GeneratedValue
    @Column(name="ADDRESS_ID")
    private int addressId;

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

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

    @OneToMany(mappedBy="EMPLOYEE")
    private ArrayList<EmployeeBean> employeeList;

    public int getAddressId() 
        return addressId;
    
    public void setAddressId(int addressId) 
        this.addressId = addressId;
    
    public String getCity() 
        return city;
    
    public void setCity(String city) 
        this.city = city;
    
    public String getCountry() 
        return country;
    
    public void setCountry(String country) 
        this.country = country;
    
    public ArrayList<EmployeeBean> getEmployeeList() 
        return employeeList;
    
    public void setEmployeeList(ArrayList<EmployeeBean> employeeList) 
        this.employeeList = employeeList;
    


@Entity
@Table(name="EMPLOYEE")
public class EmployeeBean 
    @GeneratedValue
    @Id
    @Column(name="ID")
    private int id;
    @Column(name="FIRST_NAME")
    private String firstName;
    @Column(name="LAST_NAME")
    private String lastName;
    @Column(name="EMAIL")
    private String email;
    @Column(name="REGISTRATION_DATE")
    private String registrationDate;

    public int getId() 
        return id;
    
    public void setId(int id) 
        this.id = id;
    
    public String getFirstName() 
        return firstName;
    
    public void setFirstName(String firstName) 
        this.firstName = firstName;
    
    public String getLastName() 
        return lastName;
    
    public void setLastName(String lastName) 
        this.lastName = lastName;
    
    public String getEmail() 
        return email;
    
    public void setEmail(String email) 
        this.email = email;
    
    public String getRegistrationDate() 
        return registrationDate;
    
    public void setRegistrationDate(String registrationDate) 
        this.registrationDate = registrationDate;
    

编译时出现以下错误.. 我哪里做错了?

Initial SessionFactory creation failed.org.hibernate.AnnotationException: Illegal attempt to map a non collection as a @OneToMany, @ManyToMany or @CollectionOfElements: com.example.bean.AddressBean.employeeList

【问题讨论】:

mysql sqlserver.请标记适当的技术 您的员工 bean 没有被注释为实体? 我抄错了..它被注释了。已编辑 @ImamBux 地址中有employee_ID 列吗? 我没有在数据库级别看到这两个表之间的任何引用。 【参考方案1】:

您应该使用集合接口。你的情况应该是

列表

而不是

数组列表

或者更好设置

所以这应该可以解决问题:

@OneToMany(mappedBy="EMPLOYEE")
private List<EmployeeBean> employeeList;

您也应该更改 bean 的其他部分。

【讨论】:

【参考方案2】:

您不能在 @OneToMany 关系中使用 Collection 的特定实现。

你有问题的部分是

private ArrayList<EmployeeBean> employeeList;

你必须使用

private List<EmployeeBean> employeeList;

还要注意List 也需要某种排序标准,因此最好使用Set

private Set<EmployeeBean> employeeList;

【讨论】:

【参考方案3】:

1°) 使用接口而不是实现:

private List<EmployeeBean> employeeList;

2°) 在 EmployeeBean 中 AddressBean 的列在哪里? 在地址豆中:

@OneToMany(mappedBy="address")
private List<EmployeeBean> employeeList;

在 EmployeeBean 中:

@ManyToOne(optional = false)
@JoinColumn(name = "ADDRESS")
private AddressBean address;

【讨论】:

【参考方案4】:

在您的代码中,您有两个问题:

第一个:表结构的设计。正如您提到的,多个员工可以有一个地址。所以员工表应该有一个带有address_id的列。因此,在您的 Employee 束中,您必须为此创建一个参考。

第二个:你必须 List 或 Set 而不是 Arraylist private ArrayList&lt;EmployeeBean&gt; employeeList;or private Set&lt;EmployeeBean&gt; employeeList;

希望这对您有所帮助。

使用private List&lt;EmployeeBean&gt; employeeList;

【讨论】:

【参考方案5】:

我建议进行以下更改

DB= 在员工表中添加外键 address_id。因为每个员工都应该有一个地址,一个地址可以映射到多个员工

地址

address_id INT PK AutoIncr 城市 VARCHAR 国家/地区 VARCHAR

员工

id PK AutoIncr first_name VARCHAR last_name VARCHAR 电子邮件 VARCHAR registration_date 日期 address_id INT FK, employee_id INT FK

如果您使用的是 Eclipse IDE,请使用 JPA TOOL 生成实体。

地址实体

@Entity
    @Table(name="ADDRESS")
    public class AddressBean 

        @Id
        @GeneratedValue
        @Column(name="ADDRESS_ID")
        private Integer addressId;

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

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

         //GETTER SETTER
    

员工实体

@Entity
    @Table(name="EMPLOYEE")
    public class EmployeeBean 
        @GeneratedValue
        @Id
        @Column(name="ID")
        private Integer id;

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

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

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

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

        @OneToMany(mappedBy="ADDRESS_ID")
        private List<Address> address;

        @Column(name="EMPLOYEE_ID")
        private List<EmployeeBean> employeeList;     //GETTER SETTER
    

现在您的 SQL 查询将如下所示:

SQL: 'Select * from Employee where Address_Id = 10'

【讨论】:

【参考方案6】:

SQL JOIN 子句用于根据它们之间的公共字段组合来自两个或多个表的行。 您必须在两个实体之间有一个公共列,才能让 Hibernate 为您加入表。

所以在EmployeeBean 中创建AddressBean 的引用

@Entity @Table(name="EMPLOYEE") public class EmployeeBean ....

@ManyToOne
@JoinColumn(name="ADDRESS_ID")
private AddressBean address_ID;

//getter setter

然后您可以使用您遵循的 watever 方法获取员工的地址,最简单的是 session.get(AddressBean.class,addressId); Hibernate 会在内部为您执行连接并返回特定员工的 AddressBean 对象。

此外,您可以关注this link 学习并使用 Hibernate 查询语言执行连接,以获取具有特定位置的所有员工的列表。

并且不需要将返回类型设置为集合的具体实现,在这种情况下为ArrayList。但是,即使您这样做,也没有任何问题。无论编译器抛出错误,您都必须将其转换为 (ArrayList)query.list(); 或类似的类型转换。尽管 Hibernate 的 JBoss 社区文档建议在处理连接时使用 Set 作为返回类型。选择权在你。

最后,我建议您在 AddressBean 类中添加@Cascade。添加 cascade = “all” 确保父类对象中的任何更改也将影响子类对象,并且对父对象的所有操作(如插入,删除,更新)也将强制子对象中的更改。 (参照完整性)

@OneToMany(mappedBy="EMPLOYEE")
@Cascade(org.hibernate.annotations.CascadeType.ALL) //ANNOTATION TO ADD
private ArrayList<EmployeeBean> employeeList;

【讨论】:

以上是关于@OneToMany 在休眠中的主要内容,如果未能解决你的问题,请参考以下文章

@OneToMany 在休眠中

无法在休眠中删除 OneToMany 关系的实例

@OneToMany 映射休眠中的集合

非冗余休眠列表映射 (OneToMany)

休眠 OneToMany 和 ManyToOne?

OneToMany 关系中的休眠标准