Как очистить таблицы базы данных в приложении Spring Boot?

Моя текущая попытка (согласно этот ответ) выглядит следующим образом:

@Service
class VacuumDatabaseService(
        private val entityManager: EntityManager
) {
    fun vacuumAllTables() {
        val session = entityManager.unwrap(org.hibernate.Session::class.java)
        val sessionImpl = session as org.hibernate.internal.SessionImpl
        val connection = sessionImpl.connection()
        connection.prepareStatement("VACUUM FULL").execute()
    }
}

Но выдает:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: No transactional EntityManager available

Аннотирование функции с помощью @Transactional приводит к:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.reflect.UndeclaredThrowableException

Caused by: org.postgresql.util.PSQLException: ERROR: VACUUM cannot run inside a transaction block

Следующее работает, но кажется опасно неправильным:

    @Transactional
    fun vacuumAllTables() {
        val session = entityManager.unwrap(org.hibernate.Session::class.java)
        val sessionImpl = session as org.hibernate.internal.SessionImpl
        val connection = sessionImpl.connection()
        connection.prepareStatement("END TRANSACTION; VACUUM FULL;").execute()
    }

Каков правильный путь?

Зачем проходить EntityManager и сеанс Hibernate только для того, чтобы получить соединение JDBC? Почему бы вам просто не внедрить Jdbc DataSource, получить из него соединение, выполнить свою работу и закрыть его?

JB Nizet 07.04.2019 10:20

@JBNizet Потому что я не знал, что это возможно. :D Большое спасибо за замечание. Следующее работает нормально: class VacuumDatabaseService(private val dataSource: DataSource) { fun vacuumAllTables() { dataSource.connection.prepareStatement("VACUUM FULL;").execute() } }

Tobias Hermann 07.04.2019 10:26

Хотите опубликовать это решение в качестве ответа, чтобы я мог его принять?

Tobias Hermann 07.04.2019 10:27

Вам действительно нужно закрыть соединение: dataSource.connection.use { it.prepareStatement()... }

JB Nizet 07.04.2019 10:27
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
4
983
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам просто нужно внедрить DataSource, получить из него соединение, выполнить свою работу и закрыть соединение.

@Service
class VacuumDatabaseService(
        private val dataSource: DataSource
) {

    fun vacuumAllTables() {
        dataSource.connection.use {
            it.prepareStatement("VACUUM FULL").execute()
        }
    }
}

Обратите внимание на использование use, которое закрывает соединение после выполнения блока.

Другие вопросы по теме

Похожие вопросы

Эффективно генерировать все возможные комбинации команд из 4 человек, которые содержат определенных персонажей из 130 символов, и вычислять определенные значения
Можно ли создавать базы данных PostgreSQL с динамическими именами с помощью Golang?
Как я могу изменить существующий столбец как идентификатор в PostgreSQL 11.1
Как сгруппировать столбец по месяцам и СЧИТАТЬ в месяц?
Использование соответствующего оператора SELECT для извлечения данных из нескольких таблиц
Как написать исполняемый файл postgreSQL для расчета среднего и процентного значения с использованием этой схемы?
Доступ к Config Vars в Heroku с ядром dotnet для получения URL-адреса базы данных
Jsonb_array_elements не возвращает строку, если она не найдена
Как создать SQL-скрипт для выбора всех ссылок на идентификаторы, которые являются частью одной веревки цитирования?
Наличие повторяющихся строк в первичном ключе и уникальных ограничений в postgres