2009-06-28 10 views
5

Ho bisogno di aiuto per capire cosa sto facendo male qui. Sto cercando di dominare uno a molti rapporti e in esecuzione in un posto di blocco. Ho provato a modificare il dipendente e l'esempio ContactInfo per fare uno a molte mappature:ClassCastException quando si tenta di aggiungere un figlio al genitore in uno di proprietà a molti. (usando jdo su google appengine)

Tutto funziona se creo sia il genitore (dipendente) e il figlio (Contact) e quindi chiamare makePersistent. Ma se provo ad aggiungere un oggetto figlio a un genitore già persistente, I ottiene un'eccezione java.lang.ClassCast. La traccia dello stack completo si trova nella parte inferiore del post di .

Qui è il codice che rompe (Se mi muovo il() chiamata makePersistent al dopo l'add(), tutto funziona bene:

public void testOneToMany(){ 
     pm = newPM(); 
     Employee e = new Employee("peter"); 
     pm.makePersistent(e); 
     Contact c = new Contact("123 main"); 
     List<Contact> contacts = e.getContacts(); 
     contacts.add(c); // here I get java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String 
} 

Ecco la classe padre

@PersistenceCapable(identityType = IdentityType.APPLICATION) 
public class Employee { 
@PrimaryKey 
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
private Long id; 

@Persistent 
private String name; 

@Persistent(mappedBy="employee") 
private List<Contact> contacts; 

public Employee(String e){ 
     contacts = new ArrayList<Contact>(); 
     name = e; 
} 

List<Contact> getContacts(){ 
     return contacts; 
} 

Long getId(){ 
     return id; 
} 

public String getName(){ 
     return name; 
} 

} 

Ecco la classe bambino

@PersistenceCapable(identityType = IdentityType.APPLICATION) 
public class Contact { 
@PrimaryKey 
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
private Key key; 

@Persistent 
private String streetAddress; 

@Persistent 
private Employee employee; 

public Contact(String s){ 
     streetAddress = s; 
} 
public String getAddress(){ 
     return streetAddress; 
} 
public Employee getEmployee(){ 
     return employee; 
} 

} 

Ecco lo stacktrace completo:

java.lang.ClassCastException: java.lang.Long cannot be cast to 
java.lang.String 
     at org.datanucleus.store.appengine.DatastoreRelationFieldManager 
$1.setObjectViaMapping(DatastoreRelationFieldManager.java:148) 
     at org.datanucleus.store.appengine.DatastoreRelationFieldManager 
$1.apply(DatastoreRelationFieldManager.java:108) 
     at 
org.datanucleus.store.appengine.DatastoreRelationFieldManager.storeRelations 
(DatastoreRelationFieldManager.java:80) 
     at 
org.datanucleus.store.appengine.DatastoreFieldManager.storeRelations 
(DatastoreFieldManager.java:770) 
     at 
org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject 
(DatastorePersistenceHandler.java:231) 
     at org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent 
(JDOStateManagerImpl.java:3067) 
     at org.datanucleus.state.JDOStateManagerImpl.makePersistent 
(JDOStateManagerImpl.java:3043) 
     at org.datanucleus.ObjectManagerImpl.persistObjectInternal 
(ObjectManagerImpl.java:1258) 
     at org.datanucleus.sco.SCOUtils.validateObjectForWriting 
(SCOUtils.java:1365) 
     at 
org.datanucleus.store.mapped.scostore.ElementContainerStore.validateElementForWriting 
(ElementContainerStore.java:401) 
     at 
org.datanucleus.store.mapped.scostore.FKListStore.validateElementForWriting 
(FKListStore.java:764) 
     at org.datanucleus.store.mapped.scostore.FKListStore.internalAdd 
(FKListStore.java:503) 
     at org.datanucleus.store.mapped.scostore.AbstractListStore.add 
(AbstractListStore.java:123) 
     at org.datanucleus.sco.backed.List.add(List.java:752) 
     at com.btg.plyus.scratch.JDOTest.testOneToMany(JDOTest.java:33) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
     at java.lang.reflect.Method.invoke(Unknown Source) 
     at junit.framework.TestCase.runTest(TestCase.java:168) 
     at com.btg.plyus.test.BaseTest.runTest(BaseTest.java:79) 
     at junit.framework.TestCase.runBare(TestCase.java:134) 
     at junit.framework.TestResult$1.protect(TestResult.java:110) 
     at junit.framework.TestResult.runProtected(TestResult.java:128) 
     at junit.framework.TestResult.run(TestResult.java:113) 
     at junit.framework.TestCase.run(TestCase.java:124) 
     at junit.framework.TestSuite.runTest(TestSuite.java:232) 
     at junit.framework.TestSuite.run(TestSuite.java:227) 
     at org.junit.internal.runners.OldTestClassRunner.run 
(OldTestClassRunner.java:76) 
     at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run 
(JUnit4TestReference.java:45) 
     at org.eclipse.jdt.internal.junit.runner.TestExecution.run 
(TestExecution.java:38) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests 
(RemoteTestRunner.java:460) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests 
(RemoteTestRunner.java:673) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run 
(RemoteTestRunner.java:386) 
     at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main 
(RemoteTestRunner.java:196) 
+1

Puoi provare a cambiare la PK in Employee da Long a KEY – jitter

risposta

3

non penso si sta facendo qualcosa di sbagliato. questo sembra essere un bug con il codice del fornitore. vedi this link. non c'è un sacco di informazioni, ma hanno intimo che il PK sul tuo tipo Long Employee.id è problematico.

+0

dolce. Dovrò iniziare a cercare i gruppi datanucleus e i gruppi di motori di app quando ho un problema. –

+0

Google dovrebbe fare, in quanto porterà su quelle fonti così come SO. – akf

0

La colonna ID del database non è compatibile con Long. Non penso che questo abbia nulla a che fare con la mappatura genitore/figlio. Se si desidera confermare, si prega di condividere le dichiarazioni create.

+0

Sto usando google's app-engine come back-end quindi non ci sono istruzioni create. Inoltre, entrambe le entità vengono salvate nel datastore se eseguo makePersistent dopo aver aggiunto il figlio. –

0

sono sicuro che si sta tentando di questo codice sul computer locale. Forse questo è un bug con il plugin Eclipse di GAE, perché, quando si tenta di eseguirlo in produzione, funzionerà correttamente. Penso che la versione locale di App Engine restituisca solo String e non Long per un Key, o è il contrario? Qualunque sia il caso, dovrebbe funzionare sulla produzione.