0

我不断收到这条消息,Spring 将使用 CassandraRepositoryFactoryBean 覆盖我的工厂 bean 定义。这会导致问题,因为我覆盖工厂的原因是要覆盖saverepo 上的方法,以便我可以自动填充createTimestampupdateTimestamp方法。

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]

显然这里有一些优先顺序或缺少配置,但我找不到它。也许你可以?

我的弹簧配置:

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

}

我在哪里覆盖TypedIdCassandraRepository

@NoRepositoryBean
public interface TimestampCrudRepository<T extends BaseTimestampEntity, I extends Serializable>
    extends TypedIdCassandraRepository<T, I> {


}

如果你对BaseTimestampEntity

public abstract class BaseTimestampEntity {

@CreatedDate
@Column("create_timestamp") // timestamp,
private Instant createTimestamp;
@LastModifiedDate
@Column("update_timestamp") // timestamp,
private Instant updateTimestamp;

}

我在哪里实现该save方法:

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

最后是我的工厂:

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;
    }

}
}

差点忘了回购:

public interface ContainerIdRepo extends TimestampCrudRepository<ContainerEntity, MapId> {}

什么都没有发生,但插入 Cassandra 数据库的 updateTimestamp 和 createTimestamp 是,我可以告诉你在调试时没有命中null覆盖方法。save

4

1 回答 1

1

原来

@EnableCassandraRepositories(repositoryFactoryBeanClass = TimestampCrudRepositoryFactoryBean.class, repositoryBaseClass = TimestampCrudRepositoryImpl.class, basePackages = {
"com.database.repo", "com.database.entity" })

@Bean
@Primary
@Order(Ordered.HIGHEST_PRECEDENCE)
public CassandraTemplate cassandraTemplate(Session session, CassandraConverter converter) {
return new CassandraTemplate(session, converter);
}

即使该类使用@Configuration. 我不得不把它放在主应用程序类中。

此外,我只需要删除我创建的工厂。这TimestampCrudRepositoryFactoryBean

只有接口和实现(并且一旦注释被移动)它就可以工作,Spring 没有尝试用更通用的定义替换我的定义。

图这是 Spring 配置的操作顺序。至少这是我有根据的猜测。

于 2018-01-22T14:43:52.260 回答