Hibernate:对同一个类的多个关联

时间:2011-06-10 09:11:05

标签: hibernate associations

我需要将一个实体与两个其他实体列表相关联 - 两个列表都包含相同类型的实体。它看起来像这样:

@Entity
public class Course {
    private List<Test> preTests;
    @OneToMany(cascade= javax.persistence.CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = “course”)
    @OrderBy("testNumber")
    public List< Test > getPreTests() {
        return preTests;
    }

    public void setPreTests(List< Test > preTests) {
        this. preTests = preTests;
    }

    private List<Test> postTests;
    @OneToMany(cascade= javax.persistence.CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = “course”)
    @OrderBy("testNumber")
    public List< Test > getPostTests() {
        return postTests;
    }

    public void setPostTests(List< Test > postTests) {
        this. postTests = postTests;
    }
}

现在,我甚至没有费心去尝试本身,因为很明显Hibernate没有办法区分哪个Tests进入preTests哪个进入postTests。如果我错了,请纠正我,但它必须使用的唯一信息是Test表中指向Course记录的外键,并且测试前后都会指向在同一个Course。 我的下一个想法是创建PreTest的明确PostTestTest子类,并有一个List<PreTest>和一个List<PostTest>,但这会导致臭名昭着的“mappedBy”引用一个未知的目标实体属性:当然“问题,Hibernate所说的人 - 因为让我感到挑剔的原因 - 是设计上的,因此不太可能消失。

我目前的想法是使用单独的连接表来保存这两个关联。我认为没有理由不应该这样做。它也适合我希望将所有显式SQL(甚至HQL)保留在实体定义之外,并抵制强制创建奇怪的复合键或以其他方式编写仅反映我的持久性框架的怪癖而不是我的对象设计的代码。

尽管如此,在我致力于这个课程之前,我要问的是你们中是否有人有更清洁的解决方案,或者知道我的推理存在缺陷。

提前致谢。

迈克尔

2 个答案:

答案 0 :(得分:1)

我不知道这是不是一个好主意,但你可以包括一个

@org.hibernate.annotations.Where
关联映射的

注释,并在Test表上使用一个鉴别器列,以便在加载Test实例时可以从Post测试中告诉Pre。

答案 1 :(得分:0)

一个选项是Table per class hierarchy继承映射方法,听起来就像你开始做的那样,但并没有完全采用。

另外一种选择是,如果另有说明,使用@Where annotation

我经常用于类似情况的第三个选项是为与课程相关的所有测试映射单个集合,然后添加辅助方法以在您希望使用前或后测试时返回所需的子集。示例代码:

    @Entity
    public class Course {

    private List<Text> tests;

    @OneToMany(cascade= javax.persistence.CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = “course”)
    @OrderBy("testNumber")
    public List< Test > getTests() {
        return tests;
    }

    public List< Test > getPreTests() {
        List<Test> preTests = new ArrayList<Test>();
        for (Test test : preTests) {
           if (test.isPreTest()) {
               preTests.add(test);
           }
        }
        return preTests;
    }


    public List< Test > getPostTests() {
        List<Test> postTests = new ArrayList<Test>();
        for (Test test : postTests) {
           if (test.isPostTest()) {
               postTests.add(test);
           }
        }
        return postTests;
    }