ddf168913
2009-07-11 11:24 阅读 183
已采纳

one-to-many为什么会发出多余的update?

对one-to-many当在一的一端维护关系,为什么会发出多余的update.不论是是先保存一的一端,还是多的一端,

对于对象在内存的这种关系,很是模糊,想想有时候明白,可有说不清楚

一的一端维护关系和多的一端维护关系本质区别在哪里?
[b]问题补充:[/b]
但最好的办法,是设成独立的不要设成one-many形式
能说清楚点吗?怎样维护他们关系呢?
[b]问题补充:[/b]
xuzhfa123 :(

[color=red]关联关系维护分为主控方、被动方,对于一对多,每次持久化数据时,是不是都要先存储被动方的数据,[/color]
对T_user T_address

关联关系由一的一端T_User维护时
先存储T_address(被动方),这是userId为null
再存储T_user
再Update T_address

关联关系由多的一端T_address维护时
先存储T_user(被动方),
再存储T_address,useId直接赋值就ok了,
无需要Update

是这样的吗?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

5条回答 默认 最新

  • 已采纳
    liyistudio liyistudio 2009-07-12 15:11

    关联关系,有单向与双向之分的.
    单向:产系设在那方就由那方维护
    双向:像一对多,多对多关联.如里inverse设成true.就由对方维护表之间的关联关系.像你说的先增加从表,再增加主表,这样做应该不理吧.例如:增加A用户时,你没有职业,你肯定会用"暂无"取代吧,而不会像你那样赋个NULL吧.

    总结一下:
    如果是一对一外建关联时,你是先增加主表记录(父表),再由增加从表(子表)记录.
    如果多对一时,增加顺序一样.但关联关系那由主控方维护.也就是说当你删除T_Address表里一条记录时,T_User表会自动去维护这种关系.讲扩展一点.如是主控方中cascade="all",
    那么与T_Address记录有关的用户全部干掉啦.如里还是很明白,请买一本hibernate书看看.

    点赞 评论 复制链接分享
  • wanghaolovezlq wanghaolovezlq 2009-07-11 11:28

    这就是hibernate内部的机制了,
    不然它怎么推荐让多的一端维护关系呢
    这个机制和先保存哪一方没关系

    有兴趣就去研究下hibernate的部分源码

    点赞 评论 复制链接分享
  • make0620 make0620 2009-07-11 11:46

    在一段维护关系时,可以说关联到的东西比较多,前期的准备比较多,就像先有的你爸爸,才有的你。

    点赞 评论 复制链接分享
  • weixin_42297497 weixin_42297497 2009-07-11 11:53

    建议不要用one-many,这样你更新的时候与之相关的都会更新的。不过你也可以设置不让级连更新。但最好的办法,是设成独立的不要设成one-many形式

    点赞 评论 复制链接分享
  • liyistudio liyistudio 2009-07-11 22:40

    4.4.2 一对多关联

    一对多关联在系统实现中非常见。在我们现在的这个示例中,每个用户(TUser)都关联到多个地址(TAddress),如一个用户可能拥有办公室地址、家庭地址等多个地址属性。这样,在系统中,就反映为一个“一对多”关联。
    4.4.2.1单向一对多关联

    首先,我们从一个实例入手。

    主控方(TUser)映射配置如下:

    TUser.hbm.xml

       <class
    
              name=”com.redsaga.hibernate.db.entity.TUser”
    
              table=”T_User”
    
              dynamic-update=”true”
    
              dynamic-insert=”true”
    
       >
    

    ...

              <set name=”addresses” table=”T_Address”
    
                     cascade=”all” order-by=”zipcode asc”
    
              >
    
                     <key column=”user_id”/>
    
                     <one-to-many
    
                            class=”com.redsaga.hibernate.db.entity.TAddress”
    
                     />
    
              </set>
    
       ...
    

    被动方(TAddress)的记录由Hibernate负责读取,之后存放在主控方(TUser)指定的Collection类型属性中。

    单向一对多的实现相对比较简单,但是存在一个问题,由于是单向关联,为了保持关联关系,我们只能通过主控方对被动方进行级联更新。如果被关联方的关联字段为“NOT NULL”,当Hibernate创建或者更新关联关系时,可能出现约束违例。

    ...

    双向一对多关系的出现则解决了这个问题。它除了避免约束违例和提高性能的好处之外,还带来另外一个优点,由于建立了双向关联,我们可以在关联双方中任意一方,访问关联的另一方,这提供了更丰富灵活的控制手段。
    4.4.2.2双向一对多关联

    双向一对多关联,实际上是“一对多”与“多对一”关联的组合。也就是说我们必须在主控方配置单向一对多的基础上,在被控方配置其对应的多对一关系。

    上面我们的已经大致完成了单向一对多关联的配置,我们只需在此基础上稍做修改,并对(T_Address)的相关属性进行配置即可:

    TUser.hbm.xml

       <class
    
              name=”com.redsaga.hibernate.db.entity.TUser”
    
              table=”T_User”
    
              dynamic-update=”true”
    
              dynamic-insert=”true”
    
       >
    
       ...
    
              <set
    
                     name=”addresses”
    
                     table=”t_address”
    
                     lazy=”false”
    
                     inverse=”true”
    
                     cascade=”all”
    
                     sort=”unsorted”
    
                     order-by=”zipcode asc”
    
              >
    
                     <key column=”user_id” />
    
                     <one-to-many
    
                            class=”com.redsaga.hibernate.db.entity.TAddress”
    
                     />
    
              </set>
    
       </class>
    

    关联关系中,inverse=”false”的为主动方,由主动方负责维护关联关系。

    TAddress.hbm.xml

       <class
    
              name=”com.redsaga.hibernate.db.entity.TAddress”
    
              table=”t_address”
    
              dynamic-update=”false”
    
              dynamic-insert=”false”
    
       >
    
       ...
    
              <many-to-one
    
                     name=”user”
    
                     class=”com.redsaga.hibernate.db.entity.TUser”
    
                     cascade=”none”
    
                     outer-join=”auto”
    
                     update=”true”
    
                     insert=”true”
    
                     access=”property”
    
                     column=”user_id”
    
                     not-null=”true”
    
              />
    
       </class>
    

    测试代码增加

    addr.setUser(user);

    user.getAddresses().add(addr);

    session.save(user);//级联更新

    点赞 评论 复制链接分享

相关推荐