ManyToMany【项目随笔】关于异常object references an unsaved transient instance
在保存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的更多相关文章
- object references an unsaved transient instance【异常】
[异常提示] TransientObjectException: object references an unsaved transient instance -save the transient ...
- object references an unsaved transient instance - save the transient instance before flushing异常问题处理
一.异常:org.hibernate.TransientObjectException: object references an unsaved transient instance - save ...
- 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(参考资料: ...
- 三大框架常遇的错误:hibernate : object references an unsaved transient instance
hibernate : object references an unsaved transient instance 该错误是操作顺序的问题,比如: save或update顺序问题---比方学生表和 ...
- 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 ...
- Hibernate的一个问题object references an unsaved transient instance - save the transi5
1 我做了一对多和多对一的双向关联关系,在User这一方@ManyToOne已经设置了级联Cascade,这样在测试程序中保存User时,Group也应该自动保存,为什么会抛出以下的异常: (我是按着 ...
- 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 ...
- object references an unsaved transient instance save the transient instance before flushing
object references an unsaved transient instance save the transient instance before flushing 对象引用未保存的 ...
- hibernate 对象状态异常:object references an unsaved transient instance - save the transient instance before flushing
我的问题出在,删除的对象对应的表中有一个外键,关联着另外一个表,可是另外一个表中没有数据,所以报了这个错误. 参考http://www.cnblogs.com/onlywujun/archive/20 ...
随机推荐
- uploadify图片上传发生Security Error
今天在使用uploadify进行图片上传的时候出现security error.其根本原因是flash跨域问题.主要原因是因为配了两个域名www.ttyouni.com 和 ttyouni.com 在 ...
- 洛谷P3371 【模板】单源最短路径
P3371 [模板]单源最短路径 282通过 1.1K提交 题目提供者HansBug 标签 难度普及/提高- 提交 讨论 题解 最新讨论 不萌也是新,老司机求带 求看,spfa跑模板40分 为什么 ...
- noip2006解题报告
T1.能量项链 给出一串数字(其实是个环也就是可以旋转).n个数组成n颗珠子,形如: 1 2 3 4 表示的珠子是(1,2)(2,3)(3,4)(4,1) 定义珠子的聚合:如前两颗聚合放出能量为1*2 ...
- Inside The C++ Object Model - 02
前言 - 什么是C++对象模型 C++对象模型包括2个方面的含义: 1.语言中直接支持面向对象程序设计的部分 2.对于各种(面向对象)支持的底层实现机制. 无论是什么语言,都需要转换为汇编.很多面向对 ...
- windows2008r2环境双实例安装mysql5.6
windows2008r2环境双实例安装mysql5.6 环境:windows2008 r2 标准版 1.默认安装了一个mysql5.6端口为3306 2.使用msi文件安装需要.net4.0支持,安 ...
- 一步步编写avalon组件01:弹出层组件
avalon2已经稳定下来,是时候教大家如何使用组件这个高级功能了. 组件是我们实现叠积木开发的关键. avalon2实现一个组件非常轻松,并且如何操作这个组件也比以前的avalon2,还是react ...
- checkbox绿色圆圈样式
抄自: http://www.cnblogs.com/xyzhanjiang/p/3989836.html?utm_source=tuicool&utm_medium=referral < ...
- VC++ 控制外部程序,向外部程序发送一个消息的方法
这里需要考虑两部分的内容: 发送端: 查找对应的窗体,找到CWnd的值 向窗体发送消息 举例: CWnd* wnd = FindWindow(NULL, _T("选择题做题过程中" ...
- ActiveMQ安装与使用
一 .安装运行ActiveMQ: 1.下载activemq wget http://archive.apache.org/dist/activemq/apache-activemq/5.9.0/apa ...
- jQuery2
一.类型选择器 jQuery的类型选择器 选择器 说明 :button 选择所有按钮 :checkbox 选择所有复选框 :file 选择所有文件上传输入框 :header 选择所有标题元素(h1,h ...