Как получить количество разделов секционной таблицы через Hibernate?
Нужно получить количество имеющихся на текущий момент разделов секционной таблицы PostgreSQL 17, чтобы автоматизировать создание нового раздела при заполнении предыдущего. На SQL запрос выглядит так:
SELECT count(*) AS partitionsb FROM pg_catalog.pg_inherits WHERE inhparent = 'gpan.entrys'::regclass;
И этот запрос возвращает количество существующих на текущий момент секций, пусть их будет 14. 14я секция со временем заполняется и так как переделывать структуру с теми записями, что уже в них есть - запарно, то проще создать ещё одну секцию, и её заполнять. Лучше будет, если бы это всё автоматизировать из кода. Мои догадки, что запрос должен начинаться как-то так:
Long partCount = session.createQuery("SELECT COUNT(*) FROM GpanEntryMapper ...", Long.class).uniqueResult();
//Тут должно в итоге вернуться число разделов
А как писать дальше?
Ответы (1 шт):
Как оказалось, работа со служебными таблицами postgres через hibernate то ещё болото, поэтому оказалось проще оформить нативный SQL запрос и кастануть результат через long(лучше обернуть в try-catch, мало ли что прилетит в ответ).
Используя этот пример, держите в голове что для PostgreSQL 17 в качестве ответа на запрос приведённый в теле вопроса, ожидается одна строка формата long
import jakarta.persistence.*;
import org.apache.logging.log4j.*;
import org.hibernate.*;
//...
//Версия Hibernate 6.6.14.Final
final Logger logger = LogManager.getLogger();
Session session = sessionFactory.openSession();
EntityManager em = session.getEntityManagerFactory().createEntityManager();
Transaction transaction = session.beginTransaction();
long count = -1;
try
{
//Отправляем запрос в СУБД
Query query = em.createNativeQuery("SELECT count(*) AS partitionsb FROM pg_catalog.pg_inherits WHERE inhparent = 'gpan.entrys'::regclass;");
Object result = query.getSingleResult(); //Ожидается одна строка, пустой ответ означает что что-то пошло не так
count = (long)result;
}
catch(Exception e)
{
logger.warn(e.gerLocalizedMessage());
if(transaction.isActive())
{
//Закрываем транзакцию только если она активна на текущий момент
transaction.rollback();
}
}
finally
{
logger.info("Количество секций = {}", count);
}
transaction.commit();
session.flush();