【问题标题】:JPA Hibernate enum many to manyJPA Hibernate 枚举多对多
【发布时间】:2016-07-13 20:14:57
【问题描述】:

我正在尝试创建 2 个用户实体,因为我的应用程序正在启动,它们有一个角色字段,它是枚举的集合。其中一个用户有两个角色,另一个用户有一个角色。枚举没有对应的表,但有一个名为 USER_AUTHORITY_ROLES 的连接表。这两个用户是在两个不同的 spring bean 中创建的。 User 类中的字段如下所示

@OrderColumn
    @ElementCollection(fetch = FetchType.EAGER)
    @Enumerated(EnumType.STRING)
    private List<AuthorityRole> authorityRoles = new ArrayList<AuthorityRole>();

当我只创建一个用户时它工作正常,但是当我创建 2 个用户时,休眠只为 USER_AUTHORITY_ROLES 表中的每个用户保存一个条目,相同的角色。
我创建了一个这样的用户角色

user.setAuthorityRoles(Arrays.asList(AuthorityRole.ROLE_ADMIN, AuthorityRole.ROLE_USER));

如果我尝试使用 Arrays.asList 创建其他用户的角色,hibernate 会抱怨该集合不可修改。

Caused by: java.lang.UnsupportedOperationException
    at java.util.AbstractList.remove(AbstractList.java:161) ~[?:1.8.0_31]
    at java.util.AbstractList$Itr.remove(AbstractList.java:374) ~[?:1.8.0_31]
    at java.util.AbstractList.removeRange(AbstractList.java:571) ~[?:1.8.0_31]
    at java.util.AbstractList.clear(AbstractList.java:234) ~[?:1.8.0_31]
    at org.hibernate.type.CollectionType.replaceElements(CollectionType.java:543) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.type.CollectionType.replace(CollectionType.java:697) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.type.TypeHelper.replace(TypeHelper.java:193) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:407) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.entityIsPersistent(DefaultMergeEventListener.java:219) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:192) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:85) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:876) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:858) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:863) ~[hibernate-core-4.3.11.Final.jar:4.3.11.Final]
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:1196) ~[hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]

似乎休眠只会让我为每个用户分配一个角色(相同的角色)。为什么会这样?

更新: 当两个集合都使用ArrayList 制作时,我遇到了同样的问题。在连接表中,应该有 2 个角色的用户只有一个。

【问题讨论】:

  • 我承认我有点困惑,但问题是 Arrays.toList() 返回一个不可修改的列表。尝试手动将角色列表创建为 ArrayList,看看它是否效果更好。
  • 如果我将列表创建为具有一个角色的用户的 ArrayList,它不会引发异常,而是从我的具有 2 个角色的用户中删除其中一个角色,即使我正在创建它使用 Arrays.toList 列出

标签: spring hibernate jpa


【解决方案1】:

因为你

user.setAuthorityRoles(Arrays.asList(AuthorityRole.ROLE_ADMIN, AuthorityRole.ROLE_USER));

创建一个不可修改的列表。 Hibernate 需要一个可修改的列表。尝试改用它,看看是否可以添加 2 个角色:

List<AuthorityRole> list = new ArrayList<AuthorityRole>();
list.add(AuthorityRole.ROLE_ADMIN);
list.add(AuthorityRole.ROLE_USER);    
user.setAuthorityRoles(list);

如果不检查您是否没有在 DB 中的表之间创建任何其他关系,或者您在模型中的某处指定了级联。

【讨论】:

  • Hibernate 只有在两个列表都不可修改时才会抱怨不可修改列表。该列表由没有对应表的枚举组成
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-23
  • 2013-04-13
  • 1970-01-01
  • 2018-04-11
相关资源
最近更新 更多