我试图按照https://groups.google.com/forum/?fromgroups#!topic/google-appengine-java/KNnDuZ3yXkM中描述的方式,在GAE中使用JDO将子实体保持在双向一对多拥有的关系中,这表示新的孩子需要简单地添加到父对象的“子列表”成员作为事务的一部分。但是,我的子对象不会保留在数据存储区中。
我正在使用GWT 2.5.1,google appengine 1.8.0,主要在开发模式下尝试。
我的父类是UserData,子类是Category2。 以下是父类的相关部分:
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class UserData implements IsSerializable {
@NotPersistent
public static final int CURRENT_EPOCH = 1;
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long key;
@Persistent(mappedBy = "userData")
@Order(extensions = @Extension(vendorName="datanucleus",
key="list-ordering", value="category asc"))
public List<Category2> categories;
...
public UserData() {
this.categories = new LinkedList<Category2>();
...
}
}
和子类:
@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
public class Category2 implements IsSerializable {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
private String key;
@Persistent
private UserData userData;
@Persistent
private String category;
@Persistent
private String subcategory;
@Persistent
private boolean obsolete;
public Category2() {
}
public Category2(String cat, String subcat, boolean obsolete) {
this.category = cat;
this.subcategory = subcat;
this.obsolete = obsolete;
}
...
}
我正在执行的代码是:
PersistenceManager pm = PMF.get().getPersistenceManager();
// Get the UserData object for this user
UserData userData;
Query q = pm.newQuery(UserData.class);
List<UserData> list = (List<UserData>) q.execute();
if (list.size() == 1) {
userData = list.get(0);
} else {
throw new BasileException("Found " + list.size() +
" UserData objects");
}
Category2 cat = new Category2("MyCat", "MySubcat", false);
LOG.log(Level.INFO, "Adding category. Current num cats: " +
userData.categories.size());
Transaction tx = null;
tx = pm.currentTransaction();
try {
tx.begin();
q = pm.newQuery(Category2.class,
"category == cat && subcategory == subcat");
q.declareParameters("String cat, String subcat");
List<Category2> cats = (List<Category2>) q.execute(
cat.getCategory(), cat.getSubcategory());
assert(cats.size() <= 1);
if (cats.size() == 1)
LOG.log(Level.INFO, "Category " + cat + " already exists!");
else
LOG.log(Level.INFO, "Category did not exist");
userData.categories.add(cat);
tx.commit();
LOG.log(Level.INFO, "Num cats now: " + userData.categories.size());
} finally {
if (tx.isActive()) {
LOG.log(Level.INFO, "Transaction aborted!");
tx.rollback();
}
pm.close();
}
每次运行代码时我得到的输出(在GWT devmode中)是:
[java] 05-Jun-2013 14:31:41 com.appspot.basileexp.server.BasileServiceImpl2 runRepro
[java] INFO: Adding category. Current num cats: 0
[java] 05-Jun-2013 14:31:42 com.appspot.basileexp.server.BasileServiceImpl2 runRepro
[java] INFO: Category did not exist
[java] 05-Jun-2013 14:31:42 com.appspot.basileexp.server.BasileServiceImpl2 runRepro
[java] INFO: Num cats now: 1
并在管理控制台中检查数据存储区显示数据存储区中没有Category2实体。
这是我的jdoconfig.xml以防万一:
<?xml version="1.0" encoding="utf-8"?>
<jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig">
<persistence-manager-factory name="xg-transactions">
<property name="javax.jdo.PersistenceManagerFactoryClass" value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/>
<property name="javax.jdo.option.ConnectionURL" value="appengine"/>
<property name="javax.jdo.option.NontransactionalRead" value="true"/>
<property name="javax.jdo.option.NontransactionalWrite" value="true"/>
<property name="javax.jdo.option.RetainValues" value="true"/>
<property name="datanucleus.appengine.autoCreateDatastoreTxns" value="true"/>
</persistence-manager-factory>
</jdoconfig>
知道我在这里做错了吗?