我发现了play框架的问题。我也可以重现它,所以在这里我将展示一个简化的再现szenario。
启动播放应用程序时,我想从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文件并控制结果的Job看起来像这样:
@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]
然而,文档权利here告诉我们,第二种方式应该有效。
我的示例代码中是否犯了错误,或者这是播放框架或JPA的问题?
答案 0 :(得分:1)
不,根据文件,你的第二次尝试不应该奏效。问题在于关系所有者的概念。当双向关系持续存在时,只查询所有者方(由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
中的Album
字段。它有效,因为artist
是Album
和Artist
之间双向关系的所有者。由于同样的原因,您链接的文档中的示例也适用。