Unable to get SchemaAction.CREATE to work

2.1k Views Asked by At

My Spring Data Cassandra configuration looks like this:

@Configuration
@EnableCassandraRepositories(basePackages = {
        "mypackage.repository.cassandra",
})
public class DistributedRepositoryConfiguration  {

    // ...

    @Bean
    public CassandraSessionFactoryBean session() throws Exception {

      CassandraSessionFactoryBean session = new CassandraSessionFactoryBean();
      session.setCluster(cluster().getObject());
      session.setKeyspaceName(configuration.get().getKeyspace());
      session.setConverter(converter());
      session.setSchemaAction(SchemaAction.CREATE);

      return session;
    }

}

Generally, Spring Data Cassandra works in my project. However, when I start my application I have no tables created. Anyone who could tell me what I'm doing wrong?

3

There are 3 best solutions below

2
On

It is not written well in documentation if you want to have automatic table creation you should tell cassandra where to look for entity classes:

<cassandra:mapping entity-base-packages="your.package" />

If you want to do the same using annotiation configuration you have to explicitly tell CassandraTemplate where to look for it. So

@Bean
public CassandraSessionFactoryBean session() throws Exception {

    CassandraSessionFactoryBean session = new CassandraSessionFactoryBean();
    session.setCluster(cluster().getObject());
    session.setKeyspaceName(keyspaceName);
    session.setConverter(converter());
    session.setSchemaAction(SchemaAction.CREATE);

    return session;
}

@Bean
public CassandraConverter converter() throws Exception {
    return new MappingCassandraConverter(mappingContext());
}

@Bean
public CassandraMappingContext mappingContext() throws Exception {
    BasicCassandraMappingContext bean = new BasicCassandraMappingContext(); 
    bean.setInitialEntitySet(CassandraEntityClassScanner.scan(("package.with.your.entities")));

    return bean;
}

To do it with ease I suggest using AbstractCassandraConfiguration and override methods which You need.

0
On

I checked the class AbstractCassandraConfiguration and found the following code:

public String[] getEntityBasePackages() {
    return new String[] { getClass().getPackage().getName() };
}

Since my config class isn't in the main package, the component scan does not find my classes with the @Table annotation. So I override the method "getEntityBasePackages()" using my StartUp class and everything worked fine.

This is my config class:

@Configuration
public class CassandraConfig extends AbstractCassandraConfiguration {

    @Value("${spring.data.cassandra.keyspace-name}")
    private String keyspaceName;

    @Override
    protected String getKeyspaceName() {
        return keyspaceName;
    }

    @Override
    public String[] getEntityBasePackages() {
        return new String[]{AppStartup.class.getPackage().getName()};
    }

    @Override
    protected List<CreateKeyspaceSpecification> getKeyspaceCreations() {
        return Collections.singletonList(CreateKeyspaceSpecification
                .createKeyspace(keyspaceName)
                .ifNotExists(true)
                .with(KeyspaceOption.DURABLE_WRITES, true)
                .withSimpleReplication());
    }

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

}

Using this class, your application should create the required keyspace and tables to run.

0
On

If you using CassandraDataConfiguration just annotated you base class application with:

@EntityScan("mypackage.repository.cassandra")

The base package information will be used in CassandraDataAutoConfiguration.cassandraMapping method to add this package to cassandra mapping.