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

是这样的吗?

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

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

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

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

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

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

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);//级联更新