I keep getting this message that Spring will override MY factory bean definition with the CassandraRepositoryFactoryBean. This is causing problems as the reason I am overriding the factory is to override the save
method on a repo so that I can automatically populate createTimestamp
and updateTimestamp
methods.
2018-01-16 18:24:32,355 INFO main o.s.b.f.s.DefaultListableBeanFactory:828 - Overriding bean definition for bean 'containerIdRepo' with a different definition: replacing [Root bean: class [com.database.repo.audit.TimestampCrudRepositoryFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] with [Root bean: class [org.springframework.data.cassandra.repository.support.CassandraRepositoryFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]
Obviously there is either some order of precedence or missing configuration here but I can't find it. Perhaps you can?
My Spring Configuration:
@Configuration
@EnableCassandraRepositories(repositoryFactoryBeanClass = TimestampCrudRepositoryFactoryBean.class, repositoryBaseClass = TimestampCrudRepositoryImpl.class, basePackages = {
"com.database.repo", "com.database.entity" })
public class DataCassandraConfiguration extends CassandraConfiguration {
@Bean
@Primary
@Order(Ordered.HIGHEST_PRECEDENCE)
public CassandraTemplate cassandraTemplate(Session session, CassandraConverter converter) {
return new CassandraTemplate(session, converter);
}
}
Where I override the TypedIdCassandraRepository
@NoRepositoryBean
public interface TimestampCrudRepository<T extends BaseTimestampEntity, I extends Serializable>
extends TypedIdCassandraRepository<T, I> {
}
If you're curious about the BaseTimestampEntity
public abstract class BaseTimestampEntity {
@CreatedDate
@Column("create_timestamp") // timestamp,
private Instant createTimestamp;
@LastModifiedDate
@Column("update_timestamp") // timestamp,
private Instant updateTimestamp;
}
Where I implement the save
method:
@NoRepositoryBean
@Slf4j
public class TimestampCrudRepositoryImpl<T extends BaseAuditEntity, I extends Serializable>
extends SimpleCassandraRepository<T, I> implements TimestampCrudRepository<T, I> {
private final boolean isPrimaryKeyEntity;
public TimeStampCrudRepositoryImpl(CassandraEntityInformation<T, I> metadata, CassandraOperations operations) {
super(metadata, operations);
this.isPrimaryKeyEntity = metadata.isPrimaryKeyEntity();
}
@Override
public <S extends T> S save(S entity) {
log.info("Using overriden save method to add create and update timestamp");
Assert.notNull(entity, "Entity must not be null");
Instant now = Instant.now();
entity.setUpdateTimestamp(now);
if (entity.getCreateTimestamp() == null) {
entity.setCreateTimestamp(now);
}
if (entityInformation.isNew(entity) || isPrimaryKeyEntity) {
return operations.insert(entity);
}
return operations.update(entity);
}
}
And finally my factory:
public class TimestampCrudRepositoryFactoryBean<T extends TimestampCrudRepository<S, I>, S extends BaseTimestampEntity, I extends Serializable>
extends RepositoryFactoryBeanSupport<T, S, I> {
@Autowired
private CassandraTemplate cassandraTemplate;
protected TimestampCrudRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
super(repositoryInterface);
}
public void setCassandraTemplate(CassandraTemplate cassandraTemplate) {
this.cassandraTemplate = cassandraTemplate;
}
@Override
protected RepositoryFactorySupport createRepositoryFactory() {
return new TimestampCrudRepositoryFactory(cassandraTemplate);
}
@Override
public void afterPropertiesSet() {
super.afterPropertiesSet();
Preconditions.checkNotNull(cassandraTemplate, "cassandraTemplate must not be null!");
setMappingContext(cassandraTemplate.getConverter().getMappingContext());
}
private static class TimestampCrudRepositoryFactory<S extends BaseAuditEntity, I extends Serializable>
extends CassandraRepositoryFactory {
private final CassandraTemplate cassandraTemplate;
public TimestampCrudRepositoryFactory(CassandraTemplate cassandraTemplate) {
super(cassandraTemplate);
this.cassandraTemplate = cassandraTemplate;
}
@Override
@SuppressWarnings("unchecked")
protected Object getTargetRepository(RepositoryInformation information) {
CassandraEntityInformation<?, Serializable> entityInformation = getEntityInformation(information.getDomainType());
return new TimestampCrudRepositoryImpl(entityInformation, cassandraTemplate);
}
@Override
protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
return TimestampCrudRepositoryImpl.class;
}
}
}
Almost forgot the repo:
public interface ContainerIdRepo extends TimestampCrudRepository<ContainerEntity, MapId> {}
Nothing is bombing out but the updateTimestamp and createTimestamp inserts into the Cassandra DB are null
and I can tell the override save
method is not being hit when debugging.