After upgrading an existing Java project from Spring Boot 2.7 to 3.1, everything is working except JaVers. Whenever JaVers needs to do something - like validate the schema on app startup or commit a new audit record - it throws a SQL exception saying the connection is already closed.
The versions in use are:
- Java 17
- Spring Boot 3.1.4
- JaVers 7.3.3
- Hibernate 6.2.9-Final
- Atomikos 6.0.0
I have stepped through the code in debug mode and everything looks correct, such as:
- JaVers being assigned the correct JTA transaction manager.
- Javers receives a valid
ConnectionProvider, specifically Hibernate JPA. - Javers gets a PostgreSQL connection from the connection pool.
The only thing that I see that is odd is when I look at the properties of the database connection, it says closed=true, and I cannot seem to figure out why.
Update: I have created a brand new project using only Spring Boot, JaVers, and Atomikos, with a simple Controller-Service-Repository pattern and a single entity. I have also not added any custom beans, i.e. everything is default as included in the JaVers and Atomikos starters.
The results are as follows:
- With only JaVers enabled and not Atomikos, auditing works correctly.
- With only Atomikos enabled and not JaVers, transactions work correctly.
- With both JaVers and Atomikos enabled, the application fails to start with the following stack trace:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'JaversFromStarter' defined in class path resource [org/javers/spring/boot/sql/JaversSqlAutoConfiguration.class]: [METADATA_EXTRACTION_ERROR] Failed to obtain metadata from connection.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1770) ~[spring-beans-6.0.12.jar:6.0.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598) ~[spring-beans-6.0.12.jar:6.0.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[spring-beans-6.0.12.jar:6.0.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:325) ~[spring-beans-6.0.12.jar:6.0.12]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.0.12.jar:6.0.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:323) ~[spring-beans-6.0.12.jar:6.0.12]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-6.0.12.jar:6.0.12]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:973) ~[spring-beans-6.0.12.jar:6.0.12]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:942) ~[spring-context-6.0.12.jar:6.0.12]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) ~[spring-context-6.0.12.jar:6.0.12]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.1.4.jar:3.1.4]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) ~[spring-boot-3.1.4.jar:3.1.4]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.1.4.jar:3.1.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-3.1.4.jar:3.1.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309) ~[spring-boot-3.1.4.jar:3.1.4]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298) ~[spring-boot-3.1.4.jar:3.1.4]
at com.example.springjtaatomikos.SpringJtaAtomikosApplication.main(SpringJtaAtomikosApplication.java:12) ~[classes/:na]
Caused by: org.polyjdbc.core.exception.SchemaInspectionException: [METADATA_EXTRACTION_ERROR] Failed to obtain metadata from connection.
at org.polyjdbc.core.schema.SchemaInspectorImpl.extractMetadata(SchemaInspectorImpl.java:69) ~[polyjdbc-0.7.6.jar:na]
at org.polyjdbc.core.schema.SchemaInspectorImpl.<init>(SchemaInspectorImpl.java:60) ~[polyjdbc-0.7.6.jar:na]
at org.polyjdbc.core.schema.SchemaInspectorImpl.<init>(SchemaInspectorImpl.java:52) ~[polyjdbc-0.7.6.jar:na]
at org.polyjdbc.core.schema.SchemaManagerFactory.createInspector(SchemaManagerFactory.java:44) ~[polyjdbc-0.7.6.jar:na]
at org.polyjdbc.core.DefaultPolyJDBC.schemaInspector(DefaultPolyJDBC.java:78) ~[polyjdbc-0.7.6.jar:na]
at org.javers.repository.sql.schema.JaversSchemaManager.ensureSchema(JaversSchemaManager.java:43) ~[javers-persistence-sql-7.3.3.jar:na]
at org.javers.repository.sql.JaversSqlRepository.ensureSchema(JaversSqlRepository.java:186) ~[javers-persistence-sql-7.3.3.jar:na]
at org.javers.spring.jpa.JaversTransactionalJpaDecorator$1.doInTransactionWithoutResult(JaversTransactionalJpaDecorator.java:64) ~[javers-spring-jpa-7.3.3.jar:na]
at org.springframework.transaction.support.TransactionCallbackWithoutResult.doInTransaction(TransactionCallbackWithoutResult.java:36) ~[spring-tx-6.0.12.jar:6.0.12]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-6.0.12.jar:6.0.12]
at org.javers.spring.jpa.JaversTransactionalJpaDecorator.ensureSchema(JaversTransactionalJpaDecorator.java:61) ~[javers-spring-jpa-7.3.3.jar:na]
at org.javers.spring.jpa.JaversTransactionalJpaDecorator.afterPropertiesSet(JaversTransactionalJpaDecorator.java:55) ~[javers-spring-jpa-7.3.3.jar:na]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1817) ~[spring-beans-6.0.12.jar:6.0.12]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1766) ~[spring-beans-6.0.12.jar:6.0.12]
... 16 common frames omitted
Caused by: com.atomikos.jdbc.internal.AtomikosSQLException: Connection was already closed - calling getMetaData is no longer allowed!
at com.atomikos.jdbc.internal.AtomikosSQLException.throwAtomikosSQLException(AtomikosSQLException.java:29) ~[transactions-jdbc-6.0.0-jakarta.jar:na]
at com.atomikos.jdbc.internal.AtomikosSQLException.throwAtomikosSQLException(AtomikosSQLException.java:40) ~[transactions-jdbc-6.0.0-jakarta.jar:na]
at com.atomikos.jdbc.internal.AbstractJdbcConnectionProxy.throwInvocationAfterClose(AbstractJdbcConnectionProxy.java:240) ~[transactions-jdbc-6.0.0-jakarta.jar:na]
at com.atomikos.util.DynamicProxySupport.invoke(DynamicProxySupport.java:114) ~[atomikos-util-6.0.0.jar:na]
at jdk.proxy2/jdk.proxy2.$Proxy72.getMetaData(Unknown Source) ~[na:na]
at org.polyjdbc.core.schema.SchemaInspectorImpl.extractMetadata(SchemaInspectorImpl.java:66) ~[polyjdbc-0.7.6.jar:na]
... 29 common frames omitted
As such, I suspect it is a compatibility issue between the two dependencies - perhaps the underlying org.polyjdbc dependency that JaVers uses, which is very outdated?