【问题标题】:Foreign key constraint using ebean in play在游戏中使用 ebean 的外键约束
【发布时间】:2014-11-05 17:43:04
【问题描述】:
表格:
-
Attributes: 电影属性(戏剧、惊悚片等)(有列:id、name)
-
User:系统中的用户(有列:id、name)
-
Movie:具有关联的属性(例如具有 'sci-fi - 60%'、'thriller - 40%' 等的'matrix')(具有列:id、attrid、fraction) - attrid 是 @ 的外键987654325@
-
Preference:用户对电影的偏好(具有列:id、uid、movieid、评级)-uid 是 User 的外键,movieid 是 Movie 的外键。
这是我目前的模型描述:
User:
@Entity
@Table(name="USER")
public class User extends Model {
@Id
@Column(name = "uid")
public Long uid;
@Column(name = "name")
public String name;
}
Movie Attribute:
@Entity
@Table(name = "MOVIEATTRIBUTE")
public class Attribute extends Model {
@Id
@Column(name = "attrid")
public Long attrid;
@Column(name = "name")
public String name;
@ManyToMany
@JoinColumn(name = "movieid")
public Movie movie;
}
Movie:
@Entity
public class Movie extends Model {
@Id
@Column(name = "movieid")
public Long movieid;
@ManyToMany
@JoinColumn(name = "attrid")
public Attribute attribute;
@Column(name = "rating")
public Integer rating;
}
Preference:
@Entity
public class Preference extends Model {
@Id
@Column(name = "prefid")
public Long prefid;
@ManyToMany
@JoinColumn(name="uid")
public User user;
@ManyToMany
@JoinColumn(name="movieid")
private Movie movie;
@Column(name = "rating")
public Integer rating;
}
我得到以下运行时异常:无法读取 Preference 的注释。
我错过了什么?
谢谢!
【问题讨论】:
标签:
hibernate
orm
playframework
ebean
【解决方案1】:
你在这段代码中犯了几个错误:
-
您错误地使用了@ManyToMany 注释。您将其添加到属性类中的“电影电影”字段和电影类中的“属性属性”字段中。
因此,您只能为电影对象分配一个属性,并且只能为一部电影分配属性。但是注释说单个电影可以有很多属性,属性可以有很多电影。
如果您使用 @ManyToMany 或 @OneToMany 注释,那么您应该使用集合。所以这里适当的关系应该是:
在电影类中:
@OneToMany(mappedBy="movie")
公共列表属性;
在属性类中:
@ManyToOne
public Movie movie;
- 当您定义两个模型类之间的双向关系时(您在两个类中都放置了注释),您应该在其中一个类中使用“mappedBy”属性。
该属性表示第二类中的字段,它是该关系的第二端。
- 您在任何地方都使用了@ManyToMany 关系。但是根据您的描述,我推断您不需要这种关系。您需要两个双向 @ManyToOne 关系和一个单向 @OneToOne 关系。
- 您的 Movie 类没有“title”属性
-
您不必为表和列指定名称。如果您省略它,它们将与类和字段名称相同。
我对您的代码进行了一些更正以使其正常工作:
用户类别:
@Entity
public class User extends Model {
@Id
public Long id;
public String name;
@OneToMany(mappedBy="user")
public List<Preference> preferences;
}
电影类:
@Entity
public class Movie extends Model {
@Id
public Long id;
@OneToMany(mappedBy="movie")
public List<Attribute> attributes;
public Integer rating;
public String title;
}
属性类:
@Entity
public class Attribute extends Model {
@Id
public Long id;
public String name;
@ManyToOne
public Movie movie;
}
偏好类:
@Entity
public class Preference extends Model {
@Id
public Long id;
@ManyToOne
public User user;
@OneToOne
public Movie movie;
public Integer rating;
}
测试方法:
@Test
public void movieTest () {
FakeApplication app = Helpers.fakeApplication(Helpers.inMemoryDatabase());
Helpers.start(app);
User u = new User();
u.id=1L;
u.name="John";
Movie m = new Movie();
m.id = 1L;
m.title = "Matrix";
m.rating = 5;
Attribute a = new Attribute();
a.id = 1L;
a.name = "Comedy";
a.movie = m;
m.attributes.add(a);
Preference p = new Preference();
p.id = 1L;
p.rating = 10;
p.user=u;
p.movie=m;
Ebean.save(u);
Ebean.save(m);
Ebean.save(a);
Ebean.save(p);
User fu = Ebean.find(User.class, 1L);
Movie fm = Ebean.find(Movie.class, 1L);
Attribute fa = Ebean.find(Attribute.class, 1L);
Preference fp = Ebean.find(Preference.class, 1L);
System.out.println("User: id:"+fu.id+" name:"+fu.name+ " preference_rating:"+fu.preferences.get(0).rating);
System.out.println("Movie: id:" + fm.id+" rating:" + fm.rating + " attrname:"+fm.attributes.get(0).name);
System.out.println("Attribute: id:"+fa.id+" name:"+fa.name);
System.out.println("Preference: id:"+fp.id+" name:"+fp.rating+" username:"+fp.user.name+" movietitle:"+fp.movie.title);
}