Reputation: 501
I'm completly new to cassandra, so my error might be obvious.
I'm trying to create an application with spring boot (version 2.3.0.M2) that contacts a cassandra (version 3.11.6) installed in localhost.
I've got an java.lang.IllegalStateException with the message: Since you provided explicit contact points, the local DC must be explicitly set (see basic.load-balancing-policy.local-datacenter in the config, or set it programmatically with SessionBuilder.withLocalDatacenter). Current contact points are: Node(endPoint=localhost:9042, hostId=16a785a4-eaf3-4a4d-a216-5244d75206aa, hashCode=7b0b99d7)=datacenter1. Current DCs in this cluster are: datacenter1
My pom is the following one:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.M2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.test</groupId>
<artifactId>cassandra</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>cassandra</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-cassandra</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</pluginRepository>
</pluginRepositories>
</project>
In the application code, I've got a the following configuration class:
public class CassandraConfig extends AbstractCassandraConfiguration {
public static final String KEYSPACE = "test_keyspace";
@Override
public SchemaAction getSchemaAction() {
return SchemaAction.CREATE_IF_NOT_EXISTS;
}
@Override
protected List<CreateKeyspaceSpecification> getKeyspaceCreations() {
CreateKeyspaceSpecification specification = CreateKeyspaceSpecification.createKeyspace(KEYSPACE);
return Arrays.asList(specification);
}
@Override
protected List<DropKeyspaceSpecification> getKeyspaceDrops() {
return Arrays.asList(DropKeyspaceSpecification.dropKeyspace(KEYSPACE));
}
@Override
protected String getKeyspaceName() {
return KEYSPACE;
}
@Override
public String[] getEntityBasePackages() {
return new String[]{"com.test.cassandra.entity"};
}
}
My properties file contains the following configuration:
spring.data.cassandara.keyspace-name=test_keyspace
spring.data.cassandra.contact-points=localhost
spring.data.cassanda.port=9042
spring.data.cassandra.schema-act=create_if_not_exists
I also have tried with
spring.data.cassandra.contact-points=dc1
When I execute the application, I got see from the logs that I'm using the following version DataStax Java driver for Apache Cassandra(R) (com.datastax.oss:java-driver-core) version 4.4.0
In the cassandra-rackdc.properties I've set the name to
dc=dc1
I've done several test adding configuration parameters, even adding an application.conf to the classpath as described datastax documentation, but didn't have any success. Any clue where should I do it?
Upvotes: 14
Views: 17705
Reputation: 109
Since Spring Boot 3.0 Cassandra properties' prefix is spring.cassandra.*
, not spring.data.cassandra.*
(specifically since 3.0.0-M5, as can be seen from @ConfigurationProperties.prefix
value here and here),
so you need to write
spring.cassandra.local-datacenter=datacenter1
in your application.properties
file to set local datacenter
Upvotes: 10
Reputation: 2678
I solved this problem by setting local datacenter like this :
application properties file : cassandra.local.datacenter=datacenter1
@Value("${cassandra.local.datacenter}")
private String localDatacenter;
@Bean
@Override
public CqlSessionFactoryBean cassandraSession() {
CqlSessionFactoryBean cqlSessionFactoryBean = new CqlSessionFactoryBean();
cqlSessionFactoryBean.setUsername(username);
cqlSessionFactoryBean.setPassword(password);
cqlSessionFactoryBean.setKeyspaceName(keySpace);
cqlSessionFactoryBean.setLocalDatacenter(localDatacenter);
cqlSessionFactoryBean.setPort(port);
cqlSessionFactoryBean.setContactPoints(contactPoint);
return cqlSessionFactoryBean;
}
Note : This is not all of the configuration code. I just wanted to show local datacenter configuration by this code snippet.
Upvotes: 0
Reputation: 2296
There's actually a different config needed for Apache Cassandra to truly work with the new spring versions. It took me about 50 hours of searching before finding this out on this documentation - https://docs.spring.io/spring-data/cassandra/docs/current/reference/html/#cassandra.cassandra-java-config
You'll need to create a new config file as specified there. To do this, follow thus:
Create a new package named config
Create a .java class file in the package named - CassandraConfig
Copy and paste the below code into it.
@Configuration public class CassandraConfig { public @Bean CqlSession session() { return CqlSession.builder().withKeyspace("mykeyspacename").build(); } }
Note, change the Keyspace name to your Keyspace name defined in your property file. If you have not created a Keyspace, start Cassandra server on your system, login to the cqlsh
on the terminal
or cmd
by issuing cqlsh
, and issue this command -
CREATE KEYSPACE IF NOT EXISTS mykeyspacename WITH REPLICATION = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 } AND DURABLE_WRITES = true ;
By now, when you start the spring boot app, it should run without any error.
Upvotes: 2
Reputation: 690
Run nodetool status
in the Cassandra shell. It gives you the datacenter name.
> root@d21e7b0dfc44:/# nodetool status
Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns (effective) Host ID Rack
UN 172.17.0.2 143.37 KiB 16 ? a3584baf-0665-474b-84e9-ba30528a7781 rack1
root@d21e7b0dfc44:/#
In my case, it is "datacenter1". This goes inside the properties file like so:
spring.data.cassandra.local-datacenter=datacenter1
Upvotes: 6
Reputation: 832
Its mentioned in your error logs "Current DCs in this cluster are: datacenter1"
Just add spring.data.cassandra.local-datacenter=datacenter1 in application.properties
Upvotes: 0
Reputation: 223
Simply add
spring.data.cassandra.local-datacenter=DC1
to your application.properties file, where DC1 your local datacenter name (default DC1).
Upvotes: 18
Reputation: 4936
Since Spring Boot 2.3.0.X you need to explicitly provide the name of the local datacenter (because of the added Cassandra driver 4.X support which requires local datacenter to be set explicitly). You can do this by overrirding the getLocalDataCenter
method in AbstractSessionConfiguration
. AbstractCassandraConfiguration
extends this class so you just need to add in your CassandraConfig
class:
@Override
protected String getLocalDataCenter() {
return "dc1";
}
Upvotes: 9