1

私は JDO とその概念が初めてです。以前は非常に単純な ORMLite を使用していましたが、ORMLite で行ったことを JDO で行う方法がわかりません。私は2つのエンティティを持っていBroadcastますMovie. EveryBroadcastには 1 がMovieあり、 a には複数のMovieがありBroadcastsます。ブロードキャストの ID は生成されず、永続化する前に構成されます。だからこれは私がやったことです:

@PersistenceCapable
public class Broadcast {

    @PrimaryKey
    private String id;

    @Persistent
    private Movie movie;

    //More fields....
}

これがMovieクラスです (ここでも ID は生成されず、オブジェクトを保存する前に構成されます):

@PersistenceCapable
public class Movie {

    @PrimaryKey
    private String id;

    @Persistent(mappedBy = "movie")
    private List<Broadcast> broadcasts;

    //More fields....
}

これで、DB 内のすべてのデータをフェッチして保存するサーブレットができました。最初に、すべての の映画について、タイトルとその ID しかわかっていないので、すべての をフェッチしBroadcastsますBroadcast。そのため、トランザクションでオブジェクトを含む を保存しBroadcastますMovie(保存されるオブジェクトが 2 つあるため、これはアトミックでなければなりません)。アクション):

// Check if this broadcast already exist.
try {
     mgr.getObjectById(Broadcast.class, brdcst.getId());
} catch (Exception e) {
     if(e instanceof JDOObjectNotFoundException){
    Transaction tx = null;
    try{
        tx = mgr.currentTransaction();
        tx.begin();
        mgr.makePersistent(brdcst);
        tx.commit();
    }
    catch(Exception e1){
        sLogger.log(Level.WARNING, e.getMessage());
    }
    finally{
        if (tx.isActive()) {
            tx.rollback();
        }
        mgr.flush();
    }

     }
     else sLogger.log(Level.WARNING, e.getMessage());
}

次に、映画のデータを取得して保存し、同じ ID を使用して、前のオブジェクトをオーバーライドします (オブジェクトへの参照がない別のスレッドでBroadcast)。

try {
    sLogger.log(Level.INFO, "Added the movie: " + movie);
    mgr.makePersistent(movie);
} catch (Exception e) {
    e.printStackTrace();
}
finally{
    mgr.flush();
}

明確にするために、これがORMLiteで起こっていることであり、私がここで起こりたいことです。オブジェクトを保存するときにBroadcast、ID を付けてムービーを追加するので、将来、この ID はMovieデータベース内のオブジェクトへの参照を取得するのに役立ちます。

しかし、DB にブロードキャストのクエリを実行していて、それらの中で映画への参照を見つけたいと思っているときはいつでも、null または次の例外が返されます。

Field Broadcast.movie should be able to provide a reference to its parent but the entity does not have a parent.  Did you perhaps try to establish an instance of Broadcast as the child of an instance of Movie after the child had already been persisted?

それで、私はここで何が間違っていますか?

4

3 に答える 3

1

ここで何が起こっていたのかについての簡単な説明:Listウェブから取得したブロードキャストの数。リスト内のすべてのブロードキャストには、タイトルのみを持つ Movie オブジェクト (Broadcast.setMovie) が含まれていました。私の目的は、このブロードキャストのリストを繰り返し処理し、すべてのブロードキャストのムービーに必要な情報を取得することでした (これが、すべての操作の最後に mgr.flush() を使用した理由です)。そのため、最初にブロードキャストが存在しない場合はデータストアに追加し、次にムービーのデータを取得して永続化しました。そして、ORMLite で、外部のフィールドがあり、このオブジェクトを保存すると、フレームワークがこのオブジェクトと外部フィールドのオブジェクトの ID を保存するという問題がありました。したがって、id=10 の Broadcast と id=2 の Movie があるとします。フレームワークは、Movie フィールドに 2 を指定して Broadcast をデータベースに保存します。これが私がここでやりたかったことですが、JDO では このように動作しません。@Noofizが彼の回答で共有した良い例に従った後、私はそれを間違っていて、逆の順序で行う必要があることに気付きました。すべてのブロードキャスト オブジェクトからムービーを取得し、Movie.addBroadcast を使用してブロードキャストをムービーに追加し、データストアに永続化します。これは私が行ったことであり、正常に動作しています。

皆さんの助けに感謝します。これが他の人にも役立つことを願っています。

于 2013-03-11T14:10:27.177 に答える
1

GAE で ralations を使用するcom.google.appengine.api.datastore.Keyには、長いキーまたは文字列キーの代わりに使用する必要があります。

于 2013-03-09T16:57:35.573 に答える
0

すべてのタイプのリレーション (所有している 1-N の bidir を含む) の GAE JDO で使用できる、十分なコード サンプル関連する永続化コードがあります。

トランザクションが終了した後、「フラッシュ」がありますが、よくわかりません。Movie オブジェクトと Broadcast オブジェクトを関連付けるコードがありません (つまり、Movie.addBroadcast はどこにありますか?)。ログをまったく参照しません (データストアとの間のすべての PUT および GET について通知します)。映画を取得して「保存して同じIDを上書きする」と言いますが、これを行うコードや、その時点でのオブジェクトの状態についての言及はありません...一時的なものですか? 離れた?

于 2013-03-10T09:03:58.870 に答える