1

@Service
public abstract class BaseService<R extends IChanakyaR2dbcRepository<E, String>, E, D> {

    @Autowired
    protected R repository;

    public abstract D convertToDTO(E entity);

    public abstract E convertToEntity(D DTO);

    public Flux<D> findAll() {
        return repository.findAll().map(this::convertToDTO);
    }

    public Mono<D> findById(String id) {
        return repository.findById(id).map(this::convertToDTO);
    }

    public Mono<D> create(D DTO) {
        return repository.insert(convertToEntity(DTO)).map(this::convertToDTO);
    }

    public Mono<D> update(D DTO) {
        return repository.save(convertToEntity(DTO)).map(this::convertToDTO);
    }

    public Mono<Void> delete(D DTO) {
        return repository.delete(convertToEntity(DTO));
    }
}

我将上述类作为一个抽象类,我的所有基础服务类都将从中继承。


@Service
public class ClusterService extends BaseService<IChanakyaR2dbcRepository<ClusterEntity, String>, ClusterEntity, ClusterDTO> {

    @Autowired
    ModelMapper modelMapper;

    @Override
    public ClusterDTO convertToDTO(ClusterEntity entity) {
        return modelMapper.map(entity, ClusterDTO.class);
    }

    @Override
    public ClusterEntity convertToEntity(ClusterDTO DTO) {
        return modelMapper.map(DTO, ClusterEntity.class);
    }

}

这是我的服务班。


@NoRepositoryBean
public interface IChanakyaR2dbcRepository<T, ID> extends ReactiveCrudRepository<T, ID> {

    /**
     * Inserts a given entity. Use the returned instance for further operations as the save operation might have changed the
     * entity instance completely.
     *
     * @param entity must not be {@literal null}.
     * @return {@link Mono} emitting the inserted entity.
     * @throws IllegalArgumentException in case the given {@literal entity} is {@literal null}.
     */
    <S extends T> Mono<S> insert(S entity);

}

这是我的存储库类。


@Slf4j
@Transactional(readOnly = true)
public class ChanakyaR2dbcRepository<T, ID> extends SimpleR2dbcRepository<T, ID> {

    private final RelationalEntityInformation<T, ID> entity;
    private final DatabaseClient databaseClient;
    private final R2dbcConverter converter;
    private final ReactiveDataAccessStrategy accessStrategy;

    public ChanakyaR2dbcRepository(RelationalEntityInformation entity, DatabaseClient databaseClient, R2dbcConverter converter, ReactiveDataAccessStrategy accessStrategy) {
        super(entity, databaseClient, converter, accessStrategy);
        this.entity = entity;
        this.databaseClient = databaseClient;
        this.converter = converter;
        this.accessStrategy = accessStrategy;
    }

    @Transactional
    public <S extends T> Mono<S> insert(S objectToSave) {

        Assert.notNull(objectToSave, "Object to insert must not be null!");

        try {
            return this.databaseClient.insert()
                    .into(this.entity.getJavaType())
                    .table(this.entity.getTableName()).using(objectToSave)
                    .map(this.converter.populateIdIfNecessary(objectToSave))
                    .first()
                    .defaultIfEmpty(objectToSave);
        } catch(DataIntegrityViolationException diex) {
            String errMsg = String.format("Entity {} already exists in database", this.entity);
            log.error(errMsg, diex);
            return Mono.error(new IllegalStateException(errMsg));
        }
    }

}

这是我的存储库实现。

当我运行应用程序时,我收到以下错误。

org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为“clusterService”的bean时出错:通过字段“repository”表示的依赖关系不满足;嵌套异常是

org.springframework.beans.factory.NoSuchBeanDefinitionException:没有可用的“com.appdynamics.sum.chanakya.repository.base.IChanakyaR2dbcRepository”类型的合格bean:预计至少有1个有资格作为自动装配候选者的bean。依赖注解:{@org.springframework.beans.factory.annotation.Autowired(required=true)}

上面的自动装配不起作用,但是当我IChanakyaR2dbcRepository<ClusterEntity, String>直接在另一个组件中自动装配时(不是通过通用类型)。它工作正常。

做这种事情的正确方法是什么?我想要 BaseService 实现。

我知道如果您创建一个扩展IChanakyaR2dbcRepository<ClusterEntity, String>该类并将其作为泛型类型传递给它的接口,BaseService那么它将正常工作。但这意味着为我拥有的每个实体创建这样的空类,这不是一个理想的解决方案。

4

2 回答 2

2

你应该试试这个:

@EnableR2dbcRepositories(basePackages = {"your.repository.package"}, 
basePackageClasses = {}) 

问题在于springboot不知道在哪里可以找到这个自定义类型r2dbc存储库

于 2020-07-08T14:02:34.360 回答
0

不太确定您要达到的目标。如果您希望您的 IChanakyaR2dbcRepository 成为“baserepository”(因此@NoRepositoryBean)并让“另一个”@Repository 扩展它并在您的“基本服务”中自动装配它

@Repository
MyIChanakyaR2dbcRepository ....

@Autowire
MyIChanakyaR2dbcRepository rep;

或在您的 ClusterService 或您的“BaseService”中自动装配 @Repository 应该实现您的任何存储库(取决于您要实现的目标)

但只是从异常中告诉您需要在“BaseService”中提供@Repository,如

@Repository
MyIChanakyaR2dbcRepository extends "YourBasyRepository"<"YourEntityType", "YourIdType">{.....}

@Service
public abstract class BaseService<R extends IChanakyaR2dbcRepository<E, String>, E, D> {

    @Autowired
    protected MyIChanakyaR2dbcRepository repository;

你不能自动装配@NoRepositoryBeans

于 2022-02-27T07:27:38.117 回答