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