Приведение выражения результата в критерии api - PullRequest
1 голос
/ 18 января 2020

У меня есть этот код:

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Integer> criteriaQuery = criteriaBuilder.createQuery(Integer.class);

Root<Teacher> c = criteriaQuery.from(Teacher.class);

Expression s = criteriaBuilder.locate(c.<String>get("fam"), "-").as(Integer.class);

Integer lastIndex = Integer.valueOf(s.toString());

criteriaQuery.select(criteriaBuilder.max(criteriaBuilder.substring(c.<String>get("fam"),  1, lastIndex-1).as(Integer.class)));

Integer aaa = em.createQuery(criteriaQuery).getSingleResult();

Переменная s дает мне целое число. Я хотел бы использовать его в качестве параметра функции substring. Как я могу это сделать? Этот метод не работает.

1 Ответ

1 голос
/ 19 января 2020

Вы можете использовать следующее решение:

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Integer> criteria = builder.createQuery(Integer.class);
Root<Teacher> root = criteria.from(Teacher.class);

Expression<Integer> exp = builder.locate(root.get("fam"), "-");
Expression<Integer> one = builder.literal(1);

Expression<String> numberAsString = builder.substring(
   root.get("fam"),
   one,
   builder.diff(exp, one)
);

Expression<Integer> toNumber = builder.function(
  "TO_NUMBER",
  Integer.class,
  numberAsString
);

criteria.select(
   builder.max(toNumber)
);

Integer result = session.createQuery( criteria ).getSingleResult();

В этом фрагменте кода я предположил, что вы используете oracle базу данных. Функция TO_NUMBER - это функция oracle Speci c, которая преобразует первый параметр в значение типа данных NUMBER. Я предполагаю, что подобные функции должны присутствовать во всех базах данных.

Обратите также внимание, что из-за HHH-11938 функция TO_NUMBER должна быть объявлена ​​на вашем спящем диалекте. В моем случае эта функция не была объявлена ​​в org.hibernate.dialect.Oracle12cDialect. Итак, я расширил этот диалект следующим образом:

import org.hibernate.dialect.Oracle12cDialect;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.type.StandardBasicTypes;

public class MyOracleDialect extends Oracle12cDialect
{
   public MyOracleDialect()
   {
      super();
      registerFunction("to_number", new StandardSQLFunction("to_number", StandardBasicTypes.INTEGER) );
   }
}

И затем использовал его в конфигурации hibernate hibernate.cfg.xml

<!DOCTYPE hibernate-configuration SYSTEM "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">com.sternkn.hibernate.MyOracleDialect</property>
        ...
    </session-factory>
</hibernate-configuration>
...