hibernate one2one 唯一外键关联(单向关联)

hibernate一对一唯一外键关联映射(person --> idcard)

一对一唯一外键关联其实是多对一的特例,采用<many-to_one>标签来映射,指定多的一端unique为true,这样就限制了多的一端的多重性唯一。

person.hbm.xml

<?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.cnblogs.hibernate_first">
    <class name="Person" table="t_person">
        <id name="id" column="t_id">
        <!-- 采用foreign生成测录,foreign可以取到关联对象的标识 -->
            <generator class="native">
            </generator>
        </id>
        <property name="name" column="t_name"></property>
        <many-to-one name="idCard" unique="true"></many-to-one>
    </class>
</hibernate-mapping>

Test

public void testSave1() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            IdCard idCard = new IdCard();
            idCard.setCardNo("1111111111111111111");
            Person person = new Person();
            person.setName("张三");
            person.setIdCard(idCard);
            /*抛出java.lang.IllegalStateException: org.hibernate.TransientObjectException: object 
            references an unsaved transient instance - save the transient instance beforeQue
            ry flushing 
            因为idcard是Transient状态,没保存,所以炮异常,只要保存即可
            */
            session.save(person);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        } finally {
            HibernateUtils.closeSession(session);
        }
    }
    public void testSave2() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            IdCard idCard = new IdCard();
            idCard.setCardNo("1111111111111111111");
            session.save(idCard);
            Person person = new Person();
            person.setName("张三");
            person.setIdCard(idCard);
            session.save(person);
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        } finally {
            HibernateUtils.closeSession(session);
        }
    }

    
    public void testLoad1() {
        Session session = null;
        try {
            session = HibernateUtils.getSession();
            session.beginTransaction();
            Person person = session.load(Person.class, 2);
            System.out.println("Person.name = " + person.getName());
            System.out.println("Pserson.cardNo = " + person.getIdCard().getCardNo());
            session.getTransaction().commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.getTransaction().rollback();
        } finally {
            HibernateUtils.closeSession(session);
        }
    }
}

save1()报错:

Caused by: org.hibernate.TransientObjectException: object references an unsaved
transient instance - save the transient instance beforeQuery flushing: com.cnblo
gs.hibernate_first.IdCard

load1()输出结果:

Hibernate: alter table t_person add constraint FKmwhwiyh1l4gnux6mfegyx5ki8 forei
gn key (idCard) references t_idcard (t_id)
Hibernate: select person0_.t_id as t_id1_1_0_, person0_.t_name as t_name2_1_0_,
person0_.idCard as idCard3_1_0_ from t_person person0_ where person0_.t_id=?
Person.name = 张三
Hibernate: select idcard0_.t_id as t_id1_0_0_, idcard0_.t_cardNo as t_cardNo2_0_
0_ from t_idcard idcard0_ where idcard0_.t_id=?
Pserson.cardNo = 1111111111111111111

posted @ 2017-10-21 14:42  错莫难瞒  阅读(175)  评论(0编辑  收藏  举报