I am trying to develop a small Springboot application (using JHipster) that listens to a RabbitMQ queue, acknowledges the messages and then runs some operations on a hibernate repository. For now I can consume messages with no problem. But when I try to use the hibernate repository when receiving a message, it appears the TransactionManagers get mixed up and I get the Exception:
Caused by: org.hibernate.TransactionException: Unable to commit against JDBC Connection
at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.commit(AbstractLogicalConnectionImplementor.java:92)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:282)
...
Caused by: org.postgresql.util.PSQLException: Cannot commit when autoCommit is enabled.
at org.postgresql.jdbc.PgConnection.commit(PgConnection.java:872)
My Rabbit configuration is simplistic:
@Configuration
public class RabbitExchangeConfiguration {
@Bean
Queue queue() {
return new Queue("myQueue", false);
}
}
Then there is my TestService, with a RabbitListener (listen) and a method that uses my database transaction manager to access the repository (test)
@Service
public class TestService {
public TestService(
MyRepository myRepository
) {
this.myRepository= myRepository;
}
// My Listener to receive the messages
@RabbitListener(queues = "datafactory")
public void listen(Message in) {
String messageBody = new String(in.getBody());
test(messageBody);
}
// the method that should do stuff with the repository
@Transactional(transactionManager = "myDatabaseTransactionManager")
public void test(String content) {
myRepository.findById(content).orElse(null);
..
}
}
Right now I don't care what the message contains, nor is it important if the entity can be found.
When I comment out the call to test(content)
then the message is received (I can see it in the logs). But when I try to call the function, then I get the Exception.
Is there any way to end the RabbitMQ-transaction before entering the hibernate transaction context? Why is the listener trying to use the hibernate transaction?
solved
Thanks to the answer of p3consulting I found that jpa.properties.hibernate.connection.provider_disables_autocommit=true
was set by default. It was configuered automatically by JHipster for me. I just had to make sure that autocommit was disabled for good:
spring.datasource.hikari.auto-commit=false // disables auto commit
spring.jpa.properties.hibernate.connection.provider_disables_autocommit=false // makes sure it stays that way
So nothing to do with RabbitMQ...
CodePudding user response:
The message is clear: you left autocommit to TRUE then you can't commit explicitly because it's done for you after each DML statement, you could turn it off with "hibernate.connection.autocommit=false" in your properties or calling "connection.setAutoCommit(false);"