Querydsl: GROUP_CONCAT QueryDSL рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 12 рдирд╡ре░ 2018  ┬╖  6рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: querydsl/querydsl

рдирдорд╕реНрддреЗ,

рдореИрдВ рдпрд╣ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрдШрд░реНрд╖ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ QueryDSL рдореЗрдВ 'GROUP_CONCAT' рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдПред

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 рдФрд░ рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ 2.0 рдФрд░ MySQL 5.7ред

рдореИрдВ рдирд╡реАрдирддрдо рд╕рдВрджрд░реНрдн рдбреЙрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрдврд╝рддрд╛ рд╣реВрдВ рдлрд┐рд░ рднреА рдЗрд╕рдХрд╛ рдЙрддреНрддрд░ рдирд╣реАрдВ рдорд┐рд▓ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдЗрд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП?

рдХреГрдкрдпрд╛ рдорджрдж рдХреАрдЬрд┐рдПред
рдЕрдЧреНрд░рд┐рдо рдореЗрдВ рдзрдиреНрдпрд╡рд╛рджред
@ рд╢реНрд░реЗрдбрд░ резреирез

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

@beamofsoul

рдпрджрд┐ рдЖрдк рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдбреЗрдЯрд╛ jpa рдФрд░ querydsl-jpa , рддреЛ рдЖрдк рдЗрди рдЪрд░рдгреЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

  1. рдПрдХ рдХрд╕реНрдЯрдо DB рдмреЛрд▓реА рдмрдирд╛рдПрдБ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд░реЗрдВ
//  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. 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. рдХреНрд╡реЗрд░реА-рдбреАрдПрд╕рдПрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ
// 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 рдХрд╛ рдорд┐рд╢реНрд░рдг рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред

рд╣рд╛рдБ, рджреЛрд╕реНрдд, рддреБрдо рд╕рд╣реА рд╣реЛред рдореБрдЭреЗ рдЗрд╕реЗ рдареАрдХ рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рд╕реБрд░рд╛рдЧ рдирд╣реАрдВ рд╣реИ, рдмрд╕ рдХреБрдЫ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
рдЕрдЧрд░ рдореИрдВ JPAExpressions рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдореБрдЭреЗ GROUP_CONCAT рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддреЛ рдореИрдВ рдЗрд╕рд╕реЗ рдХреИрд╕реЗ рдирд┐рдкрдЯ рд╕рдХрддрд╛ рд╣реВрдВ?

@beamofsoul

рдпрджрд┐ рдЖрдк рд╕реНрдкреНрд░рд┐рдВрдЧ рдмреВрдЯ рдбреЗрдЯрд╛ jpa рдФрд░ querydsl-jpa , рддреЛ рдЖрдк рдЗрди рдЪрд░рдгреЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

  1. рдПрдХ рдХрд╕реНрдЯрдо DB рдмреЛрд▓реА рдмрдирд╛рдПрдБ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд░реЗрдВ
//  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. 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. рдХреНрд╡реЗрд░реА-рдбреАрдПрд╕рдПрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ
// 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 рдХрд╛ рдбреБрдкреНрд▓реАрдХреЗрдЯред

@ рдЬрд┐рд░рд╛рдлрд╝-рдкреЗрдбрд╝ рдирдорд╕реНрдХрд╛рд░, рдореИрдВ "GROUP_CONCAT ({0} ORDER BY {1})" рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдлрд╝рдВрдХреНрд╢рди рдХреИрд╕реЗ рдкрдВрдЬреАрдХреГрдд рдХрд░реЗрдВ? рдХреГрдкрдпрд╛ред

JPA рдореЗрдВ рдпрд╣ рдЕрд╕рдорд░реНрдерд┐рдд рд╣реИред рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдУрдЖрд░рдПрдо рд╡рд┐рдХреНрд░реЗрддрд╛ рд╕реЗ рдЗрд╕реЗ рдкрд╣рд▓реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рдирд╛ рд╣реЛрдЧрд╛ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рд╣рд╛рдЗрдмрд░рдиреЗрдЯ)ред

рдЕрдВрддрд░ рдХреЛ рднрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдк blaze-persistence-querydsl рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: https://persistence.blazebit.com/documentation/1.5/core/manual/en_US/index.html#querydsl -intementation

рдЬрд┐рд╕рдХреА рдирд┐рдореНрди рд╡рд┐рдзрд┐рдпрд╛рдБ рд╣реИрдВ:

  • 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 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

robertandrewbain picture robertandrewbain  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

okihouse picture okihouse  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

heesuk-ahn picture heesuk-ahn  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

rafaelszp picture rafaelszp  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

michaelhum picture michaelhum  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ