我已经建立了一个简单的多对多关系帐户:Hibernate角色,但是当我在添加角色后尝试在单元测试中保存帐户时,出现UnsupportedOperationException异常:
java.lang.UnsupportedOperationException
at java.util.AbstractList.remove(AbstractList.java:144)
at java.util.AbstractList$Itr.remove(AbstractList.java:360)
at java.util.AbstractList.removeRange(AbstractList.java:559)
at java.util.AbstractList.clear(AbstractList.java:217)
at org.hibernate.type.CollectionType.replaceElements(CollectionType.java:502)
at org.hibernate.type.CollectionType.replace(CollectionType.java:582)
at org.hibernate.type.TypeHelper.replace(TypeHelper.java:178)
at org.hibernate.event.def.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:563)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsPersistent(DefaultMergeEventListener.java:288)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:261)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:84)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:867)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:851)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:855)
at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:686)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
at $Proxy33.merge(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:360)
at ....JpaProvider.save(JpaProvider.java:161)
at ....DataModelTest.testAccountRole(DataModelTest.java:47)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
这是怎么了
我的实体设置有问题吗?或者这是hibernate或JPA限制,迫使我将m:m关系分解为3:n关系,也为m:n关系表建模(我想避免这种情况,因为它没有任何关系)附加信息)。我已经在原型中为其他1:n实体建模,到目前为止看来效果很好…
这是我的设置,感谢您是否有任何疑问。
实体(简体):
@Entity
@Table(name="account")
public class Account extends AbstractPersistable<Long> {
private static final long serialVersionUID = 627519641892468240L;
private String username;
@ManyToMany
@JoinTable( name = "account_roles",
joinColumns = { @JoinColumn(name = "account_id")},
inverseJoinColumns={@JoinColumn(name="role_id")})
private List<Role> roles;
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
@Entity
@Table(name="role")
public class Role extends AbstractPersistable<Long> {
private static final long serialVersionUID = 8127092070228048914L;
private String name;
@ManyToMany
@JoinTable( name = "account_roles",
joinColumns={@JoinColumn(name="role_id")},
inverseJoinColumns={@JoinColumn(name="account_id")})
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
单元测试:
@TransactionConfiguration
@ContextConfiguration({"classpath:dw-security-context-test.xml"})
@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
public class DataModelTest {
@Inject
private AccountProvider accountProvider;
@Inject
private RoleProvider roleProvider;
@Before
public void mockAccountRolePermission(){
Account account = MockAccount.getSavedInstance(accountProvider);
Role role = MockRole.getSavedInstance(roleProvider);
}
@Test
public void testAccountRole(){
Account returnedAccount = accountProvider.findAll().get(0);
returnedAccount.setRoles(Arrays.asList(roleProvider.findAll().get(0)));
accountProvider.save(returnedAccount);
}
}
MockAccount(与MockRole相同):
public class MockAccount {
public static Account getInstance(){
Account account = new Account();
account.setUsername(RandomData.rndStr("userName-", 5));
return account;
}
public static Account getSavedInstance(AccountProvider accountProvider){
Account account = getInstance();
accountProvider.save(account);
return account;
}
}
最后是提供者:
@Repository
public class AccountProvider extends JpaProvider<Account, Long> {
}
JPAProvider仅包装了许多JPARepository方法(至少在这种情况下很重要):
public abstract class JpaProvider<T extends Object, ID extends Serializable> implements JpaRepository<T, ID>, JpaSpecificationExecutor<T>, QueryDslPredicateExecutor<T> {
...
}
关于为什么保存可能是UnsupportedOperation的任何想法?
是因为你
Arrays.asList(roleProvider.findAll().get(0))
这将创建一个不可修改的列表(实际上是一个不可调整大小的列表)。Hibernate似乎希望有一个可修改的列表。尝试使用此代替:
public void testAccountRole(){
Account returnedAccount = accountProvider.findAll().get(0);
List<Role> list = new ArrayList<Role>();
list.add(roleProvider.findAll().get(0));
returnedAccount.setRoles(list);
accountProvider.save(returnedAccount);
}
这个解决方案不会解释为什么您确实遇到了另一个异常(可能会在Hibernate文档中进行记录),但是这可能是一个有效的解决方法。
我用复合键定义了两个实体之间的多对多关系。问题是,当我获得join对象时,它只被过滤了关系的一侧,而不是两边。 图片使问题更加清晰。这里,我要查找的是dtid=185和prid=352,但我从多对多关系中得到的是两个突出显示的行。 天丁:
问题内容: 我有2个班级:驾驶员和汽车。汽车表在单独的过程中更新。我需要的是在Driver中具有属性,该属性使我可以阅读完整的汽车说明,并仅写入指向现有Car的ID。这是示例: 汽车对象只是典型的JPA对象,没有向后引用驱动程序。 因此,我想通过以下方法实现的目标是:1)我可以使用详细的JSON View阅读完整的汽车描述2)或在简短的JsonView 3中仅阅读汽车的ID 3),最重要的是,在创
问题内容: 也许这是一个愚蠢的问题,但这困扰了我。 我有一个从员工到车辆的双向一对多关系。当我第一次将Employee保留在数据库中时(即它没有分配的ID),我也希望保留其关联的Vehicles。 目前,这对我来说很好,除了我保存的Vehicle实体没有自动映射关联的Employee,并且在数据库中Vehicle表中的employee_id外键列为空。 我的问题是,是否可以在雇员本身被保留的同时保
Car对象只是典型的JPA对象,没有对驱动程序的反向引用。 所以我试图通过这个来实现的是: 我可以使用详细的JSON视图阅读完整的汽车说明 或者我可以只读取汽车的Id,简写为jsonview 最重要的是,在创建新的驱动程序时,我只想传入汽车的JSON ID。这样,我就不需要在persist期间对Car进行不确定的读取,而只需要更新ID。 谢谢你。 更新:忘记了,我在创建驱动程序时通过的汽车的ID是
我目前在数据库中的一对一/多对一映射时遇到问题。我希望我的图书表具有与“出版商”、“流派”、“评级”和“状态”表的@ManyToOne映射。 这是我的Book实体类的外观: 例如,我的Publisher实体类(类型、评级和状态类完全相同): 唯一的区别是类型、评级和状态的书籍字段,f. e: 这就是我的堆栈跟踪的样子: 更新的堆栈跟踪:
问题内容: 我正在使用JPA 2.0并hibernate。我有一个用户类和一个组类,如下所示: 然后,我创建一个用户和组,然后将该用户分配给该组。 我要拥有的是删除组时(当然),该组将被删除,并且该组具有的所有用户-组关系将从USER_GROUP连接表中自动删除,但用户本身不会从USER表。 使用上面的代码,当我删除组时,只有GROUP表中的行将被删除,并且用户在USER_GROUP连接表中仍然具