Skip to content

IllegalMonitorStateException at AbstractMappingContext #3422

@DongSeung2

Description

@DongSeung2

please, help me to figure out.
This is just a simple code.
i'm using spring boot 3.5.7, junit 5, spring r2dbc(mysql)

package test;

import static org.assertj.core.api.Assertions.assertThat;

import io.r2dbc.spi.ConnectionFactory;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.data.annotation.Id;
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
import org.springframework.data.relational.core.mapping.Table;
import org.springframework.transaction.annotation.Transactional;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;

@Log4j2
@SpringBootTest
public class RollbackTest {
  @Autowired private R2dbcEntityTemplate template;
  @Autowired private TxService txService;

  @BeforeEach
  void setup() {
    template
        .getDatabaseClient()
        .sql(
            "CREATE TABLE IF NOT EXISTS test_item (id SERIAL PRIMARY KEY, name VARCHAR(255), status VARCHAR(50))")
        .fetch()
        .rowsUpdated()
        .block();
    template.getDatabaseClient().sql("TRUNCATE TABLE test_item").fetch().rowsUpdated().block();
  }

  @AfterEach
  public void tearDown() {
    template
        .getDatabaseClient()
        .sql("DROP TABLE IF EXISTS test_item")
        .fetch()
        .rowsUpdated()
        .block();
  }

  @Test
  @DisplayName("rollback test")
  void testRollbackOnIndividualFailure() {
    List<String> items = List.of("Success-1", "FAIL-2", "Success-3", "Success-4");

    Flux<TestItem> processingFlux =
        Flux.fromIterable(items)
            .flatMap(item -> txService.saveInTx(item))
            .onErrorContinue((e, item) -> log.error("ERROR CONTINUED: {} for item\n", item, e));

    StepVerifier.create(processingFlux).expectNextCount(3).verifyComplete();

    long totalCount =
        template
            .getDatabaseClient()
            .sql("SELECT COUNT(*) as count FROM test_item")
            .fetch()
            .one()
            .map(row -> (Long) row.get("count"))
            .block();

    assertThat(totalCount).isEqualTo(3);
  }

  @Table("test_item")
  record TestItem(@Id Long id, String name, String status) {}

  @TestConfiguration(proxyBeanMethods = false)
  static class TestConfig {
    @Bean
    R2dbcEntityTemplate template(ConnectionFactory connectionFactory) {
      return new R2dbcEntityTemplate(connectionFactory);
    }

    @Bean
    TxService txService(R2dbcEntityTemplate template) {
      return new TxService(template);
    }
  }

  @RequiredArgsConstructor
  static class TxService {
    private final R2dbcEntityTemplate template;

    @Transactional
    public Mono<TestItem> saveInTx(String name) {
      TestItem item = new TestItem(null, name, "NEW");

      Mono<TestItem> saveMono = template.insert(TestItem.class).using(item);

      if (name.contains("FAIL")) {
        return saveMono.then(Mono.error(new RuntimeException("Simulated TX Failure")));
      }

      return saveMono;
    }
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: invalidAn issue that we don't feel is valid

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions