Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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)
like image 388
Kiran Singh Avatar asked Dec 29 '15 06:12

Kiran Singh


2 Answers

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

like image 104
A Sarkar Avatar answered Sep 20 '22 01:09

A Sarkar



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

like image 45
prasad Avatar answered Sep 18 '22 01:09

prasad