hibernate映射-双向n-n关联关系
- 双向n-n关联需要两端都使用集合属性
- 双向n-n关联必须使用连接表
- 集合属性应增加key子元素用以映射外键列,集合元素里还应增加many-to-many子元素关联实体类
- 在双向n-n关联的两边都需指定连接表的表名及外键列的列名。两个集合元素set的table元素的值必要指定,而且必须相同。set元素的两个子元素:key和many-to-many都必须指定column属性,其中,key和many-to-many分别指定本持久层类和关联类在连接表的外键列名,因此两边的key与many-to-many的column属性交叉相同。也就是说,一边的set元素的key的column值为a,many-to-many的column为b;则另一边的set元素的column值为b,many-to-many的column值为a.
- 对于双向n-n关联,必须把其中一端的inverse设置为true,否则两端都维护关联关系可能会造成主键冲突。
一、代码示例:
Category.class
package com.zit.hibernate.n2n.both;
import java.util.HashSet;
import java.util.Set;
public class Category {
private Integer id;
private String name;
private Set<Item> items = new HashSet<>();
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 Set<Item> getItems() {
return items;
}
public void setItems(Set<Item> items) {
this.items = items;
}
}
Item.classpackage com.zit.hibernate.n2n.both;
import java.util.HashSet;
import java.util.Set;
public class Item {
private Integer id;
private String name;
private Set<Category> categories = new HashSet<>();
public Set<Category> getCategories() {
return categories;
}
public void setCategories(Set<Category> categories) {
this.categories = categories;
}
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;
}
}
映射文件
Category.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2015-12-25 13:55:35 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="com.zit.hibernate.n2n.both">
<class name="Category" table="CATEGORIES">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<set name="items" table="CATEGORIES_ITEMS">
<key>
<column name="C_ID" />
</key>
<many-to-many class="Item" column="I_ID">
</many-to-many>
</set>
</class>
</hibernate-mapping>
Item.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2015-12-25 13:55:35 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="com.zit.hibernate.n2n.both">
<class name="Item" table="ITEMS">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<set name="categories" table="CATEGORIES_ITEMS" inverse="true">
<key>
<column name="I_ID"></column>
</key>
<many-to-many class="Category" column="C_ID">
</many-to-many>
</set>
</class>
</hibernate-mapping>
在Item与Category映射文件的配置中,两者应该交叉相同。如下:
Category.hbm.xml
<set name="items" table="CATEGORIES_ITEMS">
<key>
<column name="C_ID" />
</key>
<many-to-many class="Item" column="I_ID">
</many-to-many>
</set>
Item.hbm.xml
<set name="categories" table="CATEGORIES_ITEMS" inverse="true">
<key>
<column name="I_ID"></column>
</key>
<many-to-many class="Category" column="C_ID">
</many-to-many>
</set>
(务必注意,双向多对多映射文件中,必须把其中一端的inverse设置为true,不让两端都维护关联关系,不然会造成主键冲突)
二、使用注意:
1.注意映射文件的配置。