@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<EmployeeBean> employeeList;
or private Set<EmployeeBean> employeeList;
希望这对您有所帮助。
使用private List<EmployeeBean> 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 在休眠中的主要内容,如果未能解决你的问题,请参考以下文章