Postgresql 如何在Spring引导应用程序中清空数据库表?
我目前的尝试(根据)如下所示:Postgresql 如何在Spring引导应用程序中清空数据库表?,postgresql,hibernate,spring-boot,kotlin,vacuum,Postgresql,Hibernate,Spring Boot,Kotlin,Vacuum,我目前的尝试(根据)如下所示: @Service class VacuumDatabaseService( private val entityManager: EntityManager ) { fun vacuumAllTables() { val session = entityManager.unwrap(org.hibernate.Session::class.java) val sessionImpl = session as
@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()
}
正确的方法是什么?您只需插入
数据源,从中获取连接,执行作业,然后关闭连接
@Service
class VacuumDatabaseService(
private val dataSource: DataSource
) {
fun vacuumAllTables() {
dataSource.connection.use {
it.prepareStatement("VACUUM FULL").execute()
}
}
}
注意use
的用法,它会在执行块后关闭连接。为什么要通过EntityManager和Hibernate会话来获得JDBC连接?为什么不简单地注入Jdbc数据源,从中获取连接,完成工作并关闭它?@JBNizet,因为我不知道这是可能的D非常感谢你的评论。以下操作很好:class VacuumDatabaseService(private val dataSource:dataSource){fun vacuumAllTables(){dataSource.connection.prepareStatement(“VACUUM FULL;”)execute()}
是否将此解决方案作为答案发布,以便我可以接受?您确实需要关闭连接:dataSource.connection.use{it.prepareStatement()…}