概述
一个实体里面是可以配置多个映射关系的,也就是说同一个实体里面既能够配置@OneToMany同时也可以存在@ManyToOne(这条是废话,直接略过即可);
映射关系配置时@JoinColumn的配置十分关键,一般只要配置name和referencedColumnName两个属性,前面一个对应本表的外建列名,后面一个对应关系表中的主键列名;
在配置@OneToMany关系映射的时候,@OneToMany里面除了加targetEntity外还要加入fetch属性,fetch是用于配置该Set<>集合是否延迟加载的,如果不配置默认情况下fetch的值为FetchType.Lazy,也就是延迟加载,这里要配置成立即加载FetchType.EAGER,不然会报下面这个异常,记住一点集合属性要立即加载,不然之后可能出异常
案例
这里以菜单的案例来做例子,菜单数据库表中每个字段都存有父表的id,如果要取到指定id的菜单的父表和子表集合怎么配置呢,如下:
package com.sunsharing.po;
import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
/**
* Created by bozutung on 3/28/16.
*/
@Entity
@Table(name = "t_menu")
public class Menu {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String lable;
private String url;
@ManyToOne(targetEntity = Menu.class)
@JoinColumn(name = "superMenu", referencedColumnName = "id")
private Menu superMenu;
private Integer type;
private String note;
@OneToMany(targetEntity = Menu.class, fetch = FetchType.EAGER)
@JoinColumn(name = "superMenu", referencedColumnName = "id")
private Set<Menu> subMenus = new HashSet<Menu>();
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLable() {
return lable;
}
public void setLable(String lable) {
this.lable = lable;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Menu getSuperMenu() {
return superMenu;
}
public void setSuperMenu(Menu superMenu) {
this.superMenu = superMenu;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public Set<Menu> getSubMenus() {
return subMenus;
}
public void setSubMenus(Set<Menu> subMenus) {
this.subMenus = subMenus;
}
}
注意:这里千万不要傻傻的用idea或者eclipse集成的自动生成toString的功能 重写实体类的方法,这样会stackoverflow的,打印子菜单和父菜单,然后子菜单又有父菜单(就是菜单自身),这样就出现死循环了,而且循环越来越多。