弄了半天,终于在JBoss上把一对多关系的例子搞定,一开始出现的莫名其妙的错误在俺重装了Jboss后消失不见:)
一对多关系分两种,单向和双向.首先,先看看单向一对多的例子,比如Company和Employee的关系就是典型的一对多关系:
//Company.java
package com.denny_blue.ejb3.relationships;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
public class Company implements Serializable {
private Integer id;
private String name;
private Set<Employee> employees;
public Company() {
}
@OneToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
public Set<Employee> getEmployees() {
return employees;
}
public void setEmployees(Set<Employee> employees) {
this.employees = employees;
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
这里的@One-To-Many注释就建立了与Employee的一对多关系,当然这里是Set,也可以是其他集合类型,值的注意的是fetch属性,这个其实与Hibernate的延迟加载相同的概念,FetchType两个值:LAZY和EAGER.顾名思义就是对集合采用何种加载策略,默认状态是LAZY.我们取强制加载.
再来看看Employee.java
package com.denny_blue.ejb3.relationships;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
@Entity()
public class Employee implements Serializable {
private Integer id;
private String name;
private char sex;
public Employee() {
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
}
因为是单向一对多,此类中就没有@Many-To-One注释.单向一对多JPA会在数据库中自动建立一张中间表,比如此例中将生成的中间表名为company_employee,此表中两个字段:company_id和employee_id.JPA通过此中间表来对两者关系进行映射.
将此单向一对多的例子修改为双向很简单,首先在Company类中的@One-To-Many增加一个mappedBy属性即可:
@OneToMany(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER,mappedBy="company")
public Set<Employee> getEmployees() {
return employees;
}
mappedBy指定了关联的外键.所谓双向一对多其实是去掉中间表,在多的一方(也就是Employee)中增加一个company_id作为外键关联.Employee只要增加一个Company属性即可:
private Company company;
@ManyToOne
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
两种一对多关系的更新保存上的不同也是显而易见,对于双向一对多,你必须同时设置Employee的company和Company的employees,单向就仅仅只要设置Company的employees.
如果说有比较意外的发现,就是似乎JPA并未如hibernate那样考虑一个inverse的问题,也就是把主控方交给哪一方的问题,双向一对多只要如上那样配置即可,难道不会遇到n+1次查询问题?存疑
![]() |
谢亚龙逼女足姑娘作检讨(图)
“安静”为啥成裁判口头语?
姚明私下发给刘翔的短信
|
![]() |
曝光:姚明小时候与可爱女生合影(图) 组图:隋菲菲私家相册 率性美感领衔女篮 |
![]() |
![]() |
![]() |


档案
日志
相册
视频








评论
想第一时间抢沙发么?