如何使用Spring Data Cassandra创建表格?

10

我创建了自己的存储库,就像这样:

public interface MyRepository extends TypedIdCassandraRepository<MyEntity, String> {
}

那么问题来了,如何自动创建Cassandra表?目前Spring注入MyRepository,尝试将实体插入不存在的表。

那么是否有一种方法可以在Spring容器启动期间创建Cassandra表(如果它们不存在)?

P.S. 如果只添加布尔属性而不添加xml行并创建类似于BeanFactory等的东西,那就太好了。 :-)


我遇到了完全相同的问题,很想知道解决方法。到目前为止,我已经创建了一个名为“createIfExists”的自定义存储库方法,在其中使用ifNotExists()实例化了一个CreateTableSpecification。在spring-data-cassandra初始化后,我手动调用该方法。 - Ztyx
5个回答

11

重写AbstractCassandraConfiguration类上的getSchemaAction属性。

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

    @Override
    public String getKeyspaceName() {
        return "test_config";
    }

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

    @Bean
    public CassandraOperations cassandraOperations() throws Exception {
        return new CassandraTemplate(session().getObject());
    }

}

1
我正在手动创建SessionBeanFactory(以覆盖spring-boot的默认设置),并设置模式操作。然而,似乎没有任何改变,我仍然收到“InvalidQueryException:未配置表mytable”的错误信息。 - OrangeDog

10
您可以在application.properties中使用此配置。
spring.data.cassandra.schema-action=CREATE_IF_NOT_EXISTS

6
你还需要在 AbstractCassandraConfiguration 实现类中覆盖 getEntityBasePackages() 方法。这样,Spring 就能找到任何你用 @Table 注解的类并创建相关的表格。
@Override
public String[] getEntityBasePackages() {
    return new String[]{"com.example"};
}

我猜目前的spring-data-cassandra 1.5M1版本不可用。你能确认一下吗? - Allahbaksh Asadullah
@AllahbakshAsadullah,是的,它与1.5.1版本不兼容。您使用了哪个版本? - Abdullah Khan

4
  1. You'll need to include spring-data-cassandra dependency in your pom.xml file.
  2. Configure your TestConfig.class as below:

    @Configuration
    @PropertySource(value = { "classpath:Your .properties file here" })
    @EnableCassandraRepositories(basePackages = { "base-package name of your Repositories'" })
    public class CassandraConfig {
    
    @Autowired
    private Environment environment;
    
    @Bean
    public CassandraClusterFactoryBean cluster() {
        CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean();
        cluster.setContactPoints(env.getProperty("contactpoints from your properties file"));
        cluster.setPort(Integer.parseInt(env.getProperty("ports from your properties file")));
        return cluster;
    }
    
    @Bean
    public CassandraConverter converter() {
        return new MappingCassandraConverter(mappingContext());
    }
    
    @Bean
    public CassandraSessionFactoryBean session() throws Exception {
        CassandraSessionFactoryBean session = new CassandraSessionFactoryBean();
        session.setCluster(cluster().getObject());
        session.setKeyspaceName(env.getProperty("keyspace from your properties file"));
        session.setConverter(converter());
        session.setSchemaAction(SchemaAction.CREATE_IF_NOT_EXISTS);
        return session;
    }
    
    @Bean
    public CassandraOperations cassandraTemplate() throws Exception {
        return new CassandraTemplate(session().getObject());
    }
    
    @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());
    }
    }
    

    This last getInitialEntitySet method might be an Optional one. Try without this too.

  3. Make sure your Keyspace, contactpoints and port in .properties file. Like :

    cassandra.contactpoints=localhost,127.0.0.1
    cassandra.port=9042 
    cassandra.keyspace='Your Keyspace name here'
    

1

实际上,在查看位于spring-data-cassandra:3.1.9中的源代码后,您可以检查其实现:

org.springframework.data.cassandra.config.SessionFactoryFactoryBean#performSchemaAction

具体实现如下:

protected void performSchemaAction() throws Exception {

    boolean create = false;
    boolean drop = DEFAULT_DROP_TABLES;
    boolean dropUnused = DEFAULT_DROP_UNUSED_TABLES;
    boolean ifNotExists = DEFAULT_CREATE_IF_NOT_EXISTS;

    switch (this.schemaAction) {
        case RECREATE_DROP_UNUSED:
            dropUnused = true;
        case RECREATE:
            drop = true;
        case CREATE_IF_NOT_EXISTS:
            ifNotExists = SchemaAction.CREATE_IF_NOT_EXISTS.equals(this.schemaAction);
        case CREATE:
            create = true;
        case NONE:
        default:
            // do nothing
    }

    if (create) {
        createTables(drop, dropUnused, ifNotExists);
    }
}

这意味着如果表尚未创建,您需要将 CREATE 分配给 schemaAction。而 CREATE_IF_NOT_EXISTS 无效。

更多信息请查看这里:为什么`spring-data-jpa`与`spring-data-cassandra`不会自动创建cassandra表?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接