最近遇到了一个  one to one hibernate  多表级联update问题:
先把我的三个表:
Member,Car,Customer Member.hbm.xml
<hibernate-mapping>
    <class name="com.dbw.mps.pojo.Member" table="member" schema="dbo" catalog="mpdb">
        <id name="memberId" type="java.lang.Integer">
            <column name="member_id" />
            <generator class="native" />
        </id>
.......
  <one-to-one name="customer" class="com.dbw.mps.pojo.Customer"  cascade="delete,save-update"  property-ref="member"/>
  <one-to-one name="car" class="com.dbw.mps.pojo.Car"   cascade="delete,save-update" property-ref="member"/>   
    </class>
</hibernate-mapping>
和Member.java
public class Member implements java.io.Serializable { private static final long serialVersionUID = 3060858285446588346L;
private Integer memberId;
         private String memo;
private Car car;
private Customer customer;
}
getter setter就省略了。
Car.hbm.xml
<hibernate-mapping>
    <class name="com.dbw.mps.pojo.Car" table="car">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="native" />
        </id>
    .......
     <many-to-one name="member" class="com.dbw.mps.pojo.Member"  unique="true" >
            <column name="member_id" />
        </many-to-one>
   </class>
</hibernate-mapping>
Car.java
public class Car implements java.io.Serializable {
private static final long serialVersionUID = -294719602563257129L;
private Integer id;
private Member member;
......getter setter就省略了。
}
Customer.hbm.xml
<hibernate-mapping>
    <class name="com.dbw.mps.pojo.Customer" table="customer">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="native" />
        </id>
       
         <many-to-one name="member" class="com.dbw.mps.pojo.Member"  unique="true">
            <column name="member_id" />
        </many-to-one>
   </class>
</hibernate-mapping>
Customer.java
public class Customer implements java.io.Serializable {
private static final long serialVersionUID = 762089766198361560L;
private Integer id;
private Member member;
......getter setter就省略了。
}我在MemberDAOImpl.java中进行了Update操作:
public void updateMember(Member o,Car car,Customer customer) throws DataAccessException {
Session session=this.getSession();
try{
session.getTransaction().begin();
o.setCar(car);
o.setCustomer(customer);
session.update(o);  
}
catch(Exception e){
session.getTransaction().rollback();
e.printStackTrace();
}
finally{

} }
我想要的结果是session.update(o);修改member表的内容 同时也要修改Customer和Car表中相应的内容。
但是结果查看Sql2000的表的时候  发现member表的内容是修改了,但是Car和Customer表的对应的外键关联的记录发生异样。就是  Car和Customer 又重新添加了新的一条记录。原本的要修改的记录没变化,手写的数据库记录如下:
下面是Car表的  (Customer表也一样)
id | member_id |.....
48 | 41        |....该记录是原记录(本要修该,实际上没有变化)
52 |  null     |....该记录是点击修改时,插入的记录
在控制台发现输出语句是:
Hibernate: insert into customer (member_id, licence_type, next_date, validate_period, name, gendor, birthday, mobile, phone, fax, certificate, certificate_no, post_address, work_unit, career, address, post_code, urgent_contact, urgent_mobile, urgent_phone, status, memo) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into car (car_no, model_id, color, engine_no, is_self, identify_no, register_date, buy_price, capacity, consume_remind, consume_period, next_maitain, current_kilometer, insurance_man, insurance_no, insurance_type, insurance_begin, insurance_end, insurance_period, insurance_company, insurance_content, status, memo, member_id) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: update mpdb.dbo.member set card_no=?, enter_date=?, level_id=?, remind=?, interest=?, org_id=?, operator_id=?, owner_id=?, last_update=?, status=?, memo=? where member_id=?
原来先执行了insert语句 在执行update语句。
我想问的是:按理说应该先Update member 在car ,customer啊而不是insert。
one to one 中的cascade="delete,save-update"  作用体现级联修改 删除  增加啊。
我本人刚学hibernate几个月,不懂的多。
如果遇到相似问题的朋友或者高手,请指点迷津。谢谢!

解决方案 »

  1.   

    你的car 和 customer 有没有这两个要更新的对象有没有ID值的呀
      

  2.   

    谢了 发现Card,Customer的主键id值没有在js保存传递给car  和customer对象。我加了以后,控制台执行了:
    Hibernate: update mpdb.dbo.member set card_no=?, enter_date=?, level_id=?, remind=?, interest=?, org_id=?, operator_id=?, owner_id=?, last_update=?, status=?, memo=? where member_id=?
    Hibernate: update customer set member_id=?, licence_type=?, next_date=?, validate_period=?, name=?, gendor=?, birthday=?, mobile=?, phone=?, fax=?, certificate=?, certificate_no=?, post_address=?, work_unit=?, career=?, address=?, post_code=?, urgent_contact=?, urgent_mobile=?, urgent_phone=?, status=?, memo=? where id=?
    Hibernate: update car set car_no=?, model_id=?, color=?, engine_no=?, is_self=?, identify_no=?, register_date=?, buy_price=?, capacity=?, consume_remind=?, consume_period=?, next_maitain=?, current_kilometer=?, insurance_man=?, insurance_no=?, insurance_type=?, insurance_begin=?, insurance_end=?, insurance_period=?, insurance_company=?, insurance_content=?, status=?, memo=?, member_id=? where id=?
    对了,我原先的DAO接口实现方法,有点问题。
    修改如下:
    public void updateMember(Member o,Car car,Customer customer) throws DataAccessException {
    // TODO Auto-generated method stub
    Session session=this.getSession();
    try{
    session.getTransaction().begin();
            car.setMember(o);//修改的代码
    customer.setMember(o);//修改的代码
    o.setCar(car);
    o.setCustomer(customer);
    session.update(o);
           

    }
    catch(Exception e){
    session.getTransaction().rollback();
    e.printStackTrace();
    }
    finally{

    } }
    如果按照之前的话,虽然都执行了三条update语句。但是在car和customer对应的memberId字段值会为空!
    修改为上面就可以了。我参照BLog:http://ttitfly.javaeye.com/blog/159958#comments
    具体为什么,不是真的理解。我还得仔细学习!
    不管怎么样,你的建议让我豁然开朗,不然我现在还在思考是不是 映射文件的问题,谢了!