我想问一个hibernate里关于多对多的问题

我有两个 Persistent Classes ,一个是书,一个是人,人可以拥有多本书,书也可以属于多个人,一个很简单的结构

我只是先学学如何使用hibernate,就写了以下hxm文件:

Book:


<hibernate-mapping>
<class name="net.magician.test.testhibernate.bean.Book" table="book">
<id name=
"bookID" column="bookid" type="int" unsaved-value="null">
<generator class=
"identity"/>
</id>

<list name=
"persons" table="bookperson" inverse="true" lazy="true">
<key column=
"bookid" />
<index column=
"personid" />
<many-to-many column=
"personid" class="net.magician.test.testhibernate.bean.Person" />
</list>

</class>

</hibernate-mapping>

Person:


<hibernate-mapping>
<class name="net.magician.test.testhibernate.bean.Person" dynamic-update="false" dynamic-insert="false">
<id name=
"personID" column="personid" type="int" unsaved-value="null">
<generator class=
"identity"/>
</id>

<list name=
"books" table="bookperson" inverse="true" lazy="true">
<key column=
"personid" />
<index column=
"bookid" />
<many-to-many column=
"bookid" class="net.magician.test.testhibernate.bean.Book" />
</list>
</class>
</hibernate-mapping>

然后写了一个测试方法:


private static void testCreateBookAndPerson() throws Exception
{
Collection persons = new ArrayList);
Book book = new Book();
book.setBuyTime(new Date());
for (int i=100;i<110;i++)
{
Person ptemp = (Person)session.load(Person.class , new Integer(i));
persons.add(ptemp);
}
book.setPersons(persons);
session.save(book);
}

person表已经有足够的数据

但我执行该方法时,book会成功插入数据库,但bookperson这个中间表里什么数据也没有

这里是SchemaExport生成的表文件:


create table book (
bookid INTEGER NOT NULL AUTO_INCREMENT,
primary key (bookid)
)

create table bookperson (
personid INTEGER not null,
bookid INTEGER not null,
primary key (bookid, personid)
)

create table Person (
personid INTEGER NOT NULL AUTO_INCREMENT,
primary key (personid)
)

希望高手能帮忙解决一下

顺带提一个小问题,为什么update方法一定要用tx.commit()来完成操作?而其他的不用?我把update和insert都设为ture了,比如:


<hibernate-mapping>
<class name="net.magician.test.testhibernate.bean.Province" dynamic-update="true" dynamic-insert="true">
<id name=
"provinceID" column="provinceid" type="int" unsaved-value="null">
<generator class=
"identity"/>
</id>

<property name=
"provinceName" type="java.lang.String" update="true" insert="true" column="provincename" length="20" />
</class>
</hibernate-mapping>

多谢各位了

两个class mapping中inverse都为"true"??


如果update="false" insert="false"表明这个属性不会出现在insert,update语句中,即这是一个可以由其他持久属性得到的属性。

为什么update方法一定要用tx.commit()来完成操作?而其他的不用?
不大明白你的意思!
添加记录用save()(最后也要commit()),
而更新的话分两种情况:
1:对象在同一个session中load进来的话,直接commit()就行了
2:对象在上一个session中load进来的话,先update()(或saveOrUpdate()),再commit()

摘录
两个class mapping中inverse都为"true"??

这两个都设为true有什么问题吗?

摘录
不大明白你的意思!
添加记录用save()(最后也要commit()),
而更新的话分两种情况:
1:对象在同一个session中load进来的话,直接commit()就行了
2:对象在上一个session中load进来的话,先update()(或saveOrUpdate()),再commit()

我的代码里是从同一个session里load进来,然后update的
同时,我试过使用update和或saveOrUpdate(),都无法更新数据
除非我在开头和结尾分别加上Transaction t = session.beginTransaction()、t.commit()
而我如果是新增一个条数据则无需如此,直接save即可

你能帮忙看看问题出在哪吗?

千万别告诉我你用的是mysql还不是max..

非常不幸,是MYSQL

不过是MAX-NT

写操作都要放在事务中吧?!

inverse的问题你看看hibernate doc中有关bidirectional refrence
那部分吧。

可为什么我调用SAVE方法,不用放在事务中呢?

比如


private static void testInsert() throws Exception
{
Province province = new Province();
province.setProvinceName("某省份");

session.save(province);
}

上面的代码运行是没有任何问题的,这也是我疑惑的地方

多谢你的指点,我继续看看文档

你写的那个testCreateBookAndPerson() 中代码要用集合去操作,而不是简单的两边set一下,建议先把一对多搞定再多对多。