Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
UnuniqueObjectException:使用hibernate更新实体时_Hibernate_Jakarta Ee_Hibernate Mapping - Fatal编程技术网

UnuniqueObjectException:使用hibernate更新实体时

UnuniqueObjectException:使用hibernate更新实体时,hibernate,jakarta-ee,hibernate-mapping,Hibernate,Jakarta Ee,Hibernate Mapping,我有三个实体: -权限,权限,权限类别 class Permission{ @ManyToOne(cascade = CascadeType.ALL) private PermissionCategory permissionCategory; } -Desc:权限可以包含多个权限,权限可以在多个权限中,权限类别可以包含多个权限 1-权限>多对多具有权限 class Authority{ @ManyToMany(cascade = CascadeType.ALL)

我有三个实体:

-权限权限权限类别

class Permission{

@ManyToOne(cascade = CascadeType.ALL)
private PermissionCategory permissionCategory;

}
-Desc:权限可以包含多个权限,权限可以在多个权限中,权限类别可以包含多个权限

1-权限>多对多具有权限

class Authority{

    @ManyToMany(cascade = CascadeType.ALL)
        @JoinTable(name = "authority_permission", joinColumns = { @JoinColumn(name = "authority_id", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "permission_id", nullable = false, updatable = false) })
        private Set<Permission> permissions = new HashSet<Permission>(0);

    }
class PermissionCategory{

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
        @JoinTable(name = "perm_cat_map", joinColumns = { @JoinColumn(name = "perm_cat_id") }, inverseJoinColumns = { @JoinColumn(name = "permission_id") })
        private Set<Permission> permissions = new HashSet<Permission>(0);

       }
authority = (Authority) getCurrentSession().merge(authority);
sessionFactory.getCurrentSession().save(authority);
案例1:添加新角色

  • 当添加新角色时,用户选择已经存在的权限,所以我需要在authority和in join表中插入(authority\u Permission)
因此,我的发言如下:

Set<Permission> permissions=new HashSet<Permission>;
Permission permission=permissionDao.getPermissionById(1); 
permissions.add(permission);   
authority.setPermissions(permissions);
sessionFactory.getCurrentSession().merge(authority); // it works only with merge
    Set<Permission> permissions=new HashSet<Permission>;
    Permission permission=permissionDao.getPermissionById(1); 
    permissions.add(permission);   
    authority.setPermissions(permissions);
    sessionFactory.getCurrentSession().update(authority);
我正在使用Hibernate 3.5.1-Final
请告知。

在我进行合并然后保存更新后,它工作正常,如下所示:

Set<Permission> permissions=new HashSet<Permission>;
Permission permission=permissionDao.getPermissionById(1); 
permissions.add(permission);   
authority.setPermissions(permissions);
sessionFactory.getCurrentSession().merge(authority); // it works only with merge
    Set<Permission> permissions=new HashSet<Permission>;
    Permission permission=permissionDao.getPermissionById(1); 
    permissions.add(permission);   
    authority.setPermissions(permissions);
    sessionFactory.getCurrentSession().update(authority);
1-保存角色:(插入新角色对象,插入加入表权限)

2-更新角色(更新角色对象、更新联接表权限\u权限>删除/插入):

authority = (Authority) getCurrentSession().merge(authority);
sessionFactory.getCurrentSession().update(authority);
3-删除角色:(删除角色对象,从联接表中删除权限)

删除
cascade=CascadeType后,它可以正常工作。全部

class Authority{

    @ManyToMany
        @JoinTable(name = "authority_permission", joinColumns = { @JoinColumn(name = "authority_id", nullable = false, updatable = false) }, inverseJoinColumns = { @JoinColumn(name = "permission_id", nullable = false, updatable = false) })
        private Set<Permission> permissions = new HashSet<Permission>(0);

但是我需要任何人在这里提供一些有经验的解释,为什么我需要合并然后保存或更新,如果该解决方案是最好的,请在博客中找到它。

您在会话中拥有id为3的权限,并且尝试向会话添加具有相同id的不同权限。Hibernate保证在一个会话中从来没有一个实体被表示两次,因此它抛出异常

这可能是因为您使用会话(通过DAO)加载了一些对象。它们附加到会话,即它们在会话中

您有来自会话外部的其他对象。最初可能来自另一个会话(可能是最后一个请求),但此会话现在可能已关闭。也许您可以直接使用
new
创建它们。罪魁祸首可能是具有引用权限的
权限
对象

当您
保存
/
更新
时,
权限
会尝试将引用的权限拖到会话中,您会得到异常


合并为您提供已在会话中的实体的对象(并根据新状态设置所有字段,可能级联到引用的对象,具体取决于配置)。因此,每个实体只有一个对象,每个人(或至少Hibernate)都很高兴

感谢您的解释,我更新了关于删除角色案例的问题,请您给我建议。您的解决方案帮助我克服了Hibernate的问题。谢谢!