Querydsl: GROUP_CONCAT НЕ работает в QueryDSL

Созданный на 12 нояб. 2018  ·  6Комментарии  ·  Источник: querydsl/querydsl

Всем привет,

Я изо всех сил пытаюсь понять, как использовать GROUP_CONCAT в QueryDSL.

final QDataSourceSmallEliminate eliminate = QDataSourceSmallEliminate.dataSourceSmallEliminate;
        final QLattitudeVisitor lattitude = LattitudeVisitorServiceImpl.$;
//      Expressions.stringOperation(SQLOps.GROUP_CONCAT, lattitude.tagName)

        return QuerydslUtils.newQuery(entityManager).select(Projections.constructor(EliminateLattitude.class, 
                eliminate.id, 
                JPAExpressions.selectDistinct( SQLExpressions.groupConcat(lattitude.tagName)).from(lattitude).where(lattitude.urlCrc.eq(eliminate.urlCrc))))
            .from(eliminate)
            .fetch();

Исключение:

org.springframework.dao.InvalidDataAccessApiUsageException: No pattern found for GROUP_CONCAT; nested exception is java.lang.IllegalArgumentException: No pattern found for GROUP_CONCAT

...

Caused by: java.lang.IllegalArgumentException: No pattern found for GROUP_CONCAT
    at com.querydsl.core.support.SerializerBase.visitOperation(SerializerBase.java:280)
    at com.querydsl.jpa.JPQLSerializer.visitOperation(JPQLSerializer.java:437)
    at com.querydsl.core.support.SerializerBase.visit(SerializerBase.java:231)
    at com.querydsl.core.support.SerializerBase.visit(SerializerBase.java:31)
    at com.querydsl.core.types.OperationImpl.accept(OperationImpl.java:83)
    at com.querydsl.core.support.SerializerBase.handle(SerializerBase.java:92)
    at com.querydsl.jpa.JPQLSerializer.serialize(JPQLSerializer.java:203)
    at com.querydsl.jpa.JPQLSerializer.visit(JPQLSerializer.java:358)
    at com.querydsl.jpa.JPQLSerializer.visit(JPQLSerializer.java:39)
    at com.querydsl.core.types.SubQueryExpressionImpl.accept(SubQueryExpressionImpl.java:57)
    at com.querydsl.core.support.FetchableSubQueryBase.accept(FetchableSubQueryBase.java:150)
    at com.querydsl.core.support.SerializerBase.handle(SerializerBase.java:92)
    at com.querydsl.core.support.SerializerBase.handle(SerializerBase.java:119)
    at com.querydsl.core.support.SerializerBase.visit(SerializerBase.java:225)
    at com.querydsl.core.support.SerializerBase.visit(SerializerBase.java:31)
    at com.querydsl.core.types.ConstructorExpression.accept(ConstructorExpression.java:112)
    at com.querydsl.core.support.SerializerBase.handle(SerializerBase.java:92)
    at com.querydsl.jpa.JPQLSerializer.serialize(JPQLSerializer.java:203)
    at com.querydsl.jpa.JPAQueryBase.serialize(JPAQueryBase.java:60)
    at com.querydsl.jpa.JPAQueryBase.serialize(JPAQueryBase.java:50)
    at com.querydsl.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:98)
    at com.querydsl.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:94)
    at com.querydsl.jpa.impl.AbstractJPAQuery.fetch(AbstractJPAQuery.java:201)
    at com.moraydata.general.secondary.repository.impl.DataSourceSmallEliminateRepositoryImpl.findObject(DataSourceSmallEliminateRepositoryImpl.java:98)
    at com.moraydata.general.secondary.repository.impl.DataSourceSmallEliminateRepositoryImpl$$FastClassBySpringCGLIB$$b42d875d.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)

QueryDSL 4.2.1 и JDK1.8 и Spring Boot2.0 и MySQL 5.7.

Я прочитал последний справочный документ, но все еще не могу найти ответ, так что мне делать, чтобы он работал?

Пожалуйста помоги.
Заранее спасибо.
@ Shredder121

jpa question

Самый полезный комментарий

@beamofsoul

если вы используете данные весенней загрузки jpa и querydsl-jpa , вы можете выполнить следующие действия

  1. создать собственный диалект БД и зарегистрировать функцию
//  org.hibernate.dialect.MySQL5Dialect
public class CustomMysqlDialect extends MySQL5Dialect {
    public CustomMysqlDialect() {
        super();
        // register custom/inner function here
        this.registerFunction("group_concat", new SQLFunctionTemplate(StandardBasicTypes.STRING, "group_concat(?1)"));
    }
}
  1. config JpaVendorAdapter
<strong i="15">@Configuration</strong>
public class JpaConfiguration {
    <strong i="16">@Bean</strong>
    public JpaVendorAdapter jpaVendorAdapter() {
        AbstractJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        adapter.setShowSql(true);
        adapter.setDatabase(Database.MYSQL);
       // package to CustomMysqlDialect
        adapter.setDatabasePlatform("com.xxx.xxx.config.CustomMysqlDialect");
        adapter.setGenerateDdl(false);
        return adapter;
    }
}
  1. использовать query-dsl
// before do this , autowird JPAQueryFactory at first 
        QReportDoctorTag qReportDoctorTag = QReportDoctorTag.reportDoctorTag;
        SimpleTemplate<String> simpleTemplate = Expressions.simpleTemplate(String.class, "group_concat({0})", qReportDoctorTag.tag);
        JPAQuery<Tuple> tupleJPAQuery = queryFactory.select(qReportDoctorTag.reportId, simpleTemplate)
                .from(qReportDoctorTag)
                .groupBy(qReportDoctorTag.reportId);

        List<Tuple> fetch = tupleJPAQuery.fetch();

Все 6 Комментарий

Вы не всегда можете смешивать выражения JPAExpressions и SQLExpressions.

Вы не всегда можете смешивать выражения JPAExpressions и SQLExpressions.

Да, дружище, ты прав. Понятия не имею, как это исправить, просто попробуйте что-нибудь полезное.
Итак, как я могу с этим справиться, если мне нужно GROUP_CONCAT при использовании JPAExpressions?

@beamofsoul

если вы используете данные весенней загрузки jpa и querydsl-jpa , вы можете выполнить следующие действия

  1. создать собственный диалект БД и зарегистрировать функцию
//  org.hibernate.dialect.MySQL5Dialect
public class CustomMysqlDialect extends MySQL5Dialect {
    public CustomMysqlDialect() {
        super();
        // register custom/inner function here
        this.registerFunction("group_concat", new SQLFunctionTemplate(StandardBasicTypes.STRING, "group_concat(?1)"));
    }
}
  1. config JpaVendorAdapter
<strong i="15">@Configuration</strong>
public class JpaConfiguration {
    <strong i="16">@Bean</strong>
    public JpaVendorAdapter jpaVendorAdapter() {
        AbstractJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        adapter.setShowSql(true);
        adapter.setDatabase(Database.MYSQL);
       // package to CustomMysqlDialect
        adapter.setDatabasePlatform("com.xxx.xxx.config.CustomMysqlDialect");
        adapter.setGenerateDdl(false);
        return adapter;
    }
}
  1. использовать query-dsl
// before do this , autowird JPAQueryFactory at first 
        QReportDoctorTag qReportDoctorTag = QReportDoctorTag.reportDoctorTag;
        SimpleTemplate<String> simpleTemplate = Expressions.simpleTemplate(String.class, "group_concat({0})", qReportDoctorTag.tag);
        JPAQuery<Tuple> tupleJPAQuery = queryFactory.select(qReportDoctorTag.reportId, simpleTemplate)
                .from(qReportDoctorTag)
                .groupBy(qReportDoctorTag.reportId);

        List<Tuple> fetch = tupleJPAQuery.fetch();

Для SQL используйте SQLExpressions.groupConcat . Для JPA это не поддерживается, потому что GROUP_CONCAT не является функцией, определенной для JPQL. Ни один из поставщиков ORM не поставляет ее по умолчанию, хотя в некоторых случаях функцию можно зарегистрировать вручную (см. Пример в комментарии выше).

Дубликат №2020.

@ giraffe-tree Здравствуйте, я хочу использовать "GROUP_CONCAT ({0} ORDER BY {1})". Как зарегистрировать функцию? Пожалуйста.

В JPA это не поддерживается. Вам нужно будет сначала попросить вашего поставщика ORM реализовать его (например, Hibernate).

Вы можете рассмотреть возможность использования расширения blaze-persistence-querydsl чтобы заполнить пробел: https://persistence.blazebit.com/documentation/1.5/core/manual/en_US/index.html#querydsl -integration

У которого есть следующие методы:

  • JPQLNextExpressions.groupConcat(Expression<?> expression, String separator, OrderSpecifier<?>... orderSpecifiers)
  • JPQLNextExpressions.groupConcat(Expression<?> expression, Expression<String> separator, OrderSpecifier<?>... orderSpecifiers)
  • JPQLNextExpressions.groupConcat(boolean distinct, Expression<?> expression, String separator, OrderSpecifier<?>... orderSpecifiers)
  • JPQLNextExpressions.groupConcat(boolean distinct, Expression<?> expression, Expression<String> separator, OrderSpecifier<?>... orderSpecifiers)
Была ли эта страница полезной?
0 / 5 - 0 рейтинги