Cassandra Repository is always using keyspace from

2019-08-14 09:49发布

问题:

I have my data are on different keyspaces, i have more than one keyspace in a spring boot application, so i want my cassandra repositories to be configurable with different keyspaces each rather than having one keyspace in application level. In a spring project, i am looking something like a keyspace should be configurable at Repository level.

Cassandra Repository is always using keyspace from application.properties file, Not working if i extend AbstractCassandraConfiguration class and configure keyspace and port. I have created a Entity, CassandraConfig and Repository and tried to query and update Entity using Respository. Refer my code below.

pom.xml

<dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-cassandra</artifactId>
        <version>2.0.7.RELEASE</version>
</dependency>

Entity code:-

import org.springframework.data.cassandra.core.mapping.PrimaryKey;
import org.springframework.data.cassandra.core.mapping.Table;

@Table
public class Company {
    @PrimaryKey
    private String companyid;
    private String companyName;
    private String address;
    public String getCompanyid() {
        return companyid;
    }
    public void setCompanyid(String companyid) {
        this.companyid = companyid;
    }
    public String getCompanyName() {
        return companyName;
    }
    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }

}

Cassandra config code :-

import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.config.AbstractCassandraConfiguration;
import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories;

@Configuration
@EnableCassandraRepositories(basePackageClasses=CompanyRepository.class)
public class CassandraConfig extends AbstractCassandraConfiguration {

    public String getContactPoints() {
        return "127.0.0.1";
      }
    @Override
    protected String getKeyspaceName() {
        return "CompanyDetails";
    }

}

Repository code :-

import java.util.List;

    import org.springframework.data.cassandra.repository.CassandraRepository;
    import org.springframework.data.cassandra.repository.Query;
    import org.springframework.stereotype.Repository;

@Repository

    public interface CompanyRepository extends CassandraRepository<Company, String> {
                    @Query(allowFiltering=true)
                    public Company findByCompanyName(String companyname);

                    public List<Company> findAll();
    }

I tried to set keyspace for Repository using the class which extend AbstractCassandraConfiguration instead of application.properties. it didn't work cassandraTemplate is working fine. i am getting issue with only Repository. even if i create and configure CassandraClusterFactoryBean, CassandraMappingContext, CassandraConverter and CassandraSessionFactoryBean beans repository is throwing below exception

com.datastax.driver.core.exceptions.InvalidQueryException: No keyspace has been specified. USE a keyspace, or explicitly specify keyspace.tablename
    at com.datastax.driver.core.Responses$Error.asException(Responses.java:147) ~[cassandra-driver-core-3.4.0.jar:na]
    at com.datastax.driver.core.DefaultResultSetFuture.onSet(DefaultResultSetFuture.java:179) ~[cassandra-driver-core-3.4.0.jar:na]

if i add below entries to application.properties file then it is working fine.

spring.data.cassandra.port=9042
spring.data.cassandra.keyspace-name=CompanyDetails
spring.data.cassandra.contact-points=127.0.0.1

is it possible to set keyspace for Repository through class which extend AbstractCassandraConfiguration class instead of application.properties?

Feel free to point, if i missed or did something wrong.

回答1:

It looks like you forgot to create the keysace. With getKeySpaceName() you tell cassandra which keyspace you want to use but if it is not there you'll get an error. To create a keyspace use the following method:

@Override
protected List<CreateKeyspaceSpecification> getKeyspaceCreations() {
    return Arrays.asList(
            CreateKeyspaceSpecification.createKeyspace()
                    .name("your_keyspace_name")
                    .ifNotExists()
    );
}