Spring Data JPA Cassandra 覆盖保存方法



我一直收到这样的消息,Spring将使用CassandraRepositoryFactoryBean覆盖我的工厂bean定义。这会导致问题,因为我重写工厂的原因是覆盖存储库上的 save 方法,以便我可以自动填充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 DB的updateTimestamp和createTimestamp是null的,我可以说在调试时没有命中覆盖save方法。

原来

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

不能存在于单独的配置 java 类中,即使该类用 @Configuration 注释。我不得不把它放在主应用程序类中。

此外,我

必须删除我创建的工厂。TimestampCrudRepositoryFactoryBean

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

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

相关内容

  • 没有找到相关文章

最新更新