在hibernate中,merge和update是经常会用到的,两者都有执行更新数据的作用,但是使用的情景却有很大区别。
在数据库记录存在的情况下,修改某个字段,merge会先执行select查询语句,查到当前数据库记录,再执行update方法;而update会直接执行update方法。
在数据库记录存在的情况下,不修改字段而直接更新时,merge只会执行select查询语句,而update还是会执行更新语句。
在数据库记录不存在的情况下,merge会把获得的数据作为一条新的记录执行insert方法,而update则会报错,原因时因为,查不到匹配的记录或相关字段,无法执行更新。
下面时网上的一些回答
update肯定会出错,原因是程序会报持久层中已经有该对象,因为第二个session重新从数据库中获取了一个对象成持久态,你的update会让那个游离态对象也变成持久态,两个持久态会冲突撒,然而用merge的话,它会把第一个的对象数据赋值给已经处于持久化的那个对象中,自己本身不得变为持久态
我是在做权限与角色的级联更新的情况下碰到的这样的问题,权限与角色是多对多的关系,一张中间关系表有两者的外键id
配置文件role.hbm.xml
<set name="authoritys" table="t_roleandauthority" cascade="save-update" lazy="false">
<key>
<column name="role_id" />
</key>
<many-to-many class="org.ems.role.entity.Authority" column="authority_id"></many-to-many>
</set>
authority.hbm.xml
<set name="roles" table="t_roleandauthority" inverse="true" cascade="save-update">
<key>
<column name="authority_id" />
</key>
<many-to-many class="org.ems.role.entity.Role" column="role_id"></many-to-many>
</set>
public String modifyRole() throws Exception{
//得到角色
// Hibernate.initialize(role.getAuthoritys());
// role = new Role();
role = roleService.query(id);
System.out.println(role+"modifyRole方法");
if(rolename!=null&&rolename.trim().length()>0){
role.setName(rolename);
}
System.out.println(rolename);
//得到权限
if(authid!=null){
for(int i=0;i<authid.length;i++){
System.out.println(authid.length);
System.out.println(authid[0]);
int auid = authid[i];
Authority authority = authorityService.query(auid);
System.out.println(authority);
role.getAuthoritys().add(authority);
}
System.out.println(authid[1]+"在这里");
}
//更新角色
roleService.modify(role);//hibernateTemplate.merge(role);
return SUCCESS;
}