由以下原因引起:com.datastax.oss.driver.api.core.InvalidKeyspaceException:Spring Boot Cassandra 中的密钥空间 mykeyspace 无效

Caused by: com.datastax.oss.driver.api.core.InvalidKeyspaceException: Invalid keyspace mykeyspace in Spring Boot Cassandra

我设计了一个使用 Spring boot 和 Cassandra 的项目,它在 Docker Container 上运行。

在我实施 Cassandra 的配置后,我 运行 项目并抛出了如下所示的错误。

Caused by: com.datastax.oss.driver.api.core.InvalidKeyspaceException: Invalid keyspace mykeyspace

我该如何解决这个问题?

这是我的 application.properties 文件。

spring.cassandra.contactpoints=127.0.0.1
spring.cassandra.port=9042
spring.data.cassandra.keyspace-name=mykeyspace
spring.cassandra.basepackages=com.springboot.cassandra

这是Cassandra的配置文件

@Configuration
@EnableCassandraRepositories
public class CassandraConfiguration extends AbstractCassandraConfiguration {

    @Value("${spring.cassandra.contactpoints}")
    private String contactPoint;

    @Value("${spring.cassandra.port}")
    private int port;

    @Value("${spring.data.cassandra.keyspace-name}")
    private String keyspaceName;

    @Value("${spring.cassandra.basepackages}")
    private String basePackages;

    @Override
    protected String getKeyspaceName() {
        return keyspaceName;
    }

    @Override
    protected int getPort() {
        return port;
    }

    @Override
    protected String getContactPoints() {
        return contactPoint;
    }

    @Override
    public SchemaAction getSchemaAction() {
        return SchemaAction.CREATE_IF_NOT_EXISTS;
    }

    @Override
    public String[] getEntityBasePackages() {
        return new String[] {basePackages};
    }

}

默认情况下Spring数据将不会为您创建或更改架构。对于大多数用例来说,这是一件好事,因为通常您不希望基于 java class 创建架构。一般来说,改变会更糟,尤其是对 Cassandra 来说也很困难。

如果要 spring 创建它,您需要:

spring.data.cassandra.schema-action=CREATE_IF_NOT_EXISTS

我仍然建议不要在生产中使用它。

然而,在谈论键空间时,据我所知documentationspring的措辞不会创建键空间即使 你使用上面的代码。这对 Cassandra 来说很有意义,因为键空间需要复制策略和复制因子等信息,后者会因添加或删除新数据中心等内容而发生变化。这些都是管理任务,不应留给 Spring。

如果你可以删除 - 个字符,我想你可以 运行 编码而不会出错。

替换此行:

@Value("${spring.data.cassandra.keyspace-name}")

这个:

@Value("${spring.data.cassandra.keyspacename}")

使用 spring-boot 无需扩展 AbstractCassandraConfiguration,它可以为您自动配置 Cassandra。您可以删除配置 class,一切都会正常进行。然而,即使在这种情况下,您也需要做一些工作来自动创建键空间。我已经决定将自动配置添加到我们公司的 spring-boot starter,但您也可以将其定义为应用程序中的常规配置。

/**
 * create the configured keyspace before the first cqlSession is instantiated. This is guaranteed by running this
 * autoconfiguration before the spring-boot one.
 */
@ConditionalOnClass(CqlSession.class)
@ConditionalOnProperty(name = "spring.data.cassandra.create-keyspace", havingValue = "true")
@AutoConfigureBefore(CassandraAutoConfiguration.class)
public class CassandraCreateKeyspaceAutoConfiguration {

    private static final Logger logger = LoggerFactory.getLogger(CassandraCreateKeyspaceAutoConfiguration.class);

    public CassandraCreateKeyspaceAutoConfiguration(CqlSessionBuilder cqlSessionBuilder, CassandraProperties properties) {
        // It's OK to mutate cqlSessionBuilder because it has prototype scope.
        try (CqlSession session = cqlSessionBuilder.withKeyspace((CqlIdentifier) null).build()) {
            logger.info("Creating keyspace {} ...", properties.getKeyspaceName());
            session.execute(CreateKeyspaceCqlGenerator.toCql(
                    CreateKeyspaceSpecification.createKeyspace(properties.getKeyspaceName()).ifNotExists()));
        }
    }
}

在我的例子中,我还添加了一个配置 属性 来控制创建,spring.data.cassandra.create-keyspace,如果您不需要灵活性,可以将其省略。

请注意,spring-boot 自动配置取决于某些配置属性,这是我在开发环境中拥有的:

spring:
  data:
    cassandra:
      keyspace-name: mykeyspace
      contact-points: 127.0.0.1
      port: 9042
      local-datacenter: datacenter1
      schema-action: CREATE_IF_NOT_EXISTS
      create-keyspace: true

更多详情:spring-boot and Cassandra