当前位置:编程学习 > JAVA >>

关于hibernate 级联保存的问题

这是一个基础的问题 ,但我还是没弄明白, 大家看我理解的是不是正确,还是我理解错了,或者不应这样用
------------------------------------------------------------
一个用户组的配置
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                                   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="test.UserGroup" table="t_usergroup" lazy="false">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<set name="userList" inverse="true" lazy="false"  cascade="all">
<key column="groupid" />
<one-to-many class="test.User" />
</set>
</class>
</hibernate-mapping>
     
用户组类
public class UserGroup {
private int id;
private String name;
private Set<User> userList=new HashSet<User>();
public void addUser(User user){
userList.add(user);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Set<User> getUserList() {
return userList;
}
public void setUserList(Set<User> userList) {
this.userList = userList;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}


------------------------------------------------------------
一个用户的配置
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                                   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="test.User" table="t_user" lazy="false">
<id name="id">
<generator class="native" />
</id>
<property name="name" />
<many-to-one name="userGroup" column="groupid" />
</class>
</hibernate-mapping>

用户类
public class User {
private int id;
private String name;
private UserGroup userGroup;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public UserGroup getUserGroup() {
return userGroup;
}
public void setUserGroup(UserGroup userGroup) {
this.userGroup = userGroup;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
------------------------------------------------------------
现在测式:
测式1
新建立一个用户组
UserGroup userGroup=new UserGroup();
新建一个用户
User user=new User();
此时:save(user);再save(userGroup); 
没问题两个表都创建了,并且user表里的groupid有UserGroup的ID
------------------------------------------------------
测式2
但如果这样
新建立一个组和用户
UserGroup userGroup=new UserGroup();
User user=new User()
把用户加到组里
userGroup.add(user);
此时:再save(userGroup); 
此时有问题了,两个表都创建了,但用户表里的groupid没有指向usergroup 也就是创建了两个表
-------------------------------------------------------------------
测式3
新建立一个组和用户
UserGroup userGroup=new UserGroup();
User user=new User()
把用户加到组里
userGroup.add(user);
再save(userGroup); 
再save(user)
此时有问题了,两个表都创建了,但用户表里的groupid有重复的两条数据,
有一个groupid=null,有一个是正确的


我是这样理解的:
测式1里:UserGroup的Set<User>设置了级联,但save(userGroup)时userGroup里还没有用户列表,所以当时组加上了,并且没有级联创建user的表
此时Set<User>设置由多端维护,然后增加一个save(User)把用户加上
测式1的结果正确:userGroup表正确,并且user表里有指定userGroup

测式2里:先创建一个UserGroup,然后往组里加一个User,此时不sava(user),而直接sava(userGroup)
因为Set<User>设置了级联,所以加userGroup的时候会自动创建user表,但此时Set<User>又设置了由多端维护
所以才出现在userGroup端创建了user表,但多端设置了维护,所以userGroup端没有加入指向组的ID

不知道我理解的对不对?
我现在的方法是用测式一的方法加,但要保证userGroup
里的userList是空的,然后再见手动save(user),否则就会出现测式3的状态,
有两条user数据,一个groupid为null,一个正确,
因为级联保存usergroup的时候创建了一个没有指向的user,此时手动再save一个正确的user就会有两条

我总结如下,不知道对不对?还是我理解错了?用法不当?
<!-- 级联和多端维护注意:当级联时,会自动SAVE所级联的表,但又设置了多端维护, -->
<!-- 所以创建的多端的表没有指向一端,此时同时再SAVA多端 就会有重复的2行,一个有一端指向的,一个指向NULL的 -->
<!-- 所以应该先sava一端,并且一端没有子表数据,然后再由多端加入 -->

大家一般情况下是否是用用第一种?,还是有别的方法?


Hibernate --------------------编程问答-------------------- hibernate级联更新是根据两表关系来的 而不是你所谓的在group表增加一个add方法就可以的
比如你在group表的set属性上设置级联更新 那么如果你想通过保存group表的同时保存user的话 就必须先将user放入set集合 然后这个集合放入group.setUserList(...)这个里面 这样的话就都可以保存了
如果你不这样做的 而是调用user.setUserGroup(...)把新建的组加进去同样也是无效的 这样只保存组而用户不会保存

如果在user的many-to-one上建立级联更新保存的话 就是想通过保存user的同时保存group 那么hibernate会调用user.setUserGroup(...)的方法 所以这时候只要在这里设置下就好了 就没有必要在group的setUserList上做任何文章了

你可以试着更改下group上set的inverse属性 无非就多发几条语句 设置外键的东西

希望对你有帮助
补充:Java ,  Web 开发
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,