如何在 JUnit 测试期间消除 'Hibernate audit tables are missing' WARN 消息

How to eliminate 'Hibernate audit tables are missing' WARN message during JUnit tests

我正在使用 Hibernate + Envers 编写 JUnit 测试。我的测试工作正常,但我的日志充满了以下和类似的恼人警告消息:

user lacks privilege or object not found: PUBLIC.USER_AUD

我试图找到在测试期间关闭 Envers 的方法,但我找不到任何东西。

这是日志中完整的 WARN 消息之一:

INFO - HHH000412: Hibernate Core {5.2.10.Final}
INFO - HHH000206: hibernate.properties not found
INFO - HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
INFO - HHH000400: Using dialect: org.hibernate.dialect.HSQLDialect
INFO - Envers integration enabled? : true
WARN - GenerationTarget encountered exception accepting command : Error executing DDL via JDBC Statement
org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL via JDBC Statement
        at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67)
        at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlString(SchemaDropperImpl.java:375)
        at org.hibernate.tool.schema.internal.SchemaDropperImpl.applySqlStrings(SchemaDropperImpl.java:359)
        at org.hibernate.tool.schema.internal.SchemaDropperImpl.applyConstraintDropping(SchemaDropperImpl.java:331)
        at org.hibernate.tool.schema.internal.SchemaDropperImpl.dropFromMetadata(SchemaDropperImpl.java:230)
        at org.hibernate.tool.schema.internal.SchemaDropperImpl.performDrop(SchemaDropperImpl.java:154)
        at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:126)
        at org.hibernate.tool.schema.internal.SchemaDropperImpl.doDrop(SchemaDropperImpl.java:112)
        at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:144)
        at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:72)
        at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:309)
        at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:452)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:889)
        at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:151)
        at org.apache.openejb.assembler.classic.EntityManagerFactoryCallable.call(EntityManagerFactoryCallable.java:109)
        at org.apache.openejb.assembler.classic.ReloadableEntityManagerFactory.createDelegate(ReloadableEntityManagerFactory.java:134)
        at org.apache.openejb.assembler.classic.ReloadableEntityManagerFactory.delegate(ReloadableEntityManagerFactory.java:123)
        at org.apache.openejb.assembler.classic.ReloadableEntityManagerFactory.createEntityManager(ReloadableEntityManagerFactory.java:208)
        at org.apache.openejb.persistence.JtaEntityManagerRegistry.getEntityManager(JtaEntityManagerRegistry.java:125)
        at org.apache.openejb.persistence.JtaEntityManager.getEntityManager(JtaEntityManager.java:145)
        at org.apache.openejb.persistence.JtaEntityManager.persist(JtaEntityManager.java:193)
        at com.a.b.dao.BaseDAO.persist(BaseDAO.java:23)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:205)
        at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:186)
        at org.apache.openejb.monitoring.StatsInterceptor.record(StatsInterceptor.java:181)
        at org.apache.openejb.monitoring.StatsInterceptor.invoke(StatsInterceptor.java:100)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:205)
        at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:186)
        at org.apache.openejb.core.interceptor.InterceptorStack.invoke(InterceptorStack.java:85)
        at org.apache.openejb.core.stateless.StatelessContainer._invoke(StatelessContainer.java:252)
        at org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:212)
        at org.apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod(EjbObjectProxyHandler.java:265)
        at org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:260)
        at org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:89)
        at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:347)
        at xxxxxxxxxxx.xxxxxDAO$$LocalBeanProxy.persist(com/xxx/xxxxxxxxxxDAO.java)
        at xxxxxxxxxxx.xxxxxDAOTest.testFindByxxxxxxxx(xxxxxDAOTest.java:41)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85)
        at org.testng.internal.Invoker.invokeMethod(Invoker.java:639)
        at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:816)
        at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1124)
        at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
        at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108)
        at org.testng.TestRunner.privateRun(TestRunner.java:774)
        at org.testng.TestRunner.run(TestRunner.java:624)
        at org.testng.SuiteRunner.runTest(SuiteRunner.java:359)
        at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:354)
        at org.testng.SuiteRunner.privateRun(SuiteRunner.java:312)
        at org.testng.SuiteRunner.run(SuiteRunner.java:261)
        at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
        at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
        at org.testng.TestNG.runSuitesSequentially(TestNG.java:1191)
        at org.testng.TestNG.runSuitesLocally(TestNG.java:1116)
        at org.testng.TestNG.run(TestNG.java:1024)
        at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:77)
        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:159)
        at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:99)
        at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:106)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
        at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
        at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: PUBLIC.USER_AUD
        at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
        at org.hsqldb.jdbc.JDBCUtil.sqlException(Unknown Source)
        at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
        at org.hsqldb.jdbc.JDBCStatement.execute(Unknown Source)
        at org.apache.commons.dbcp2.DelegatingStatement.execute(DelegatingStatement.java:291)
        at org.apache.commons.dbcp2.DelegatingStatement.execute(DelegatingStatement.java:291)
        at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:54)
        ... 78 more
Caused by: org.hsqldb.HsqlException: user lacks privilege or object not found: PUBLIC.USER_AUD
        at org.hsqldb.error.Error.error(Unknown Source)
        at org.hsqldb.error.Error.error(Unknown Source)
        at org.hsqldb.SchemaManager.getUserTable(Unknown Source)
        at org.hsqldb.ParserDDL.compileAlterTable(Unknown Source)
        at org.hsqldb.ParserDDL.compileAlter(Unknown Source)
        at org.hsqldb.ParserCommand.compilePart(Unknown Source)
        at org.hsqldb.ParserCommand.compileStatements(Unknown Source)
        at org.hsqldb.Session.executeDirectStatement(Unknown Source)
        at org.hsqldb.Session.execute(Unknown Source)
        ... 83 more

如何摆脱这些 WARN 消息?

这是 HSQL 的一个已知问题。

问题的存在取决于提供给 hibernate.hbm2ddl.auto 设置的值。基本上,一些值会导致模式管理工具在数据库上执行一系列 ALTERDROP 语句,以保证没有先前的工件测试运行。

根本问题是 HSQL 不支持使用 IF EXISTS[ 执行 DROP CONSTRAINTALTER 语句的概念=31=] 子句;所以你最终会收到这个警告。

警告是无害的,但我知道它可能令人沮丧。

您可能想要考虑支持 HSQL 的开发人员提供此行为,或者考虑其他内存数据库替代方案,例如 H2 用于支持此类语法的单元测试。