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

I devised a project with the usage of Spring boot and Cassandra which runs on Docker Container.

After I implemented the configuration of Cassandra, I ran the project and it threw an error shown below.

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

How can I fix the issue?

Here is my application.properties file.

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

Here is a configuration file of 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};
    }

}

Upvotes: 3

Views: 4221

Answers (3)

Bogdan Calmac
Bogdan Calmac

Reputation: 8283

With spring-boot there's no need to extend AbstractCassandraConfiguration, it can auto-configure Cassandra for you. You can just remove your configuration class and everything will work just fine. However, even in this case you need to do some work to automatically create the keyspace. I've settled on an auto-configuration added to our company's spring-boot starter, but you can also define it as a regular configuration in your application.

/**
 * 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()));
        }
    }
}

In my case I've also added a configuration property to control the creation, spring.data.cassandra.create-keyspace, you may leave it out if you don't need the flexibility.

Note that spring-boot auto-configuration depends on certain configuration properties, here's what I have in my dev environment:

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

More details: spring-boot and Cassandra

Upvotes: 0

fsk
fsk

Reputation: 398

If you can delete - character, I think you can run code without errors.

Replace this line:

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

with this one:

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

Upvotes: 0

Mike
Mike

Reputation: 531

By default Spring Data will not create or alter the schema for you. This is a good thing for most use cases as normally you do not want your schema to be created based on a java class. Altering would be even worse in general and also difficult for Cassandra in particular.

If you want for spring to create it you need:

spring.data.cassandra.schema-action=CREATE_IF_NOT_EXISTS

I would still recommend not using this in production.

When talking about keyspaces however, from my knowledge and from the wording of the documentation spring will not create the keyspace even if you use the code above. This makes a lot of sense for Cassandra as a keyspace needs info such as replication strategy and replication factor, the latter being changed for things such as new Data centers being added or removed. This things are administrative tasks that should not be left up to Spring.

Upvotes: 2

Related Questions