我正在尝试按照https://groups.google.com/forum/?fromgroups#!topic/google中描述的方式在 GAE 中与 JDO 保持双向一对多拥有关系中的子实体-appengine-java/KNnDuZ3yXkM,它表示只需将新子对象作为事务的一部分添加到父对象的“子列表”成员中。但是,我的子对象没有保存在数据存储中。
我正在使用 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 开发模式下)时得到的输出是这样的:
[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>
知道我在这里做错了什么吗?