ok FINALLY I got the point,
yet I think that DataStore's JDO implementation ( I don't know if its DataNucleus job) miss there something. According to transactions on DataStore usually only entities along an ancestor can be persisted in one go, exceptionally GAE claims to support Cross-Group Transactions which is limited by number but can persist unrelated entity paths. Both did not apply in my case.
The poor solution is now to enforce unowned relationship via a Key (GAE proprietary), which is the only possible kandidate to describe ancestor path so that DataStore gets it right is following extension to my POJOs:
class A {
...
private String naturalPK;
public String getNaturalPK(){
return naturalPK;
}
...
}
class C {
...
public void setId(String id){
this.id=id;
}
...
}
and the persistency-code:
tx.begin();
// we have to assign parent/child keys to enforce ancestor path
Key parentKey = KeyFactory.createKey("A", A.getNaturalPK());
a.setId(KeyFactory.keyToString(parentKey));
// now build child key
a.getB().getC().setId(KeyFactory.createKeyString(parentKey, "C", A.getNaturalPK()));
pm.makePersistent(offerer);
tx.commit(); // works.
one issue is that I cannot use surrogate keys here, the other thing is that I dont want non-JDO and non-BO code to be in my POJOs, so the parent-child relationship has to be established somewhere in die JDO-DAO implementation. I suppose that DataNucleus GAE port is doing somewhat inaccurate here as the persistency graph looks to be reversed :)