【问题标题】:Custom bridge table in playframework ebeanplayframework ebean中的自定义桥接表
【发布时间】:2014-11-29 16:58:03
【问题描述】:

我没有成功尝试创建可以解决两个@ManyToMany 关系的桥接表。但是,此表必须包含附加字段。例如:

Course: -course_id - pk

Student: -student_id -pk

Bridge: -(course_id, student_id) - pk
        -additional_field

我的学生班级如下所示:

@Entity
public class Student extends Model {

    @Id
    @OneToMany
    public List<Bridge> student_id;
}

课程基本相同。

桥表如下所示:

@Entity
public class Bridge extends Model{

    @EmbeddedId 
    public compound_key student_course;

    public String additional_field;

    @Embeddable
    public class compound_key{

        @ManyToOne
        public Student student_id;

        @ManyToOne
        public Student course_id;

    }

}

感谢您的帮助。

【问题讨论】:

  • 为什么网桥列表是主键?主键不应该是 long 还是 int ?
  • @rtruszk 这就是我在 ebean 用户指南中读到 OneToMany 关系已完成的方式。逻辑上是的,我希望 pk 是 int,但是我不知道如何将它链接到桥表。
  • 请注意,'Bridge' 表通常被称为 'Intersection' 表,因此只需在此处添加此评论以帮助将来进行谷歌搜索。

标签: java database playframework playframework-2.2 ebean


【解决方案1】:

我找到了以下解决方案。这是在 Bridge 中没有组合键的解决方案。我在 Bridge 类中添加了正常的 @Id 字段,并且与 Student 和 Course 的关系是正常的关系。 此解决方案在数据库的“bridge”表中包含一个额外的“id”字段。

代码如下:

学生.java:

@Entity
public class Student extends Model {

    @Id
    public Integer id;

    @OneToMany(mappedBy="student")
    public List<Bridge> bridges;

    public static Finder<Integer,Student> find = new Finder<Integer,Student>(
        Integer.class, Student.class
    ); 
}

课程.java:

@Entity
public class Course extends Model {

    @Id
    public Integer id;

    @OneToMany(mappedBy="course")
    public List<Bridge> bridges;

    public static Finder<Integer,Course> find = new Finder<Integer,Course>(
        Integer.class, Course.class
    ); 
}

Bridge.java:

@Entity
public class Bridge extends Model {

    @Id
    public Integer id;

    @ManyToOne public Student student;

    @ManyToOne public Course course;

    public String additional_field;

    public static Finder<Integer,Bridge> find = new Finder<Integer,Bridge>(
        Integer.class, Bridge.class
    ); 
}

编辑

经过多次尝试,我在 Bridge 类中找到了使用复合键的解决方案。班级学生和课程与之前的解决方案相同。

Bridge.java 改成如下:

@Entity
public class Bridge extends Model {

    Bridge() {
        bridgeId = new BridgeId();      
    }

    @EmbeddedId
    protected BridgeId bridgeId;

    @ManyToOne
    @JoinColumn(name = "student_id", insertable = false, updatable = false)
    private Student student;

    @ManyToOne 
    @JoinColumn(name="course_id", insertable = false, updatable = false)
    private Course course;

    public String additional_field;

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student aStudent) {
        student=aStudent;
        bridgeId.student_id = aStudent.id;
    }

    public Course getCourse() {
        return course;
    }

    public void setCourse(Course aCourse){
        course=aCourse;
        bridgeId.course_id = aCourse.id;
    }
}

还有额外的BridgeId.java:

@Embeddable
public class BridgeId implements Serializable
{
    public Integer student_id;

    public Integer course_id;

    public int hashCode() {
        return student_id + course_id;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) 
            return true;
        BridgeId b = (BridgeId)obj;
        if(b==null)
            return false;
        if (b.student_id == student_id && b.course_id == course_id) {
            return true;
        }
        return false;
    }
}

这段代码更重要的是:

  1. 嵌入 id 的字段映射到与多对一关系相同的列。
  2. “student_id”和“course_id”列的值是从嵌入的 id 而不是从关系中插入的。这是因为关系的属性“可插入”和“可更新”设置为 false。
  3. 我必须在“学生”和“课程”字段中添加 getter 和 setter。在设置器中,我正在更新嵌入键的字段。

上述解决方案有几种解决方法。但我找不到更简单、更干净的。

【讨论】:

  • 当我这样做时,我会延迟 Beanlist。你是怎么查询的?
  • 另外,您的网桥中的 id 字段是什么?这是一个附加字段还是?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多