JPA2 Criteria Builder - Запросы на абстрактные классы и несколько подклассов - PullRequest
4 голосов
/ 07 февраля 2012

Прежде всего, извините, если этот вопрос уже задавался, но я не смог найти ни похожих вопросов, ни ответов на мою проблему.

Моя проблема в том, что у меня есть несколько подклассов на нескольких уровнях иерархии, наследующих от одного подкласса.



    @Entity
    public class A{ }

    @Entity
    public class B extends A { ... }

    @Entity
    public class C extends A{ ... }

    @Entity 
    public class D extends C { 
        private String someAttribute; 
    }

    @Entity 
    public class E extends C { 
        private String anotherAttribute; 
    }

Мне нужно обработать запрос на C и получить все объекты из C,D,E в соответствии с моими критериями, которые получают доступ к атрибутам из D and E.

Я заметил, что невозможно получить доступ, например, someAttribute сюда D, выполнив запрос на C. как это:



    Root root = query.from(C.class);
    Path p = root.get("someAttribute");
    Path p2 = root.get("anotherAttribute");

Обратите внимание, что на данный момент я не могу работать с метамоделями.

В JPAQL я бы написал что-то вроде этого:

`select e1 from C eq where someAttribute = .... or anotherAttribute = ....`

И это правильно разрешило бы мою иерархию.

Чтобы решить эту проблему, я создал собственную аннотацию, эквивалентную @XmlSeeAlso, и назвал ее @PersistenceSeeAlso, которая говорит мне, какие подклассы мне нужно найти, чтобы найти свой атрибут. Поэтому, когда я обрабатываю свою иерархию в соответствии с @PersistenceSeeAlso и получаю свои пути, мне нужно создать новый элемент Root для каждого подкласса, который я ищу для своего атрибута.

Основная проблема здесь в том, что query.form(clazz) создает соединение по запросу, что полностью портит мой запрос, но мне нужен элемент Root в моем типе для разрешения пути.

Итак, мой вопрос; Есть ли способ, чтобы обрабатывать несколько выборок подклассов с JPA2 CriteriaBuilder без создания новых Root экземпляров, может быть, с EntityType?

Или я что-то не так делаю?

Заранее большое спасибо!

С уважением, Q

1 Ответ

1 голос
/ 31 октября 2012

извините за долгое ожидание!

Это отличный вопрос, который я вижу все время.Проблема в том, что вы принимаете информацию о подтипах C, что не совсем верно.

Если вы используете стратегию наследования «таблица на класс» или «объединенная таблица», то данные дляD и E хранятся в отдельных таблицах, и select e1 from C eq where someAttribute = .... or anotherAttribute = .... не будет работать, так как эти столбцы не существуют в C.

. Прежде чем вы сможете отфильтровать, вам нужно СЛЕДУТЬ ПОДКЛЮЧИТЬ столбцы от D и E к C,(Я ответил на похожий вопрос , прежде чем это должно помочь.

...