Hibernate: несколько ассоциаций в одном классе - PullRequest
3 голосов
/ 10 июня 2011

Мне нужно связать объект с двумя списками других объектов - оба списка, содержащие объекты одного типа. Это выглядит примерно так:

@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 и PostTest Test и иметь один List<PreTest> и один List<PostTest>, но это привело к печально известной проблеме «mappedBy со ссылкой на неизвестное свойство целевого объекта: курс» , что люди в Hibernate утверждают - по причинам, которые кажутся мне суетливыми - не совсем понятны и поэтому вряд ли уйдут.

Моя текущая мысль - использовать отдельные таблицы соединений для хранения двух ассоциаций. Я не вижу причин, почему это не должно работать. Это также соответствует моему желанию не допустить явного SQL (или даже HQL) в определения сущностей и сопротивляться принуждению создавать странные составные ключи или иным образом писать код, который отражает только причуды моей персистентной инфраструктуры, а не мой объектный дизайн.

Тем не менее, прежде чем я приступлю к этому курсу, я спрашиваю, есть ли у кого-нибудь из вас более ясное решение или он знает о недостатках в моих рассуждениях здесь.

Заранее спасибо.

Michael

Ответы [ 2 ]

1 голос
/ 10 июня 2011

Я не знаю, действительно ли это хорошая идея или нет, но вы могли бы включить

@org.hibernate.annotations.Where

аннотации на сопоставлении вашей ассоциации и используйте столбец дискриминатора в вашей тестовой таблице, чтобы вы могли отличить Pre от теста Post после загрузки экземпляров Test.

0 голосов
/ 11 июня 2011

Одним из вариантов является Таблица для иерархии классов метод отображения наследования, который, похоже, вы начали делать, но не прошли весь путь.

Другой вариант, как уже упоминалось, использует аннотацию @ Где .

Третий вариант, который я часто использую для аналогичных случаев, состоит в том, чтобы отобразить одну коллекцию для всех тестов, связанных с курсом, а затем добавить вспомогательные методы, чтобы возвращать только нужные подмножества, когда вы хотите работать с предили пост тесты.Пример кода:

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