2016-06-13 6 views
1

私はebeanのモデルを更新していますが、モデルへの他の参照は変更されていないという問題があります。 結合された列または@ManyToManyマッピングを使用して、更新されたモデルを参照するモデルを自動的に更新または更新することができるかどうかは疑問でした。ebean ormのすべての参照を更新するには

これは私のテストコードです:

// Create students and club 
Student john = new Student("John"); 
Student lizz = new Student("Lizz"); 
Club soccer = new Club("Soccer"); 

// Save the students 
server.save(john); 
server.save(lizz); 

// Add them to their club 
john.getClubs().add(soccer); 
server.save(john); 
lizz.getClubs().add(soccer); 
server.save(lizz); 

// Reload users (fresh) 
john = server.find(Student.class).where().ieq("name", "john").findUnique(); 
lizz = server.find(Student.class).where().ieq("name", "lizz").findUnique(); 
System.out.println("Club: " + lizz.getClubs().get(0).getName()); 

// Modify the club name 
john.getClubs().get(0).setName("Baseball"); 
System.out.println("Club: " + lizz.getClubs().get(0).getName()); 

// Update the club 
server.save(john); 
System.out.println("Club: " + lizz.getClubs().get(0).getName()); 

、これらは私のモデルです:

@Entity 
@Table(name = "students") 
public class Student { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(unique = true, updatable = false) 
    private int id; 

    @Column 
    private String name; 

    @ManyToMany(mappedBy = "students", cascade = CascadeType.ALL) 
    private List<Club> clubs; 

    @Version 
    private long version; 
} 

と:

@Entity 
@Table(name = "clubs") 
public class Club { 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(unique = true, updatable = false) 
    private int id; 

    @Column 
    private String name; 

    @ManyToMany 
    @JoinColumn 
    private List<Student> students; 

    @Version 
    private long version; 
} 

出力は、クラブがそうのように、サッカーのように残っていることですクラブ:サッカー
クラブ:サッカー
クラブ:サッカー

+0

コードがjohnとlizzをリロードすると、スパニングトランザクション/永続コンテキストが存在しないため、2つの独立したオブジェクトグラフが作成されます。これらのオブジェクト・グラフは、ある時点の特定の分離レベル(JPA仕様などに基づいてデフォルトでコミットされた読取り)でのデータベースの一部のスナップショットを表します。 –

+0

@RobBygraveは意味があります。分離レベルをSERIALIZABLEに設定します。 常に同じ参照を保持することは可能ですか? – lenis0012

+0

SERIALIZABLEオプティミスティック並行性チェックは機能しません(チェックはトランザクションの開始からの相対的なものです)。一般的には、SERIALIZABLEで悲観的なロックを使い始める必要があります。並行性が問題となるアプリケーションのために、READ_COMMITTEDはIMOよりはるかに良い選択です... –

答えて

2

あなたはジョンを編集していますが、Lizzを印刷しています。 Lizzは変更されていません(Lizzのクラブはロードされており、リフレッシュされていません)。

理由は、JohnとLizzのフェッチが2つの異なるトランザクションにあり、2つの異なる永続コンテキストがあるためです。

BOTH JohnとLizzのフェッチにまたがるトランザクションがあった場合、基本的な永続コンテキストがトランザクションにスコープされ、クラブで同じインスタンスが使用されるため、クラブは両方とも同じ/単一インスタンスになります。あなたはそれはあなたがそれが必要だと思う何を確認するように、ログインSQLおよびトランザクションをオンになっているはずですサイドポイントとして

<!-- LOGBACK configuration --> 

<!-- SQL and bind values --> 
<logger name="org.avaje.ebean.SQL" level="TRACE"/> 

<!-- Transaction Commit and Rollback events --> 
<logger name="org.avaje.ebean.TXN" level="TRACE"/> 

ロギング設定についてはhttp://ebean-orm.github.io/docs/setup/logging

ドを参照してください。

server.beginTransaction(); 
try { 
    // persistence context scoped to transaction so 
    // .. now spans both fetches giving John and Lizz 
    // .. the same shared Club instance 
    john = server.find(Student.class).where().ieq("name", "john").findUnique(); 
    lizz = server.find(Student.class).where().ieq("name", "lizz").findUnique(); 
} finally { 
    server.endTransaction(); 
} 
+0

ありがとうございます。これは非常に役に立ちます。 しかし、実際には両方同時に読み込まないでしょう。 しかし、私はすべてのクラブが矛盾することなく、1人の学生のためにクラブを変更したいと思います。 – lenis0012

+0

上記の他の説明を参照してください。 –

+0

FYI:Ebeanの「Persistence Context」についてhttps://youtu.be/Y18HsBkeLukで話し合っているビデオがあります.JAAと比較し、これがなぜこのように機能するのかを少し説明してほしい。 –

関連する問題