Reputation: 2701
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
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
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
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