日期:2014-05-20  浏览次数:20812 次

Hibernate的rollback不起作用?
单向一对一外键关联
XML code

<hibernate-mapping package="com.example.hibernate">
    <class name="IdCard" table="t_idcard">
        <id name="id">
            <generator class="native" />
        </id>
        <property name="cardNo" unique="true"/>
    </class>
</hibernate-mapping>


XML code

<hibernate-mapping package="com.example.hibernate">
    <class name="Person" table="t_person">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
        <many-to-one name="idCard" unique="true"/>
    </class>
</hibernate-mapping>



测试代码
Java code

        Session session = null;
        Transaction tx = null;
        try {
            session = HibernateUtils.getSession();
            tx = session.beginTransaction();
            
            IdCard idCard = new IdCard();
            idCard.setCardNo("78383");
            
            Person person = new Person();
            person.setName("tom");
            person.setIdCard(idCard);
            
            session.save(person);
            tx.commit();
        }
        catch(Exception e) {
            e.printStackTrace();
            tx.rollback();
        }
        finally {
            HibernateUtils.closeSession(session);
        }


HibernateUtils是工具类

这段代码执行到tx.commit();的时候会抛出exception,错误是object references an unsaved transient instance
因为person.setIdCard(idCard);中,idCard没有持久化
但是在rollback后,数据库里还是会插入了一条person记录
id name idCard  
1 tom NULL 

实在找不出是什么原因,是不是我的mysql配置问题?

另外,如果我给两个person保存相同的idCard,即当前的idCard在person表已经有引用,违背了唯一性
那么程序执行到session.save(person);会抛异常,rollback会成功
这又是为什么

------解决方案--------------------
如果你的Exception出现在commit以后,rollback就不会起作用了
你在save person之前save一下ID Card应该就没问题了

------解决方案--------------------
探讨
其实问题就出在
第一种情况执行完commit时才挂掉
第二种情况执行完session.save的时候就挂了