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 ...
随机推荐
- C++ 约瑟夫环问题
约瑟夫环比较经典了 已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列:他的下一个人又从1开始报数,数到m的那个人又出列:依此规律重复下去,直 ...
- spring 获取 bean
不通过注解或者是配置文件怎么获取spring中定义的bean呢?有几个方法: 1.实现ApplicationContextAware <bean class="com.xxx.Spri ...
- java中常用数据类型转换器
/** * 把String转换成long * * @param src 要转换的String * @param def 转换失败时返回此值 * @return 转换好的long */ public s ...
- AS
1.修改注释模板: “File“->“Settings” File and Code Templates 然后选中Includes tab下面的File Header. 2.代码提 ...
- 自己练习读取写入txt
读取文件中的内容生成一个list,然后修改list后再写会该文件文件中的格式是:AA,BB,CC,DDblist = []for line in open('a.txt'): blist.extend ...
- android 学习(1)
第二次发生这种事了,写完啦,手一抖,丢了,这个写完不用博客园了,怪不得用户越来越少 简写 androidstudio安装注意点 1JDK安装需配置环境变量 2安装遇到haxm错误需要进入BIOS打开C ...
- ubuntu 挂载windows共享目录的方法
建立windows共享目录 右击要共享的文件夹-->属性-->高级共享-->添加用户-->添加完全控制权限 假设建立的共享地址为\\192.168.1.100\Linux 获取 ...
- linux shell 去重 uniq和sort的区别
sort -u 和 uniq都能起到删除重复信息的功能,那么他们的区别究竟在哪呢?$ cat test jasonjasonjasonfffffjason 下面分别执行三个命 ...
- Selenium2+python自动化17-JS处理滚动条
前言 selenium并不是万能的,有时候页面上操作无法实现的,这时候就需要借助JS来完成了. 常见场景: 当页面上的元素超过一屏后,想操作屏幕下方的元素,是不能直接定位到,会报元素不可见的. 这时候 ...
- 自定义ImageView回调实现手动改变圆环大小
//-----------------自定义MyView继承Imageview------------------------------- package com.bw.yuanhuan; impo ...