Home > Mobile >  RabbitMQ and Hibernate: Unable to commit against JDBC Connection
RabbitMQ and Hibernate: Unable to commit against JDBC Connection

Time:01-06

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);"

  • Related