I am currently working on a report which needs a group_concat for one of the fields.
CriteriaQuery<GameDetailsDto> criteriaQuery = criteriaBuilder
                .createQuery(GameDetailsDto.class);
Root<BetDetails> betDetails = criteriaQuery.from(BetDetails.class);
Expression<String> betSelection = betDetails.get("winningOutcome");
criteriaQuery.multiselect(
    // other fields to select
    criteriaBuilder.function("group_concat", String.class, betSelection),
    // other fields to select
    );
//predicate, where clause and other filters
TypedQuery<GameDetailsDto> typedQuery = entityManager.createQuery(criteriaQuery);
this throws a null pointer exception on the line: 
TypedQuery<GameDetailsDto> typedQuery = entityManager.createQuery(criteriaQuery);
did i incorrectly use the function method of the criteriaBuilder?
the documentations says:
function(String name, Class<T> type, Expression<?>... args);
I figured out how to do this with Hibernate-jpa-mysql:
1.) created a GroupConcatFunction class extending org.hibernate.dialect.function.SQLFunction (this is for single column group_concat for now)
public class GroupConcatFunction implements SQLFunction {
@Override
public boolean hasArguments() {
    return true;
}
@Override
public boolean hasParenthesesIfNoArguments() {
    return true;
}
@Override
public Type getReturnType(Type firstArgumentType, Mapping mapping)
        throws QueryException {
    return StandardBasicTypes.STRING;
}
@Override
public String render(Type firstArgumentType, List arguments,
        SessionFactoryImplementor factory) throws QueryException {
    if (arguments.size() != 1) {
        throw new QueryException(new IllegalArgumentException(
                "group_concat shoudl have one arg"));
    }
    return "group_concat(" + arguments.get(0) + ")";
}
}
2.) i created the CustomMySql5Dialect class extending org.hibernate.dialect.MySQL5Dialect and registered the group_concat class created in step 1
3.) On the app context, i updated the jpaVendorAdapter to use the CustomMySql5Dialect as the databasePlatform
4.) Finally to use it
criteriaBuilder.function("group_concat", String.class,
        sampleRoot.get("sampleColumnName"))
Simple solution: instead of creating the whole class, just use SQLFunctionTemplate.
new SQLFunctionTemplate(StandardBasicTypes.STRING, "group_concat(?1)")
and then register this function in your own SQL dialect (eg. in constructor)
public class MyOwnSQLDialect extends MySQL5Dialect {
  public MyOwnSQLDialect() {
    super();
    this.registerFunction("group_concat", new SQLFunctionTemplate(StandardBasicTypes.STRING, "group_concat(?1)"));
  }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With