在游戏中使用ebean的外键约束

时间:2014-11-05 17:43:05

标签: hibernate orm playframework ebean

表:

  1. Attributes:电影属性(戏剧,惊悚片等)(有列:id,名称)
  2. User:系统中的用户(具有列:id,名称)
  3. Movie:有关联的属性(比如'矩阵'有'sci-fi - 60%','惊悚片 - 40%'等)(有列:id,attrid,fraction) - {{1} }是attrid
  4. 的外键
  5. Attributes:用户对电影的偏好(包含列:id,uid,movieid,评级) - Preferenceuid的外键,User是外键进入movieid
  6. 这是我到目前为止的模型描述:

    Movie

    我收到以下运行时异常:无法读取Preference的注释。

    我错过了什么?

    谢谢!

1 个答案:

答案 0 :(得分:1)

您在此代码中犯了几个错误:

  1. 您错误地使用了@ManyToMany注释。你把它添加到了电影电影'属性类中的字段和'属性属性' Movie类中的字段。 因此,您只能为影片对象分配一个属性,并且只能分配一个要归属的影片。但是注释说单个电影和许多电影的属性可以有很多属性。 如果您使用@ManyToMany或@OneToMany注释,那么您应该使用集合。所以这里适当的关系应该是:

    在电影课上:

    @OneToMany(的mappedBy ="电影&#34) 公共列表属性;

  2. 在属性类中:

    @ManyToOne
    public Movie movie;
    
    1. 当您定义两个模型类之间的双向关系时(在两个类中都添加了注释),您应该使用' mappedBy'其中一个属性。 此属性指示第二类中的字段,该字段是此关系的第二个结尾。
    2. 你到处都使用@ManyToMany关系。但是根据你的描述我推断出你不需要这种关系。您需要两个双向@ManyToOne关系和一个单向@OneToOne关系。
    3. 您的电影课程没有'标题'属性
    4. 您不必指定表和列的名称。如果省略它,它们将与类和字段名称相同。

      我在您的代码中进行了一些修正以使其正常工作:

    5. 用户类:

      @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);
      }