loading ...
loading...

2006-09-04 | JPA的一对多关系(7)

分享

弄了半天,终于在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次查询问题?存疑

分享 分享 |  评论 (0) |  阅读 (?)  |  固定链接 |  类别 (Java) |  发表于 06:44
搜狐博客温馨提示:搜狐博客官方不会要求参加活动的各位博友缴纳任何的手续费用。请勿轻信留言、评论中的中奖信息,更不要拨打陌生电话及向陌生帐户汇款,谨防受骗!识别更多网络骗术,请 点击查看详情
您还未登录,只能匿名发表评论。或者您可以 登录 后发表。
 
  *中国人爱国心,搜狗输入法爱国主题皮肤下载>>
表  情:
加载中...
回复通知: 同时用小纸条通知对方该回复