【问题标题】:How create table with spring data cassandara?如何使用 Spring Data cassandra 创建表?
【发布时间】:2014-10-11 00:23:25
【问题描述】:

我已经像这样创建了自己的存储库:

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

那么问题是如何为此自动创建 cassandra 表?目前 Spring 注入 MyRepository 尝试将实体插入到不存在的表中。

那么有没有办法在 spring 容器启动期间创建 cassandra 表(如果它们不存在)?

PS 如果只有配置布尔属性而不添加 xml 行并创建诸如 BeanFactory 之类的东西,那将是 非常好。 :-)

【问题讨论】:

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

标签: java spring cassandra spring-data-cassandra


【解决方案1】:

覆盖 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());
    }

}

【讨论】:

  • 我正在手动创建SessionBeanFactory(以覆盖spring-boot)并设置模式操作。但是,它似乎没有任何区别,我仍然收到“InvalidQueryException: unconfigured table mytable”。
【解决方案2】:

您可以在 application.properties

中使用此配置
spring.data.cassandra.schema-action=CREATE_IF_NOT_EXISTS

【讨论】:

    【解决方案3】:

    您还需要在 AbstractCassandraConfiguration 实现中重写 getEntityBasePackages() 方法。这将允许 Spring 找到您使用 @Table 注释的任何类,并创建表。

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

    【讨论】:

    • 我想目前 spring-data-cassandra 1.5M1 它不工作。你能确认一下吗?
    • @AllahbakshAsadullah 是的,它不适用于 1.5.1 版。您改用了哪个版本?
    【解决方案4】:
    1. 您需要在 pom.xml 文件中包含 spring-data-cassandra 依赖项。
    2. 如下配置您的 TestConfig.class

      @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());
      }
      }
      

      最后一个 getInitialEntitySet 方法可能是可选的。不用这个也可以试试。

    3. 确保 Keyspacecontactpointsport.properties 文件中。喜欢:

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

    【讨论】:

      【解决方案5】:

      其实,在深入研究位于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 不起作用。


      更多信息请在此处查看:Why `spring-data-jpa` with `spring-data-cassandra` won't create cassandra tables automatically?

      【讨论】:

        猜你喜欢
        • 2019-10-29
        • 2016-09-18
        • 1970-01-01
        • 2020-12-02
        • 2019-12-23
        • 2020-03-08
        • 2017-11-12
        • 1970-01-01
        • 2019-05-29
        相关资源
        最近更新 更多