Hibernate, PostgreSQL: как искать в столбце массива - PullRequest
0 голосов
/ 14 февраля 2019

Я использую таблицу PostgreSQL agents.В нем есть столбец zip_codes character(5)[], в котором хранятся почтовые индексы областей, за которые отвечают агенты.

В нем хранится agent1 с почтовыми индексами {11111,22222} и agent2 с почтовым индексом {33333}.

Я хочу найти всех агентов, которые отвечают за особую область,

Без Hibernate это просто: SELECT * FROM agents WHERE '11111' = ANY (zip_codes) возвращает agent1.

Но как мне сделать это с HQL?Он не знает any.Но если я использую in вместо этого, я получу неправильные результаты: если я напишу select agents from Agents as agents where '{11111}' in (agents.zip_codes), agent1 не будет найдено.Если вместо этого я использую '{33333}', будет найдено agent2.

Конечно, я могу искать что-то вроде (в sql) WHERE zip_codes[1] = '11111' OR zip_codes[2] = '11111' (массивы в PostgreSQL начинаются с индекса 1), но это не такудобно для многих записей в zip_codes.

Ответы [ 2 ]

0 голосов
/ 29 мая 2019

вы можете зарегистрировать dailect вот так

public class MyPostgresSQLDialect extends PostgreSQLDialect {
  public MyPostgresSQLDialect() {
    super();

    this.registerFunction( "array_any", new SQLFunctionTemplate(StandardBasicTypes.INTEGER,"ANY(?1)") );
    this.registerFunction( "array_array", new SQLFunctionTemplate(StandardBasicTypes.INTEGER,"array[?1]") );

  }
}

теперь вы можете использовать в hql

String hql = " from tablename" +
            " where year = :year and month = :month and :version = array_any(versions)";

запомнить регистрацию dailect в sessionFactory

<prop key="hibernate.dialect">com.test.MyPostgresSQLDialect</prop>
0 голосов
/ 14 февраля 2019

Временное решение с Hibernate Interceptor

Это не очень хорошее решение:

Напишите hql-запрос select agents from Agents as agents where '11111' in (agents.zip_codes) и используйте Hibernate Interceptor

public class CustomInterceptor extends EmptyInterceptor {

  @Override
  public String onPrepareStatement(String sql) {
    return sql.replaceAll("\\s+in\\s*\\(", " = any (");
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...