Search code examples
jdbcjax-rsebean

Why is Ebean ORM throwing java.sql.SQLException: IJ031021: You cannot rollback during a managed transaction


I have a Jax-RS Rest service that uses Ebean to query the database. On any query I make this exception is thrown.

For example.

User currentUser = new QUser().where().id.eq(currentUserID)).findUnique();

Logs

ERROR [io.ebeaninternal.server.transaction.JdbcTransaction] (default task-10) Error when ending a query only transaction via ROLLBACK: java.sql.SQLException: IJ031021: You cannot rollback during a managed transaction

Now the query returns the appropriate user and doesn't interfere with the Jax-RS.

But I can't ignore the large code-smell

And the huge log that is created because it gets thrown on every query.

My Configuration

ServerConfig config = new ServerConfig();
        config.setDataSource(ds);
        config.setName("db");
        config.setAutoCommitMode(false);
        config.setDatabasePlatform(new PostgresPlatform());
        config.setRegister(true);
        config.setDefaultServer(true);
        config.setTransactionRollbackOnChecked(true);
        config.addPackage(User.class.getPackage().getName());
        EbeanServer es = EbeanServerFactory.create(config);

Solution

  • When using ebean inside Java EE you need to configure the EbeanServer before it is used. A typical place to do it is in a @PostConstruct method in a @Startup @Singleton bean-managed transaction ejb. And you need to configure it to use the JTA transaction manager so it doesn't try to begin/commit the transactions on its own.

    @Singleton
    @Startup
    @TransactionManagement(TransactionManagementType.BEAN)
    public class AtStartup {
    
        @Resource(mappedName = "java:jboss/datasources/EbeanTestDS")
        private DataSource ds;
    
        @SneakyThrows
        @PostConstruct
        public void startup() {
            new MigrationRunner(new MigrationConfig()).run(ds); // begin/commits transaction for the migration...
    
            ServerConfig config = new ServerConfig();
            config.setDataSource(ds);
            config.addPackage(Customer.class.getPackage().getName());
            config.setUseJtaTransactionManager(true); // This is important !
            config.setAutoCommitMode(false);
            EbeanServerFactory.create(config);
        }