使用 Spring 和 Testcontainers 时序列不可用

问题描述 投票:0回答:1

我正在尝试在测试容器中使用 postgres 进行集成测试,由于缺少序列,它在 JUnit 执行期间抛出错误。

我试过不指定生成器,但由于找不到 hiberate_sequence 而失败。这在生产中有效(命名生成器)所以我很确定这不是一个简单的语法问题。

对可能导致错误的原因有什么建议吗?

更新

我创建了一个没有 Testcontainers 的新测试,它使用现有数据库,表和生成器已经在模式中。该测试是绿色的。用于创建表和生成器的 SQL 是 Spring 生成的 SQL。


环境:Spring Boot v2.7.8、postgres 12、testcontainers 1.17.6、JUnit 5、Java 11

简单的例子

@Builder(toBuilder = true)
@Entity
@Table(name = "motor")
public class MotorImpl implements Motor, Serializable {
    private static final long serialVersionUID = -8719527647178838271L;
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "motor_generator")
    @SequenceGenerator(name = "motor_generator", sequenceName = "motor_id_seq", allocationSize = 1)
    private Long id;
    @Version
    private Integer version;
    private String name;
    
    // getters, setters, constructors generated by lombok   
}

JUnit5测试类

@SpringBootTest
@Testcontainers
class MotorRepositoryTest {

    @Container
    private static final PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:12");

    @DynamicPropertySource
    static void registerPostgresProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.datasource.url", postgres::getJdbcUrl);
        registry.add("spring.datasource.username", postgres::getUsername);
        registry.add("spring.datasource.password", postgres::getPassword);
    }

    @Autowired
    MotorRepository repo;
    
    @Test
    @Transactional
    void givenValidMotor_whenInsert_thenRecordCreated() {
        MotorImpl m = MotorImpl.builder().build();
        MotorImpl m_saved = repo.save(m);
        assertNotNull(m_saved.getId());
        Optional<MotorImpl> m_retrieved = repo.findById(m_saved.getId());
        assertTrue(m_retrieved.isPresent());
    }
}

从 Spring 捕获的自动 DDL

create sequence motor_id_seq start 1 increment 1;

    create table motor (
       id int8 not null,
        name varchar(255),
        status int4,
        version int4,
        primary key (id)
    );

控制台日志

14:31:24.410 [main] INFO  org.springframework.test.context.transaction.TransactionContext - Began transaction (1) for test context [DefaultTestContext@2681185e testClass = MotorRepositoryTest, testInstance = com.vogelware.testcontainer.motor.impl.MotorRepositoryTest@41f5389f, testMethod = givenValidMotor_whenInsert_thenRecordCreated@MotorRepositoryTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@3a012678 testClass = MotorRepositoryTest, locations = '{}', classes = '{class com.vogelware.testcontainer.TestcontainerApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@2c4d1ac, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@41e68d87, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@24ba9639, org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer@4331d187, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@335b5620, org.springframework.test.context.support.DynamicPropertiesContextCustomizer@513b5eb, org.springframework.boot.test.context.SpringBootTestArgs@1, org.springframework.boot.test.context.SpringBootTestWebEnvironment@3c153a1], contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.event.ApplicationEventsTestExecutionListener.recordApplicationEvents' -> false]]; transaction manager [org.springframework.orm.jpa.JpaTransactionManager@69cb134]; rollback [true]
14:31:24.562 [main] DEBUG org.hibernate.SQL - 
    select
        nextval ('motor_id_seq')
14:31:24.573 [main] WARN  org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 0, SQLState: 42P01
14:31:24.573 [main] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - ERROR: relation "motor_id_seq" does not exist
  Position: 17
postgresql spring-data testcontainers
1个回答
0
投票

我认为这是因为你的 spring.datasource.url 没有设置正确。 您必须在 jdbc Url 中指定 currentSchema。

类似的东西:

registry.add("spring.datasource.url",
                () -> String.format("jdbc:postgresql://%s:%d/db064d10?currentSchema=test", databaseContainer.getContainerIpAddress(), databaseContainer.getMappedPort(5432)));
© www.soinside.com 2019 - 2024. All rights reserved.