Составные DTO-проекции с использованием Constructor Expression и JPQL - PullRequest
0 голосов
/ 06 ноября 2018

Я пытаюсь выбрать конкретные столбцы из db в составном классе DTO, давая полностью квалифицированные имена.

 @Data
    public class Temp {
    String dName;
    Temp2 value;

    public Temp( String dName, Temp2 value) {
        this.dName = dName;
        this.value = value;
    }
    @Data
    public static class Temp2 {
        Integer day;
        public Temp2(Integer day) {
            this.day = day;
        }
    }
 }

Запрос: ВЫБЕРИТЕ новый com.pojo.Temp (t1.displayName, new com.pojo.Temp.Temp2 (t3.day)) FROM table1 t1 ПРИСОЕДИНЯЙТЕСЬ table2 t2 ON t1.bId = t2.id И СЛЕДУЮЩЕЕ СОЕДИНЕНИЕ table3 t3 ON t1.g_id = t2.id

Error: `[2018-11-06 12:02:54] [main] ERROR o.h.hql.internal.ast.ErrorCounter.reportError -  [  ] line 1:64: unexpected token: ,
[2018-11-06 12:02:54] [main] ERROR o.h.hql.internal.ast.ErrorCounter.reportError -  [  ] line 1:64: unexpected token: ,
antlr.NoViableAltException: unexpected token: ,
    at org.hibernate.hql.internal.antlr.HqlBaseParser.primaryExpression(HqlBaseParser.java:1009)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.atom(HqlBaseParser.java:3549)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.unaryExpression(HqlBaseParser.java:3401)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.multiplyExpression(HqlBaseParser.java:3273)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.additiveExpression(HqlBaseParser.java:2930)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.concatenation(HqlBaseParser.java:615)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.relationalExpression(HqlBaseParser.java:2697)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.equalityExpression(HqlBaseParser.java:2558)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.negatedExpression(HqlBaseParser.java:2522)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.logicalAndExpression(HqlBaseParser.java:2438)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.logicalOrExpression(HqlBaseParser.java:2403)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.expression(HqlBaseParser.java:2116)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.aliasedExpression(HqlBaseParser.java:2357)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.selectedPropertiesList(HqlBaseParser.java:1390)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.newExpression(HqlBaseParser.java:1434)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.selectClause(HqlBaseParser.java:1306)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.selectFrom(HqlBaseParser.java:1040)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.queryRule(HqlBaseParser.java:748)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.selectStatement(HqlBaseParser.java:319)
    at org.hibernate.hql.internal.antlr.HqlBaseParser.statement(HqlBaseParser.java:198)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.parse(QueryTranslatorImpl.java:284)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:186)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:141)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153)
    at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:553)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:662)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:103)
    `

Я не могу найти соответствующие ответы для получения данных в составной класс dto с использованием выражения jpql. Поскольку я новичок, я могу что-то упустить.

Любая помощь будет оценена.

1 Ответ

0 голосов
/ 06 ноября 2018

Вложение таких выражений конструктора невозможно AFAIK. Есть один способ сделать это, о котором я знаю, но это грязная и безобразная работа вокруг. Я поместил все параметры в один конструктор, а затем создал экземпляры других объектов класса внутри конструктора.

Пример:

    public CommentDTO(Long id, String body, LocalDateTime datePosted,
                  LocalDateTime lastModifiedDate, Long userId,
                  String login, String avatarUrl, boolean hireable) {
    this.id = id;
    this.body = body;
    this.datePosted = datePosted;
    this.lastModifiedDate = lastModifiedDate;
    this.author = new UserDTO(userId, login, avatarUrl, hireable);

Таким образом, в запросе JPQL должны быть все эти параметры.

Опять же, не рекомендую делать это таким образом, так как это становится на 100% неприемлемым. Но это единственный способ сделать это с помощью выражений конструктора.

Я просто реорганизовал использование проекций на основе интерфейса. Если вы используете Spring Data JPA, просто смешно настроить его для вложенных проекций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...