先把配置文件放上来:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.lj.zhang">
<class name="Order" table="test_order">
<id name="id">
<generator class="native"/>
</id>
<property name="name" column="test_name"/>
<many-to-one name="user" class="com.lj.zhang.User" column="customer_id"></many-to-one>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.lj.zhang">
<class name="User" table="test_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name" type="string" length="40" column="test_name"/>
<set name="orders" cascade="save-update" inverse="true">
<key column="customer_id"></key>
<one-to-many class="com.lj.zhang.Order"/>
</set>
</class>
</hibernate-mapping>
Main代码:
package com.lj.zhang;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;
import util.HibernateUtil;
public class HibernateTest4
{
@SuppressWarnings({ "unused", "unchecked" })
public static void main(String[] args)
{
Session session = HibernateUtil.openSession();
Transaction tx = null;
tx = session.beginTransaction();
// Query query = session.createQuery("from User");
// List<User> list=query.list();
User u=new User(1,"alleni");
Order o1=new Order(1,"o1",u);
Order o2=new Order(2,"o2",u);
Set<Order>orders=new HashSet<Order>();
orders.add(o1);
orders.add(o2);
// session.save(o);
u.setOrders(new HashSet<Order>());
u.getOrders().add(o1);
u.getOrders().add(o2);
session.save(u);
tx.commit();
session.close();
}
}
在运行之前, 数据库里面是没有任何相关的数据的。 当transaction.commit()的时候, hibernate会执行
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: insert into test_user (test_name, id) values (?, ?)
Hibernate: update test_order set test_name=?, customer_id=? where id=?
这里很意外的执行了一条update语句, 然后报错。
在网上找到了解决方案, 不过还是看了一下源码,想看看问题究竟出在哪里。可惜
没找到,但是学习到了一点点源码。。
解决方案 :http://hi.baidu.com/shirdrn/item/2fd8bc0abc8bc56ed45a11af
---------------------------------------
在ActionQueue里面有这个executeActions()方法,
它对所有的dml相关的内容进行执行操作。
private void executeActions(List list) throws HibernateException {
for ( Object aList : list ) {
execute( (Executable) aList );
}
list.clear();
session.getTransactionCoordinator().getJdbcCoordinator().executeBatch();
}
下个图是关于这些list参数的, 可以看到, 我们的Order对象, 原本是应该被插入到数据库里并和User实现级联的,可是这里却被直接放入了updates的集合中。
结果就出发了update的sql语句。
==========================================
当把Order的id生成方式改成
<generator class="assigned"/>
Order对象便被放入了inserts集合对象中, 最终也就触发了insert语句的执行。
仅仅改变了一个identifier的生成方式就导致这样, 到底是为什么?