TTL support in spring boot application using spring-data-cassandra

大兔子大兔子 提交于 2019-12-23 10:15:20

问题


I am trying to add TTL to each column while insertion and update data using spring boot applicaiton. For this i am using spring-data-cassandra 1.1.3.RELEASE

For this i had written one interface CustomTTLRepository:

@NoRepositoryBean

public interface CustomTTLRepository<T, ID extends Serializable> extends TypedIdCassandraRepository<T, ID> {

    <S extends T> S save(S s, int ttl);

}

Implementation CustomTTLRepositoryImpl:

@NoRepositoryBean

public class CustomTTLRepositoryImpl<T, ID extends Serializable> extends SimpleCassandraRepository<T, ID> implements CustomTTLRepository<T, ID> {

    public CustomTTLRepositoryImpl(CassandraEntityInformation<T, ID> metadata, CassandraTemplate template) {
         super(metadata, template);
         this.entityInformation = metadata;
         this.template = template;
    }   

    @Override
    public <S extends T> S save(S s, int ttl) {
        WriteOptions writeOptions=new WriteOptions();
        writeOptions.setTtl(ttl);
        return template.insert(s, writeOptions);
    }

}

But when i am trying to deploy this application i am getting following error:

Caused by: java.lang.IllegalArgumentException: encountered unsupported query parameter type [class java.lang.Object] in method public abstract java.lang.Object com.cisco.operation.CustomTTLRepository.save(java.lang.Object,int)
    at org.springframework.data.cassandra.repository.query.CassandraQueryMethod.verify(CassandraQueryMethod.java:104)
    at org.springframework.data.cassandra.repository.query.CassandraQueryMethod.<init>(CassandraQueryMethod.java:68)
    at org.springframework.data.cassandra.repository.support.CassandraRepositoryFactory$CassandraQueryLookupStrategy.resolveQuery(CassandraRepositoryFactory.java:106)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:369)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:192)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:239)
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:225)

回答1:


It may be an old thread to submit any post. But it helped me to complete my task at hand. So here are the solutions that worked for me

  1. Customizing Base Repository
  2. Customizing Individual Repository

Changes for Customizing Base Repository

1.1. Extend CassandraRepository to add save method that accepts TTL

@NoRepositoryBean
public interface ExtendedCassandraRepository<T, ID> extends CassandraRepository<T, ID> {
    <S extends T> S save(S entity, int ttl);
}

1.2. Provide implementation for new save method

public class ExtendedCassandraRepositoryImpl<T, ID> extends SimpleCassandraRepository<T, ID> implements ExtendedCassandraRepository<T, ID> {

private final CassandraEntityInformation<T, ID> entityInformation;
private final CassandraOperations operations;

public ExtendedCassandraRepositoryImpl(CassandraEntityInformation metadata, CassandraOperations operations) {
    super(metadata, operations);

    this.entityInformation = metadata;
    this.operations = operations;
}

@Override
public <S extends T> S save(S entity, int ttl) {
    InsertOptions insertOptions = org.springframework.data.cassandra.core.InsertOptions.builder().ttl(ttl).build();
    operations.insert(entity, insertOptions);
    return entity;
}
}

1.3. Create repository for my domain entity

@Repository
public interface MyDomainEntityRepository extends ExtendedCassandraRepository<MyDomainEntity,String> {
}

1.4. Update repositoryBaseClass

@EnableCassandraRepositories(basePackages = "my.repository", repositoryBaseClass = ExtendedCassandraRepositoryImpl.class)

Changes for Customizing Individual Repository

2.1. Define a fragment interface with new save method

public interface CustomizedSave<T> {
    <S extends T> S save(S entity, int ttl);
}

2.2. Provide implementation

public class CustomizedSaveImpl<T> implements CustomizedSave<T> {

@Autowired
private CassandraOperations operations;

@Override
public <S extends T> S save(S entity, int ttl) {
    InsertOptions insertOptions = org.springframework.data.cassandra.core.InsertOptions.builder().ttl(ttl).build();
    operations.insert(entity, insertOptions);
    return entity;
}
}

2.3. Extend this method in repository

@Repository
public interface MyDomainEntityRepository extends CassandraRepository<MyDomainEntity,String>, CustomizedSave<MyDomainEntity> {
}

Reference Document https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.custom-implementations




回答2:



Even though it's too late answer may be it will help full for others, i have tried with CassandraOperations which is working fine please check below repository implementation

 @Repository
 public class DomainRepository {

 @Autowired
 CassandraOperations cassandraOperations;

 @Autowired
 WriteOptions writeOptions;

 @Override
 public void save(DomainObject domainObject) {
    writeOptions.setTtl(100);
    cassandraOperations.insert(domainObject,writeOptions);
 }
}

Thanks



来源:https://stackoverflow.com/questions/34505376/ttl-support-in-spring-boot-application-using-spring-data-cassandra

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!