0

play フレームワークに問題があることがわかりました。再現することもできたので、ここでは簡略化した再現シナリオを示します。

playアプリ起動時にyamlファイルからサンプルデータを読み込みたい。したがって、クラス Fixtures を使用します。yaml ファイルでは、相互に関連するオブジェクトのデータ構造を用意しました。

データ構造のモデル クラスは次のようになります。

@Entity
public class Album extends Model{
 public String name;
 @ManyToOne
 public Artist artist;
}
@Entity
public class Artist extends Model{
 public String name;
 @OneToMany(mappedBy="artist")
 public List<Album> albums = new ArrayList<Album>();
}

yaml ファイルをロードして結果を制御するために使用するジョブは次のようになります。

@OnApplicationStart
public class Bootstrap extends Job {
@Override
public void doJob(){
    Fixtures.deleteAllModels();
    Fixtures.loadModels("sample.yml");
    List<Artist> artists = Artist.findAll();
    for (Artist artist : artists) {
        play.Logger.info(artist.name + " has " + artist.albums.size() + " albums");
    }        
}
}

yml ファイルで次の構造を使用すると、機能します。

Artist(b1):
  name: Nirvana
Artist(b2):
  name: ACDC
Album(a1):
  name: Back in Black
  artist: b2
Album(a2):
  name: Highway to Hell
  artist: b2
Album(a3):
  name: Nevermind
  artist: b1
Album(a4):
  name: Bleach
  artist: b1

しかし、私がこのようにすると、うまくいきません:

Album(a1):
  name: Back in Black
Album(a2):
  name: Highway to Hell
Album(a3):
  name: Nevermind
Album(a4):
  name: Bleach
Artist(b1):
  name: Nirvana
  albums: [a3,a4]
Artist(b2):
  name: ACDC
  albums: [a1,a2]

ただし、ここのドキュメントには、2 番目の方法が機能するはずであることが示されています。

私のサンプルコードで間違いを犯したのでしょうか、それともこれは本当に play フレームワークや JPA に問題があるのでしょうか?

4

1 に答える 1

1

いいえ、ドキュメントによると、2 回目の試行は機能しないはずです。問題は関係所有者の概念にあります。双方向の関係が永続化されている場合は、所有者側 (mappedby によって参照される側) のみが参照されます。

あなたの場合

Artist(b1):
  name: Nirvana
  albums: [a3,a4]

関係の所有者ではない次のリストに作用します:

 //owner of this relationship if attribute artist in Album entity.
 @OneToMany(mappedBy="artist")
 public List<Album> albums = new ArrayList<Album>();

あなたの最初の試みはartistのフィールドを使用していますAlbumartistとの間の双方向関係の所有者であるため、機能AlbumArtistます。同じ理由で、リンクしたドキュメントの例も同様に機能します。

于 2012-08-16T07:15:37.020 に答える