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