如何在Spring Boot应用程序中清理数据库表?

时间:2019-04-07 08:11:19

标签: postgresql hibernate spring-boot kotlin vacuum

我目前的尝试(根据this answer)如下所示:

@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()
    }

正确的方法是什么?

1 个答案:

答案 0 :(得分:4)

您只需要注入DataSource,断开连接,执行您的工作,然后关闭连接。

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

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

请注意use的用法,一旦执行该块,它将关闭连接。