Hi everybody,
My model contains a Class A <---Bidi one to many---> B ---one to
many---> C ---one to one---> D.
I wrote 3 unit tests with appengine 1.2.8 and JDO on eclipse 3.5 which
generate an error.
It looks like a bug in JDO to me but I may be wrong:
1- org.springframework.orm.jdo.JdoSystemException: can't update the
same entity twice in a transaction or operation; nested exception is
javax.jdo.JDOException: can't update the same entity twice in a
transaction or operation
NestedThrowables:
java.lang.IllegalArgumentException: can't update the same entity twice
in a transaction or operation
at
org.springframework.orm.jdo.PersistenceManagerFactoryUtils.convertJdoAccessException
(PersistenceManagerFactoryUtils.java:247)
at org.springframework.orm.jdo.DefaultJdoDialect.translateException
(DefaultJdoDialect.java:230)
at
org.springframework.orm.jdo.JdoTransactionManager.convertJdoAccessException
(JdoTransactionManager.java:503)
at org.springframework.orm.jdo.JdoTransactionManager.doCommit
(JdoTransactionManager.java:427)
However (see the code below), when I change the member variable
expList of class A then it works. An other way is not to call setEmail
of class A (but if I set the firstName which is also a String then it
works)...
This look like a JDO bug or bug to me.
2- com.testgae.xp.server.dao.DaoException:
javax.jdo.JDOFatalUserException: Illegal argument
NestedThrowables:
java.lang.IllegalArgumentException: can't operate on multiple entity
groups in a single transaction. found both Element {
type: "A"
id: 1
}
and Element {
type: "C"
id: 3
}
Here I don't understand because A and C should be in the same group.
There are only owned relationship between them. If I create the
hierarchy A->B->C->D all at once it works. But not if I do A->B and
then ->C->D like in my second test. Is it a bug in my code or a JDO
bug again?
If I set manually the key of class C (as a child of B) then that
works... Another way to make it works is to change the Set of C to a
List of C in class B.
Isn't it a bug in JDO or something?
3- my "childs" are never loaded. But if I used the updated object
returned by my DAO instead of loading it from the datastore, then that
works. All my requests return null. I can't understand why because
this was working in appengine 1.2.1.
This is likely something about my code is missing or wrong but I can't
see what.
You can find my source code below and also a full packed eclipse
project ready to import :D:
http://www.mediafire.com/file/0rwmfnfjtqg/TestGAE_src.zip
http://www.mediafire.com/file/tmknjaaoxwn/TestGAE_full.zip
Thanks a lot for your help!
Here is an extract of my code:
@PersistenceCapable(identityType = IdentityType.APPLICATION,
detachable="true")
public class A {
private static final long serialVersionUID = 7061281232540895192L;
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key _key;
@Persistent
private String _firstName;
@Persistent
private String _email;
@Persistent(mappedBy="_parent", defaultFetchGroup="true")
/////////////////////////////////////////////////////////////
// If I rename _expList in _aList, then test1 works
/////////////////////////////////////////////////////////////
private List<B> _expList;
...
@PersistenceCapable(identityType = IdentityType.APPLICATION,
detachable="true")
public class B {
private static final long serialVersionUID = 829289483086117887L;
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key _key;
@Persistent
private String _string;
@Persistent(defaultFetchGroup="true")
private A _parent;
@Persistent(defaultFetchGroup="true")
/////////////////////////////////////////////////////////////
// If I change this to List<C>, then test2 works
/////////////////////////////////////////////////////////////
private Set<C> _cUpdates;
...
@PersistenceCapable(identityType = IdentityType.APPLICATION,
detachable="true")
public class C {
private static final long serialVersionUID = -5806378892487300728L;
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key _key;
@Persistent
private int _level;
@Persistent(defaultFetchGroup="true")
private D _sList;
...
@PersistenceCapable(identityType = IdentityType.APPLICATION,
detachable="true")
public class D {
private static final long serialVersionUID = -6630402708475167158L;
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Key _key;
@Persistent
@Unique
private String _name;
...
private final A initAinDatabase(String pFirstName, String
pLastName, String pEmail)
throws DaoException {
A a = new A(pFirstName, pEmail);
A newA = _aDao.create(a);
assertAEquals(newA, a);
return a;
}
public final void testBug() throws DaoException {
A a = initAinDatabase("Dupont", "Pierre",
"[email protected]");
D d = new D();
/////////////////////////////////////////////////////////////
// If I set d to null, then test1 works
/////////////////////////////////////////////////////////////
C c = new C(d, 3);
B b = new B();
b.addCUpdate(c);
/////////////////////////////////////////////////////////////
// If I use a.setFirstName("") instead, then test1 works
/////////////////////////////////////////////////////////////
a.setEmail("");
a.addB(b);
_aDao.update(a);
// FIXME Here I get a
// org.springframework.orm.jdo.JdoSystemException: can't update
the
same
// entity twice in a transaction or operation; nested exception
is
// javax.jdo.JDOException: can't update the same entity twice
in a
// transaction or operation
}
public final void testBug2() throws DaoException {
A a = initAinDatabase("Dupont", "Pierre",
"[email protected]");
B experience = new B();
a.setEmail("");
a.addB(experience);
a = _aDao.update(a);
D d = new D();
C c = new C(d, 3);
a.getBList().get(0).addCUpdate(c);
a = _aDao.update(a);
// FIXME Here I get a
// DaoException: javax.jdo.JDOFatalUserException: Illegal
argument
// NestedThrowables:
// java.lang.IllegalArgumentException: can't operate on multiple
entity
// groups in a single transaction. found both Element {
// type: "A"
// id: 1
// }
// and Element {
// type: "C"
// id: 3
// }
}
public final void testBug3() throws DaoException {
A a = initAinDatabase("Dupont", "Pierre",
"[email protected]");
B b = new B();
b.setString("Tooto");
a.addB(b);
A a2 = _aDao.update(a);
a = _aDao.loadByKey(a.getKey());
D d = new D();
C c = new C(d, 3);
// FIXME Here I have an IndexOutOFBoundException / Index 0
Size 0
a.getBList().get(0).addCUpdate(c);
a = _aDao.update(a);
}
--
You received this message because you are subscribed to the Google Groups
"Google App Engine for Java" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-appengine-java?hl=en.