在保存ManyToMany  时出现异常:

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientObjectException: object references an unsaved transient instance

如图:

出现原因:单向ManyToMany保存顺序反了,应当先保存主控端permission对象

错误代码:

@Transactional(readOnly=false)
@Lock(LockModeType.OPTIMISTIC_FORCE_INCREMENT)
@CacheEvict(value = "permissionList", allEntries = true)
public Permission save(Permission permission) {
permission.setMenu(menuDao.findOne(permission.getMenuId())); List<Role> roles = roleDao.findByDataScope(DataScope.ALL.getValue());
for(Role temp : roles){
List <Permission> permissions = temp.getPermissions();
permissions.add(permission);
}
roleDao.save(roles);
permission.setRoles(roles); //权限归属于该角色
return permissionDao.save(permission);
}

两个类,角色Role和权限Permission,一个角色可以拥有多个权限,反之亦然。

代码如下:

package net.myspring.blue.modules.sys.entity;

import java.util.List;

import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.persistence.Transient; import com.google.common.collect.Lists; import net.myspring.blue.common.persistence.DataEntity;
import net.myspring.blue.common.utils.Collections3; /**
* The persistent class for the sys_role database table.
*
*/
@Entity
@Table(name="sys_role")
@Cacheable
public class Role extends DataEntity {
private String code;
private Integer dataScope;
private String name;
private List<Permission> permissions=Lists.newArrayList();
private List<User> users=Lists.newArrayList(); private List<Long> permissionIds=Lists.newArrayList(); public Role() {
} public String getCode() {
return this.code;
} public void setCode(String code) {
this.code = code;
} @Column(name="data_scope")
public Integer getDataScope() {
return this.dataScope;
} public void setDataScope(Integer dataScope) {
this.dataScope = dataScope;
} public String getName() {
return this.name;
} public void setName(String name) {
this.name = name;
} //bi-directional many-to-many association to Permission
@ManyToMany
@JoinTable(name = "sys_role_permission", joinColumns = { @JoinColumn(name = "role_id") }, inverseJoinColumns = { @JoinColumn(name = "permission_id") })
public List<Permission> getPermissions() {
return this.permissions;
} public void setPermissions(List<Permission> permissions) {
this.permissions = permissions;
} //bi-directional many-to-many association to User
@ManyToMany(mappedBy="roles")
public List<User> getUsers() {
return this.users;
} public void setUsers(List<User> users) {
this.users = users;
} @SuppressWarnings("unchecked")
@Transient
public List<Long> getPermissionIds() {
if(permissionIds!=null && permissionIds.size()==0 && Collections3.isNotEmpty(permissions)) {
permissionIds= Collections3.extractToList(permissions, "id");
}
return permissionIds;
} public void setPermissionIds(List<Long> permissionIds) {
this.permissionIds = permissionIds;
}
}

权限Permission类

package net.myspring.blue.modules.sys.entity;

import javax.persistence.*;

import net.myspring.blue.common.config.Global;
import net.myspring.blue.common.persistence.DataEntity;
import net.myspring.blue.common.utils.Collections3; import com.google.common.collect.Lists; import java.util.List; /**
* The persistent class for the sys_permission database table.
*
*/
@Entity
@Table(name="sys_permission")
@Cacheable
public class Permission extends DataEntity {
private String name;
private String permission;
private Menu menu;
private List<Role> roles=Lists.newArrayList(); private Long menuId; public Permission() {
} public String getName() {
return this.name;
} public void setName(String name) {
this.name = name;
} public String getPermission() {
return this.permission;
} public void setPermission(String permission) {
this.permission = permission;
} //bi-directional many-to-one association to Menu
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="menu_id")
public Menu getMenu() {
return this.menu;
} public void setMenu(Menu menu) {
this.menu = menu;
} //bi-directional many-to-many association to Role
@ManyToMany(mappedBy="permissions")
public List<Role> getRoles() {
return this.roles;
} public void setRoles(List<Role> roles) {
this.roles = roles;
} @Transient
public Long getMenuId() {
if(menuId==null && menu!=null) {
menuId=menu.getId();
}
return menuId;
} public void setMenuId(Long menuId) {
this.menuId = menuId;
} @Transient
public String getRoleNames() {
return Collections3.extractToString(roles, "name", Global.CHAR_COMMA);
}
}

注意主控端是Permission类 ,注解“ @ManyToMany(mappedBy="permissions") ”说明了这点

业务场景:

  admin角色是拥有"任意权限"的,我在添加新权限的时候,权限应当同步被admin所拥有。

权限对应的的角色组成的List<Role>也应当等于拥有”任意权限"的角色 .->List<Role> roles = roleDao.findByDataScope(DataScope.ALL.getValue());

保存时,一定要先save主控端permission,否则数据库将报错

正确的写法

@Transactional(readOnly=false)
@Lock(LockModeType.OPTIMISTIC_FORCE_INCREMENT)
@CacheEvict(value = "permissionList", allEntries = true)
public Permission save(Permission permission) {
permission.setMenu(menuDao.findOne(permission.getMenuId()));
List<Role> roles = roleDao.findByDataScope(DataScope.ALL.getValue());
permission.setRoles(roles);
permissionDao.save(permission); //注意save的顺序 permission先
for(Role temp : roles){
List <Permission> permissions = temp.getPermissions();
permissions.add(permission);
}
roleDao.save(roles); //roles后
return null;
}

ManyToMany【项目随笔】关于异常object references an unsaved transient instance的更多相关文章

  1. object references an unsaved transient instance【异常】

    [异常提示] TransientObjectException: object references an unsaved transient instance -save the transient ...

  2. object references an unsaved transient instance - save the transient instance before flushing异常问题处理

    一.异常:org.hibernate.TransientObjectException: object references an unsaved transient instance - save ...

  3. object references an unsaved transient instance - save the transient instance before flushing错误

    异常1:not-null property references a null or transient value解决方法:将“一对多”关系中的“一”方,not-null设置为false(参考资料: ...

  4. 三大框架常遇的错误:hibernate : object references an unsaved transient instance

    hibernate : object references an unsaved transient instance 该错误是操作顺序的问题,比如: save或update顺序问题---比方学生表和 ...

  5. ERROR org.hibernate.internal.SessionImpl - HHH000346: Error during managed flush [object references an unsaved transient instance - save the transient instance before flushing: cn.itcast.domain.Custom

    本片博文整理关于Hibernate中级联策略cascade和它导致的异常: Exception in thread "main" org.hibernate.TransientOb ...

  6. Hibernate的一个问题object references an unsaved transient instance - save the transi5

    1 我做了一对多和多对一的双向关联关系,在User这一方@ManyToOne已经设置了级联Cascade,这样在测试程序中保存User时,Group也应该自动保存,为什么会抛出以下的异常: (我是按着 ...

  7. object references an unsaved transient instance - save the transient instance before flushing: com.jspxcms.core.domain.ScTeam

    object references an unsaved transient instance - save the transient instance before flushing: com.j ...

  8. object references an unsaved transient instance save the transient instance before flushing

    object references an unsaved transient instance save the transient instance before flushing 对象引用未保存的 ...

  9. hibernate 对象状态异常:object references an unsaved transient instance - save the transient instance before flushing

    我的问题出在,删除的对象对应的表中有一个外键,关联着另外一个表,可是另外一个表中没有数据,所以报了这个错误. 参考http://www.cnblogs.com/onlywujun/archive/20 ...

随机推荐

  1. 华为RH2285安装过程及经验总结

    安装测试 1.由于服务器为二手服务器,噪音相对较大,如果未经改造无法正常使用,当机器第一次运行的时候,我的血压一下升高不少. 第一步  服务器的远程端口和路由器连接在一起 第二步  设置服务器的bio ...

  2. linker command failed with exit code 1 (use -vto see invocation)

    报这样的错误可能是同一个.m文件同时存在,要先把你新添加的.m文件彻底删除 Move to Trash 点击这个删除.然后clear一下,再在重新添加你所需要的文件即可解决.这次添加不要推进来,需要在 ...

  3. google快捷键

          使用快捷键的好处不言自明,如果能过直接访问google自然有对应的帮助文档以供参考,不过为了方便起见,还是将自己觉得有用的信息收藏到自己访问无障碍的地方吧! 一:以下快捷键适用于Windo ...

  4. UVa10806 Dijkstra,Dijkstra-费用网络流

    Problem, in short Given a weighed, undirected graph, find the shortest path from S to T and back wit ...

  5. net.sf.json 时间格式的转化

    后台代码 //后台代码 response.setCharacterEncoding("UTF-8"); JsonConfig jsonConfig = new JsonConfig ...

  6. 3,SFDC 管理员篇 - 区域划分

    1,销售区域划分 Setup | Administrator | Manage Territory Territory Type : 帮助用户建立大的销售区域分类,分类顺序按照Priority进行显示 ...

  7. C# 将DataTable存储到DBF文件中

    (准备)生成一个DataTable /// <summary> /// 生成一个数据表 /// </summary> /// <returns></retur ...

  8. how to monitor system logs and export to files simultaneously

    What will you do when you conduct a malware analysis on a smartphone? You will focus on running proc ...

  9. java对话框形式实现加减乘除

    import javax.swing.JOptionPane; // import class JOptionPane public class sumit{ public static void m ...

  10. 温习SQL server

    做了好几年的管理工作,技术上有些退步,现在又一一捡起来啦, 以下最近几天看到的好文章, SQL Server约束 http://blog.csdn.net/qq61394323/article/det ...