多对一 单向关联 匹配 关系数据库中的外键参照关系


多对一 单向关联 匹配 关系数据库中的外键参照关系
2008-09-06 12:22
映射 多对一 单向关联 [原创 2007-02-07 15:14:44]   

读完 Java对象持久化技术详解6.1节,写一下读书笔记:

    多对一 单向关联 匹配 关系数据库中的外键参照关系。

     在关系数据库中,只存在外键参照关系,而且是由many--->one,是单向关联。

    以Customer和Order为例。

 

        单向关联中,Order中包含一个customer属性。这样定义了一个Order到Customer的关联,是多对一的。Customer中未包含Order属性.

       在Order.hbm.xml中,要进行关联映射Order类与ORDERS表。

       查看更多精彩图片         查看更多精彩图片

单向关联中,Order中包含一个customer属性。这样定义了一个Order到Customer的关联,是多对一的。Customer中未包含Order属性.

       在Order.hbm.xml中,要进行关联映射Order类与ORDERS表。

       查看更多精彩图片         查看更多精彩图片

         id------ID         customer------CUSTOMER_ID

         映射 customer------CUSTOMER_ID需要 使用 many-to-one

        many-to-one用来建立customer属性和ORDERS表的外键CUSTOMER_ID之间的映射

         <many-to-one

                name = "customer"        //待映射的持久化类的属性名

               column = "CUSTOMER_ID"   //设定和该属性对应的表的外键

               class = "Customer"        //设定该属性的类型

                not-null = "true"         //表示customer属性不能为null,默认为false

               cascade = "all"          //级联更新与Order类对象相关联的对象

        />

       一个概念:

       临时对象(transient)

                刚刚通过new( )创建,并且未被持久化的对象。

               Customer customer = new Customer();   //transient

                session.save(customer); //执行完该语句后,customer成为持久化对象

 

     //------------------不同的配置出现的不同情况-----------------------

    cascade取默认值的情况

      <many-to-one

     Order order = new Order();

     order.setCustomer(customer);

     session.save(order);

      Hibernate持久化order时, 不会自动持久化与其相关联的其他对象,因为没有显示设置cascade属性的相关值。

     这样cascade取默认值none,当持久化order时,会执行类似如下语句:

     insert into ORDERS (ID,CUSTOMER_ID) values (1,null )

    这违反了数据库完整性约束,因为ORDERS表中设置的CUSTOMER_ID为 not null

   抛出异常:

      net.sf.hibernate.PropertyValueException: not-null property references a null or transient

     value: Order.customer

    删除 not-null = "true"后,

     会把order与customer一起持久化。

      insert into CUSTOMERS(ID,NAME) values( 1 , " haha")

     insert into ORDERS( ID, CUSTOMER_ID) values (1,1 )

     

 

      <many-to-one

     Order order = new Order();

     order.setCustomer(customer);

     session.save(order);

      Hibernate持久化order时,

    insert into ORDERS (ID,CUSTOMER_ID) values (3,null )

      这次成功持久化了order对象,不再抛出PropertyValueException,因为ORDERS表的CUSTOMER_ID允许null值出现

     但当Hibernate自动清理(flush)缓存中所有持久化对象时,抛出新的异常:

    net.sf.hibernate.TransientObjectException: object references an unsaved transient instance -

    save the transient instance before flushing: Customer

     flush -- Hibernate按照内存中持久化对象的状态 来同步更新数据库.

     Hibernate发现持久化对象order引用transient对象customer,而ORDERS表中相应的记录的

     CUSTOMER_ID字段为null,也就是说内存中的持久化对象的状态与数据库中的记录不一致。

     而且在这种情况下,Hibernate没办法使两者同步,因为Hibernate不会自动持久化customer对象,

     所以,Hibernate抛出 TransientObjectException异常。

    这时需要设置cascade属性来解决问题

      <many-to-one

                name = "customer"        //待映射的持久化类的属性名

               column = "CUSTOMER_ID"   //设定和该属性对应的表的外键

               class = "Customer"        //设定该属性的类型

               cascade = "save-update"           //当保存或更新当前对象时

                                                          //级联保存或更新与Order类对象相关联的对象

        />

       这样当执行

       Customer customer = new Customer();   //transient

      customer.setName("haha");

       Order order = new Order();

      order.setCustomer(customer);

      session.save(order);

 

                name = "customer"         //待映射的持久化类的属性名

               column = "CUSTOMER_ID"   //设定和该属性对应的表的外键

               class = "Customer"        //设定该属性的类型

        />

    Customer customer = new Customer();    //transient

 

                name = "customer"         //待映射的持久化类的属性名

               column = "CUSTOMER_ID"   //设定和该属性对应的表的外键

               class = "Customer"        //设定该属性的类型

                not-null = "true"         //表示customer属性不能为null,默认为false

        />

    Customer customer = new Customer();    //transient

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值