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 ...
随机推荐
- 洛谷P3367 【模板】并查集
P3367 [模板]并查集 293通过 551提交 题目提供者HansBug 标签 难度普及- 提交 讨论 题解 最新讨论 不知道哪错了 为啥通不过最后三个节点 题解 不懂为什么MLE 最后一个数 ...
- 【226】C# 相关功能实现代码
目录: 1. 实现代码的等待操作 2. 实现文件夹/文件打开操作 3. 建立事件模板,然后调用 4. 用代码在Form中写控件,同时可以编写控件数组 5. 用代码执行事件 1. 实现代码的等待操作 ...
- 2016.02.17 JS DOM编程艺术 第四五六章
看完这三章内容,集中精力,加快速度.
- jQuery之ajax的跨域获取数据
如果获取的数据文件存放在远程服务器上(域名不同,也就是跨域获取数据),则需要使用jsonp类型.使用这种类型的话,会创建一个查询字符串参数 callback=? ,这个参数会加在请求的URL后面.服务 ...
- 《C++编程规范:101条规则、准则与最佳实践》学习笔记
转载:http://dsqiu.iteye.com/blog/1688217 组织和策略问题 0. 不要为小事斤斤计较.(或者说是:知道什么东西不需要标准化) 无需在多个项目或者整个公司范围内强制实施 ...
- asp.net GridView控件的列属性
BoundField 默认的数据绑定类型,通常用于显示普通文本 CheckBoxField 显示布尔类型的数据.绑定数据为TRUE时,复选框数据绑定列为选中状态:绑定数据为FALSE时,则显示未选中状 ...
- static 使用,静态变量
由static修饰,属于整个类,被类对象共享, 可以由类名,对象名访问 static可以修饰变量,方法,代码块 public class HelloWorld { static String clas ...
- OpenSSL命令---passwd
NAME passwd - compute password hashes SYNOPSIS openssl passwd [-crypt] [-1] [-apr1] [-salt string] [ ...
- Android消息推送——JPush极光推送
刚看了一篇关于Android消息推送评测总结的博客http://www.cnblogs.com/logan/p/4514635.html: 自己也对原学过的JPush极光进行一下小结,方便后续工作使用 ...
- css控制页面打印(分页、屏蔽不需要打印的对象)
样式: <style media="print"> .Noprint { DISPLAY: none;} .PageNext { ...