2011-09-15 23 views
21

के साथ कई से अधिक संबंधों को विलय-बचत करना मैंने हाइबरनेट के साथ एक साधारण कई से अधिक संबंध खाता स्थापित किए हैं, लेकिन जब मैं एक यूनिट परीक्षण में खाता सहेजने का प्रयास करता हूं इसकी भूमिका में जोड़ा गया था मुझे एक असमर्थितऑपरेशन अपवाद प्राप्त हुआ:असमर्थितऑपरेशन एक्सेप्शन हाइबरनेट और जेपीए

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) 

क्या गलत हो रहा है? क्या मेरी इकाई सेटअप दोषपूर्ण है या क्या यह एक हाइबरनेट या जेपीए सीमा है जो मुझे अपने एम: एम रिलेशनशिप को अलग करने के लिए मजबूर कर रही है: एम रिलेशनशिप एम: एन रिलेशनशिप टेबल के साथ-साथ (जो मैं बचाना चाहता था क्योंकि इसमें कोई भी नहीं है अतिरिक्त जानकारी)। मैंने अपने प्रोटोटाइप में अन्य 1: एन इकाइयों का मॉडल किया है और यह अब तक अच्छी तरह से काम करने लग रहा था ...

यहां मेरा सेटअप है, कोई विचार है कि यह दोषपूर्ण हो सकता है या नहीं।

संस्थाओं (सरलीकृत):

@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 हो सकता है पर कोई विचार?

उत्तर

42

की वजह से इसे अपने

Arrays.asList(roleProvider.findAll().get(0)) 

यह एक unmodifiable सूची (वास्तव में, एक गैर आकार बदलने योग्य सूची) पैदा करता है। हाइबरनेट एक संशोधित सूची की अपेक्षा करता है। बजाय इस उपयोग करके देखें:

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); 
} 

यह समाधान नहीं समझा जाएगा क्यों वास्तव में आप अन्य अपवाद (हाइबरनेट डॉक्स में दर्ज किया जा सकता है) मिल गया है, लेकिन यह एक वैध वैकल्पिक हल हो सकता है।

+0

अरे, तत्काल उत्तर के लिए धन्यवाद! मैं इस पल में टेबल पर अपने सिर को टक्कर लगी हूँ! मेरे पास ऐसा ही था जब मेरे सहयोगी ने मेरी तरफ देखा, "तुम ऐसा क्यों नहीं करते .. .." ;) आह ठीक है .. फिर से काम कर, मुझे खुश करो! – Pete

0

प्रश्न में Collection की हाइबरनेट के लगातार संस्करण एक सार आधार वर्ग (PersistenceBag) कि add विधि को लागू नहीं करता है को सौंपने के लिए प्रयास करता है।

संबंधित मुद्दे