在PostgresSQL中运行一系列在ltree中插入ltree的单元测试时,“类型17024的高速缓存查找失败”

问题描述

正在进行飞行路线迁移,并且在运行测试时收到以下错误消息;

org.springframework.jdbc.UncategorizedsqlException: PreparedStatementCallback; uncategorized sqlException for sql [INSERT INTO foo_tag (
    foo_uuid,foo_path
) VALUES (
    ?,?
)]; sql state [XX000]; error code [0]; ERROR: cache lookup Failed for type 17024; nested exception is org.postgresql.util.PsqlException: ERROR: cache lookup Failed for type 17024`

这仅在一起运行测试时发生,而不是孤立运行。例如。同时运行test1test2,将使test2失败,并显示上述消息,但是单独运行它们是可以的。

  @Before
  @FlywayTest // Reset DB state before each test,to ensure they are independent.
  fun setUp() {
    testRepository = TestRepository(jdbcTemplate)
  }

  @Test
  fun `test1`() {
    testRepository.insertFooTag(fooUuid,"foo.bar")
  }

  @Test
  fun `test2`() {
    testRepository.insertFooTag(fooUuid,"bar.baz")
  }

插入test-db的过程如下

    @Transactional
    @Throws(DuplicateKeyException::class)
    open fun insertFooTag(
        fooUuid: UUID,foo_tag: String
    ) {
        val sql = """
            INSERT INTO foo_tag (
                foo_uuid,foo_path
            ) VALUES (
                :foo_uuid,:foo_path
            )
        """.trimIndent()
        
        val ltreePgObject = PGobject()
        ltreePgObject.type = "ltree"
        ltreePgObject.value = foo_tag

        val params = MapsqlParameterSource()
            .addValue("foo_uuid",fooUuid)
            .addValue("foo_path",ltreePgObject)
        jdbcTemplate.update(sql,params)
    }

我不确定是什么原因引起的,但是我认为它与数据库迁移中的ltree数据类型介绍有关;

CREATE EXTENSION IF NOT EXISTS "ltree";

CREATE TABLE foo_tag (
    foo_uuid UUID REFERENCES foo (uuid),foo_path ltree,PRIMARY KEY (foo_uuid,foo_path)
);

解决方法

不太确定为什么这可以解决我的问题,但是将我在application-db-test.properties中使用的完全相同的设置添加到Spring配置文件中(与我正在使用的ActiveProfile("db-test")匹配)在我的测试课程中)使测试运行没有此错误。

@Configuration
class TestDataBaseConfiguration {
  @Bean
  @Profile("db-test")
  fun dataSource(): DataSource {
    val containerPort = "12785"
    val url = "jdbc:postgresql://localhost:$containerPort/postgres"
    val dataSource = DriverManagerDataSource()

    dataSource.setDriverClassName("org.postgresql.Driver")
    dataSource.url = url
    dataSource.username = "foo"
    dataSource.password = "bar"
    dataSource.schema = "public"

    return dataSource
  }
}