【问题标题】:Foreign key constraint using ebean in play在游戏中使用 ebean 的外键约束
【发布时间】:2014-11-05 17:43:04
【问题描述】:

表格:

  1. Attributes: 电影属性(戏剧、惊悚片等)(有列:id、name)
  2. User:系统中的用户(有列:id、name)
  3. Movie:具有关联的属性(例如具有 'sci-fi - 60%'、'thriller - 40%' 等的'matrix')(具有列:id、attrid、fraction) - attrid 是 @ 的外键987654325@
  4. Preference:用户对电影的偏好(具有列:id、uid、movieid、评级)-uidUser 的外键,movieidMovie 的外键。

这是我目前的模型描述:

  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】:

    你在这段代码中犯了几个错误:

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

      在电影类中:

      @OneToMany(mappedBy="movie") 公共列表属性;

    在属性类中:

    @ManyToOne
    public Movie movie;
    
    1. 当您定义两个模型类之间的双向关系时(您在两个类中都放置了注释),您应该在其中一个类中使用“mappedBy”属性。 该属性表示第二类中的字段,它是该关系的第二端。
    2. 您在任何地方都使用了@ManyToMany 关系。但是根据您的描述,我推断您不需要这种关系。您需要两个双向 @ManyToOne 关系和一个单向 @OneToOne 关系。
    3. 您的 Movie 类没有“title”属性
    4. 您不必为表和列指定名称。如果您省略它,它们将与类和字段名称相同。

      我对您的代码进行了一些更正以使其正常工作:

    用户类别:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-14
      • 1970-01-01
      • 1970-01-01
      • 2021-07-02
      • 2011-08-30
      • 2013-05-03
      相关资源
      最近更新 更多