GWT JDO 機能を実装しようとしているときに問題が発生しました。Data
オブジェクトを含むオブジェクトがあるとしましょうItem
。データストアでは、これにより 1 対 1 の関係が作成されます。
問題は、データストアからオブジェクトを取得しようとすると、'item' フィールドが常に nullになることです。もちろん、初期化されたオブジェクトを含むデータストアにオブジェクトを置きItem
ます (リストの終わり)。データストアを表示すると、Data
とItem
エンティティの両方が存在します。
1 対 1 の関係を間違って管理していませんか? 他に何が必要ですか?同じ状況は、1 対多の関係 (の配列Item
)を作成しようとした場合です。
Data.java:
package com.rafalrybacki.jdotest.client.model;
import java.io.Serializable;
import java.util.ArrayList;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Data implements Serializable {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long id;
@Persistent
private String symbol;
@Persistent
public Item item;
public Data(){}
// ...
}
アイテム.java:
package com.rafalrybacki.jdotest.client.model;
import java.io.Serializable;
import javax.jdo.annotations.Extension;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class Item implements Serializable {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
@Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true")
private String encodedKey;
@Persistent
public String title;
public Item(){}
public Item(String title){
this.title = title;
}
// ...
}
サーバー側の実装:
public void save(Data data) {
PersistenceManager pm = PersistenceManagerFactoryGetter.get().getPersistenceManager();
try {
pm.makePersistent(data);
} finally {
pm.close();
}
return;
}
public Item load() {
PersistenceManager pm = PersistenceManagerFactoryGetter.get().getPersistenceManager();
List<Data> datas = new ArrayList<Data>();
Data data0 = null;
try {
Query q = pm.newQuery(Data.class);
datas = (List<Data>) q.execute();
if (datas.size() > 0)
data0 = pm.detachCopy(datas.get(0)); // get first item only
} finally {
pm.close();
}
return data0.item; // always null !!!!!
}
クライアント側では、そのような作成されたdata
オブジェクトを操作しています( nullitem
ではないフィールドを使用)
Data d = new Data("data1");
d.item = new Item("item2");
service.save(d, ...); //rpc service call
// ...
service.load(...);