【问题标题】:Extend reactive crud repository扩展响应式 crud 存储库
【发布时间】:2020-04-11 00:13:46
【问题描述】:

尝试扩展 spring boot ReactiveCrudRepository 接口,使其具有单独的实体插入和更新方法。现在save() 方法区分插入和更新检查 ID 是否提供。为什么我需要以这种方式扩展它的想法,因为即将到来的带有新实体或修改实体的 kafka 事件已经填充了 ID。

CustomReactiveCrudRepository:

public interface CustomReactiveCrudRepository<T, ID> extends ReactiveCrudRepository<T, ID> {

    <S extends T> Mono<S> insert(S entity);

    <S extends T> Mono<S> update(S entity);

}

CustomReactiveCrudRepositoryImpl:

public class CustomReactiveCrudRepositoryImpl<T, ID> extends SimpleR2dbcRepository<T, ID> implements CustomReactiveCrudRepository<T, ID> {

    private final RelationalEntityInformation<T, ID> entity;
    private final DatabaseClient                     databaseClient;

    public CustomReactiveCrudRepositoryImpl(RelationalEntityInformation<T, ID> entity, DatabaseClient databaseClient, R2dbcConverter converter, ReactiveDataAccessStrategy accessStrategy) {
        super(entity, databaseClient, converter, accessStrategy);
        this.entity = entity;
        this.databaseClient = databaseClient;
    }

    @Override
    public <S extends T> Mono<S> insert(S objectToSave) {
        Assert.notNull(objectToSave, "Object to save must not be null!");

        return this.databaseClient.insert()
                                  .into(this.entity.getJavaType())
                                  .table(this.entity.getTableName()).using(objectToSave)
                                  // Removed ID generation since it's generated initially
                                  .map((row, rowMetadata) -> objectToSave)
                                  .first()
                                  .defaultIfEmpty(objectToSave);

    }

    @Override
    public <S extends T> Mono<S> update(S objectToSave) {
        Assert.notNull(objectToSave, "Object to save must not be null!");

        return this.databaseClient.update()
                                  .table(this.entity.getJavaType())
                                  .table(this.entity.getTableName()).using(objectToSave)
                                  .fetch().rowsUpdated().handle((rowsUpdated, sink) -> {

                if (rowsUpdated == 0) {
                    sink.error(new TransientDataAccessResourceException(
                        String.format("Failed to update table [%s]. Row with Id [%s] does not exist.",
                                      this.entity.getTableName(), this.entity.getId(objectToSave))));
                } else {
                    sink.next(objectToSave);
                }
            });
    }

}

FooRepository:

@Repository
public interface FooRepository extends CustomReactiveCrudRepository<Foo, UUID> {}

Foo 实体:

@Data
@Table
public class Foo {

    @Id
    private UUID      id;
    private SomeStatus someStatus;
    private Boolean   someBoolean;

}

上面的例子导致UnsupportedOperationException:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fooRepository': Invocation of init method failed; nested exception is java.lang.UnsupportedOperationException: Query derivation not yet supported!

我应该如何以适当的方式扩展这些功能?

【问题讨论】:

    标签: spring-boot spring-data-r2dbc


    【解决方案1】:

    这可能不再相关,但我是这样做的(使用 Spring webflux):

    我正在使用 R2dbc,它为每个存储库创建一个 SimpleR2dbcRepository

    我创建了一个自定义类,它扩展了名为CustomRepositorySimpleR2dbcRepository。在一个配置中我说@EnableR2dbcRepositories(repositoryBaseClass = CustomRepository.class)

    然后我可以覆盖旧方法并创建新方法。

    【讨论】:

    • 当然,您的存储库仍然需要自定义接口,因此方法调用可用。
    【解决方案2】:

    确保您正在导入 org.springframework.data.r2dbc.repository.query.Query 不是org.springframework.data.jpa.repository.Query

    【讨论】:

      猜你喜欢
      • 2017-12-27
      • 1970-01-01
      • 2017-05-23
      • 2014-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-21
      相关资源
      最近更新 更多