Как инициализировать пространство ключей и таблицы Cassandra с помощью загрузки Spring

Я использую Cassandra в качестве источника данных в моем загрузочном приложении Spring и хочу инициализировать базу данных перед запуском приложения.

До сих пор я определил класс «CassandraConfiguration», расширяющий класс «AbstractCassandraConfiguration», как в примерах, которые вы можете видеть ниже, и у меня есть репозиторий, расширяющий «CassandraRepository». Когда я сам создаю пространство ключей и таблицу, приложение работает нормально.

Однако я хочу автоматически создавать пространство ключей и таблицы при запуске приложения. Для этого я предоставил файл schema.cql в папке ресурсов, но мне не удалось заставить этот скрипт работать.

Кто-нибудь знает, что я могу сделать для автоматического создания пространств ключей и таблиц?

Спасибо.

Изменить: я использую версии Cassandra 2.0.9, spring-boot 1.3.2.RELEASE и datastax cassandra driver 2.1.6.

CassandraConfiguration.java

@Configuration
@PropertySource(value = { "classpath:cassandra.properties" })
@EnableCassandraRepositories(basePackages = { "bla.bla.bla.repository" })
public class CassandraConfiguration extends AbstractCassandraConfiguration {

    @Autowired
    private Environment environment;


    @Bean
    public CassandraClusterFactoryBean cluster() {
        CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean();
        cluster.setContactPoints( environment.getProperty( "cassandra.contactpoints" ) );
        cluster.setPort( Integer.parseInt( environment.getProperty( "cassandra.port" ) ) );
        return cluster;
    }


    @Bean
    public CassandraMappingContext cassandraMapping() throws ClassNotFoundException {
        return new BasicCassandraMappingContext();
    }


    @Bean
    public CassandraConverter converter() throws ClassNotFoundException {
        return new MappingCassandraConverter(cassandraMapping());
    }


    @Override
    protected String getKeyspaceName() {
        return environment.getProperty( "cassandra.keyspace" );
    }


    @Bean
    public CassandraSessionFactoryBean session() throws Exception {

        CassandraSessionFactoryBean session = new CassandraSessionFactoryBean();
        session.setCluster(cluster().getObject());
        session.setKeyspaceName(environment.getProperty("cassandra.keyspace"));
        session.setConverter(converter());
        session.setSchemaAction(SchemaAction.NONE);

        return session;
    }


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

person frkn    schedule 02.02.2016    source источник
comment
С Spring boot 1.3 конфигурация намного проще, см. Это: flnjworkingnotes.blogspot.com/2016/01/, например.   -  person jny    schedule 02.02.2016
comment
Моя проблема заключается не в сопоставлении объектов, а в автоматическом создании таблиц, если таблицы нет заранее.   -  person frkn    schedule 03.02.2016


Ответы (4)


Если у вас все еще возникают проблемы с этим, в Spring Boot 2 и SD Cassandra 2.0.3 вы можете выполнить эту простую настройку Java и настроить все из коробки.

@Configuration
@EnableCassandraRepositories(basePackages = "com.example.repository")
public class DbConfigAutoStart extends AbstractCassandraConfiguration {

    /*
     * Provide a contact point to the configuration.
     */
    @Override
    public String getContactPoints() {
        return "exampleContactPointsUrl";
    }

    /*
     * Provide a keyspace name to the configuration.
     */
    @Override
    public String getKeyspaceName() {
        return "exampleKeyspace";
    }

    /*
     * Automatically creates a Keyspace if it doesn't exist
     */
    @Override
    protected List<CreateKeyspaceSpecification> getKeyspaceCreations() {
        CreateKeyspaceSpecification specification = CreateKeyspaceSpecification
                .createKeyspace("exampleKeyspace").ifNotExists()
                .with(KeyspaceOption.DURABLE_WRITES, true).withSimpleReplication();
        return Arrays.asList(specification);
    }


    /*
     * Automatically configure a table if doesn't exist
     */
    @Override
    public SchemaAction getSchemaAction() {
        return SchemaAction.CREATE_IF_NOT_EXISTS;
    }


    /*
     * Get the entity package (where the entity class has the @Table annotation)
     */
    @Override
    public String[] getEntityBasePackages() {
        return new String[] { "com.example.entity" };
    }

И тебе хорошо идти

person Urosh T.    schedule 17.02.2018
comment
работает также с более низкими версиями (spring boot 1.5.10 и cassandra 3.0.16). - person NotMyFaultSir; 16.08.2018

Ваш тип возвращаемого значения BasicCassandraMappingContext () может быть устаревшим. Использовать

@Bean
public CassandraMappingContext mappingContext() throws ClassNotFoundException {
    CassandraMappingContext mappingContext= new CassandraMappingContext();
    mappingContext.setInitialEntitySet(getInitialEntitySet());
    return mappingContext;
}
@Override
public String[] getEntityBasePackages() {
    return new String[]{"base-package name of all your entity, annotated 
with @Table"};
}

@Override
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
    return CassandraEntityClassScanner.scan(getEntityBasePackages());
}

Вместо,

@Bean
public CassandraMappingContext cassandraMapping() throws ClassNotFoundException {
    return new BasicCassandraMappingContext();
}

также установите:

session.setSchemaAction(SchemaAction.RECREATE_DROP_UNUSED);

и исключить:

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

получите ссылку здесь.

person Rujal Shrestha    schedule 06.10.2017

Я работаю с spring-boot 1.5.10.RELEASE и cassandra 3.0.16, но вы можете попробовать уменьшить версии. Чтобы создать пространство ключей, вы можете импортировать имя пространства ключей от себя application.yml или application.properties. Используя аннотацию @Table, ваши таблицы должны создаваться автоматически, если вы установили базовый пакет сущности.

@Value("${cassandra.keyspace}")
private String keySpace;

@Override
public String[] getEntityBasePackages() {
    return new String[]{"com.example.your.entities"};
}

@Override
protected List<CreateKeyspaceSpecification> getKeyspaceCreations() {
    return Arrays.asList(
            CreateKeyspaceSpecification.createKeyspace()
                    .name(keySpace)
                    .ifNotExists()
    );
}
person NotMyFaultSir    schedule 03.08.2018

Наконец, я заставил его работать, добавив setKeyspaceCreations (getKeyspaceCreations ()) в CassandraClusterFactoryBean Override, а также не забудьте включить @ComponentScan.

import com.datastax.driver.core.PlainTextAuthProvider;
import com.datastax.driver.core.policies.ConstantReconnectionPolicy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.cassandra.config.*;
import org.springframework.data.cassandra.core.cql.keyspace.CreateKeyspaceSpecification;
import org.springframework.data.cassandra.core.cql.keyspace.DropKeyspaceSpecification;
import org.springframework.data.cassandra.core.cql.keyspace.KeyspaceOption;
import org.springframework.data.cassandra.repository.config.EnableReactiveCassandraRepositories;

import java.util.Arrays;
import java.util.List;



@Configuration
@EnableReactiveCassandraRepositories(basePackages = "com.company.domain.data")
public class CassandraConfig extends AbstractReactiveCassandraConfiguration{
@Value("${spring.data.cassandra.contactpoints}") private String contactPoints;
@Value("${spring.data.cassandra.port}") private int port;
@Value("${spring.data.cassandra.keyspace-name}") private String keyspace;

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


@Override protected String getKeyspaceName() {
    return keyspace;
}
@Override protected String getContactPoints() {
    return contactPoints;
}
@Override protected int getPort() {
    return port;
}
@Override public SchemaAction getSchemaAction() {
    return SchemaAction.CREATE_IF_NOT_EXISTS;
}
@Override
public String[] getEntityBasePackages() {
    return new String[]{"com.company.domain.data"};
}

@Override
public CassandraClusterFactoryBean cluster() {
    PlainTextAuthProvider authProvider = new PlainTextAuthProvider(userName, password);

    CassandraClusterFactoryBean cluster=new CassandraClusterFactoryBean();

    cluster.setJmxReportingEnabled(false);
    cluster.setContactPoints(contactPoints);
    cluster.setPort(port);
    cluster.setAuthProvider(authProvider);
    cluster.setKeyspaceCreations(getKeyspaceCreations());
    cluster.setReconnectionPolicy(new ConstantReconnectionPolicy(1000));

    return cluster;
}


@Override
protected List<CreateKeyspaceSpecification> getKeyspaceCreations() {

    CreateKeyspaceSpecification specification = CreateKeyspaceSpecification.createKeyspace(keyspace)
            .ifNotExists()
            .with(KeyspaceOption.DURABLE_WRITES, true);

    return Arrays.asList(specification);
}



@Override
protected List<DropKeyspaceSpecification> getKeyspaceDrops() {
    return Arrays.asList(DropKeyspaceSpecification.dropKeyspace(keyspace));
}



}
person VinothNair    schedule 06.02.2019