多对多连接表双向关联时:只能有一端的<set>放入属性inverse="true",之后Session.save()时,首先保存哪个端POJO均可,当另一端的POJO必须调用saveOrUpdate()进行相应的链接和连接表的更新。
示例:
一个Person可以有多个Address,一个Address可以有多个Person。利用连接表进行双向链接:
数据库表:
CREATE TABLE `address_nn_sx` (
`addressid` int(11) NOT NULL auto_increment,
`addressdetail` varchar(255) default NULL,
PRIMARY KEY (`addressid`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
CREATE TABLE `person_nn_sx` (
`personid` int(11) NOT NULL auto_increment,
`name` varchar(255) default NULL,
`age` int(11) default NULL,
PRIMARY KEY (`personid`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
CREATE TABLE `join_nn_sx` (
`addressid` int(11) NOT NULL,
`personid` int(11) NOT NULL,
PRIMARY KEY (`personid`,`addressid`),
KEY `FK6EBBC5EF6C600921` (`personid`),
KEY `FK6EBBC5EF2A92FF3D` (`addressid`),
CONSTRAINT `FK6EBBC5EF2A92FF3D` FOREIGN KEY (`addressid`) REFERENCES `address_nn_sx` (`addressid`),
CONSTRAINT `FK6EBBC5EF6C600921` FOREIGN KEY (`personid`) REFERENCES `person_nn_sx` (`personid`)
) ENGINE=InnoDB DEFAULT CHARSET=gbk;
POJO(省去getter,setter):
public class Personnn_sx {
private int personid;
private String name;
private int age;
private Set addresses=new HashSet();
public class Addressnn_sx {
private int addressid;
private String addressdetail;
private Set persons = new HashSet();
hbm.xml:
<hibernate-mapping>
<class name="com.Addressnnsx" table="address_nn_sx">
<id column="addressid" name="addressid" type="int">
<generator class="identity"/>
</id>
<property name="addressdetail" column="addressdetail" type="string"/>
<set name="persons" table="join_nn_sx">
<key column="addressid"/>
<many-to-many column="personid" class="com.Personnnsx"/>
</set>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.Personnnsx" table="person_nn_sx">
<id column="personid" name="personid" type="int">
<generator class="identity"/>
</id>
<property name="name" column="name" type="string"/>
<property name="age" column="age" type="int"/>
<set table="join_nn_sx"
name="addresses" cascade="all" inverse="true">
<key column="personid"/>
<many-to-many class="com.Addressnnsx"
column="addressid"/>
</set>
</class>
</hibernate-mapping>
Test Main:
public class Test_nn_sx {
public static void main(String args[]){
Addressnnsx add1=new Addressnnsx();
Addressnnsx add2=new Addressnnsx();
Personnnsx p1=new Personnnsx();
Personnnsx p2=new Personnnsx();
add1.setAddressdetail("郑州市经三路");
add2.setAddressdetail("合肥市宿州路");
p1.setName("wang");
p1.setAge(30);
p2.setName("zhang");
p2.setAge(22);
add1.getPersons().add(p1);
add2.getPersons().add(p1);
add2.getPersons().add(p2);
p1.getAddresses().add(add1);
p1.getAddresses().add(add2);
p2.getAddresses().add(add2);
Session session= HibernateUtil.getSession();
Transaction tx=session.beginTransaction();
session.save(add1);
session.save(add2);
session.saveOrUpdate(p1);
session.saveOrUpdate(p2);
//session.save(p1);
//session.save(p2);
//session.saveOrUpdate(add1); //上面的save()已经对相应的address进行插入操作,故这里必须检查相应的表是否需要更新再保存
//session.saveOrUpdate(add2);
tx.commit();
HibernateUtil.closeSession();
}
}