2011-06-30 8 views
3

私はGoogleのアプリエンジン/データストアのスキルを追い払っています。Google Datastore - エンティティの更新に関する問題

私は次のようにエンティティを更新しようとしていますthe example on the GAE documentationを1として:

// persistence and business logic 
PersistenceManager pm = PMF.get().getPersistenceManager(); 

// get it 
NickName n = pm.getObjectById(NickName.class, nicknameId); 

// update fields 
n.givenName = "new name"; 
n.nickName = "new nickname"; 
n.timeStamp = new Date();    

// close manager to persist changes 
pm.close(); 

これは動作しません(変更のように持続し、ないエラーや他の何かされていません)!

// persistence and business logic 
PersistenceManager pm = PMF.get().getPersistenceManager(); 

NickName n = new NickName("new name", "new nickname", new Date()); 

// set id 
n.id = nicknameId; 

pm.makePersistent(n); 

pm.close(); 

が、私は感じが私はすでにこの私はアプリエンジンと近づい第一の時間を解決した:私は、同じIDを持つ新しいエンティティを作成する場合、変更が持続し得ることを見出した。同時に

データストア。すべてのヘルプ感謝

@PersistenceCapable 
public class NickName { 

    public NickName(String name, String nickname, Date timestamp) { 
     this.givenName = name; 
     this.nickName = nickname; 
     this.timeStamp = timestamp; 
    } 

    @PrimaryKey 
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) 
    public String id; 

    @Persistent 
    public String givenName; 

    @Persistent 
    public String nickName; 

    @Persistent 
    public Date timeStamp; 
} 

これは私のエンティティは次のようになります!

+2

「これは機能しません!」良い声明ではありません。コンソールログに表示される正確なエラーは何ですか? –

+0

コンソールログには何も表示されませんが、データストアを見ても変更内容は保持されません(あるいは、古い値がそこに残っています) – JohnIdol

答えて

2

setterメソッドを実行する代わりに、フィールドを直接設定することが1つの問題かもしれません。私は、JDOがフィールドセッターをインスツルメンテーションして、永続レイヤに発生した変更を通知するように動作することはかなり確信しています。バッキングフィールド値自体の変更を直接監視する方法はありません。そのため、おそらく試してみてください。

n.setGivenName("new name"); 
n.setNickName("new nickname"); 
n.setTimeStamp(new Date()); 

あなたはmakePersistent()呼び出しがフィールドの値を検査し、それらを保存する必要があるパーシスタンス・マネージャーに指示しますので、あなたがオブジェクトを作成するときに、直接フィールドを設定して逃げることができるしています。フィールド値を直接このように設定することは、一般的にコーディングスタイルが悪いとみなされます。

さらに、JDOインターフェイスの代わりにJPAインターフェイスを使用してみましたか? GAEでは、彼らは交換する必要があります:

EntityManager em = EMF.get(); 

NickName n = em.find(NickName.class, nicknameId); 

n.givenName = "new name"; 
n.nickName = "new nickname"; 
n.timeStamp = new Date();  

em.merge(n); 

em.close(); 

これはあなたにも、直接フィールド値を設定することで動作するはず明示的merge()コールを提供します。

+1

FYI JDOの監視方法が* public *フィールドは、呼び出し元クラスを@PersistenceAwareとしてマークすることです。 JPAにはそのような方法がありませんので、JDO – DataNucleus

+0

に固執するのが一番です。私は怠け者であり、それは単なるテストだったので、セッターを置いていませんでした - 偉大な提案のおかげで – JohnIdol

+0

@DataNucleus - JPAとJDOの選択は本当に個人的な好みの問題です。個人的には、JDOは非常に貧しい選択肢だと思っています。いずれにせよ、パブリックフィールドに直接加えられた変更を監視する能力は、JDOを選択する魅力的な理由ではないと私は考えています。うまく設計されたアプリでは、一般に公開領域を最初に持っていたり、設定したりしていません。 – aroth