Использование JPA Criteria API group_concat - PullRequest
2 голосов
/ 10 августа 2011

В настоящее время я работаю над отчетом, для которого требуется group_concat для одного из полей.

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);

это вызывает исключение нулевого указателя в строке:

TypedQuery<GameDetailsDto> typedQuery = entityManager.createQuery(criteriaQuery);

Неправильно ли я использовал метод функции attributeBuilder?
Документация гласит:

function(String name, Class<T> type, Expression<?>... args);

Ответы [ 2 ]

7 голосов
/ 13 сентября 2011

Я понял, как это сделать с Hibernate-jpa-mysql:

1.) Создал класс GroupConcatFunction, расширяющий org.hibernate.dialect.function.SQLFunction (сейчас это только для одного столбца group_concat)

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.) Я создал класс CustomMySql5Dialect, расширяющий org.hibernate.dialect.MySQL5Dialect, и зарегистрировал класс group_concat, созданный на шаге 1
3.) В контексте приложения я обновил jpaVendorAdapter, чтобы использовать CustomMySql5Dialect в качестве базы данных платформы
4.) Наконец, использовать его

criteriaBuilder.function("group_concat", String.class,
        sampleRoot.get("sampleColumnName"))
1 голос
/ 02 августа 2016

Простое решение: вместо создания всего класса просто используйте SQLFunctionTemplate.

new SQLFunctionTemplate(StandardBasicTypes.STRING, "group_concat(?1)")

и затем зарегистрируйте эту функцию на своем собственном диалекте SQL (например, в конструкторе)

public class MyOwnSQLDialect extends MySQL5Dialect {

  public MyOwnSQLDialect() {
    super();
    this.registerFunction("group_concat", new SQLFunctionTemplate(StandardBasicTypes.STRING, "group_concat(?1)"));
  }
}
...