不执行Reactive Cassandra Callback doInSession

时间:2017-10-14 22:00:30

标签: java project-reactor spring-data-cassandra

我通过一些小修改来关注一个例子:https://dzone.com/articles/spring-webflux-first-steps

我的ServiceImpl看起来像:

private final HotelRepository hotelRepository;

private final HotelByLetterRepository hotelByLetterRepository;

public HotelServiceImpl(HotelRepository hotelRepository, HotelByLetterRepository hotelByLetterRepository) {
    this.hotelRepository = hotelRepository;
    this.hotelByLetterRepository = hotelByLetterRepository;
}

@Override
public Mono<Hotel> save(Hotel hotel) {
    if (hotel.getId() == null) {
        hotel.setId(UUID.randomUUID());
    }
    Mono<Hotel> saved = hotelRepository.save(hotel);
    saved.then(hotelByLetterRepository.save(new HotelByLetter(hotel)));
    return saved;
}

保存Hotel实体后,逻辑尝试保存HottelByLetter

在存储库中我注入ReactiveCassandraOperations,对于save方法,我只调用insert方法。

@Repository
public class CassandraHotelRepository implements HotelRepository {

    private final ReactiveCassandraOperations cassandraTemplate;

    public CassandraHotelRepository(ReactiveCassandraOperations cassandraTemplate) {
        this.cassandraTemplate = cassandraTemplate;
    }

    @Override
    public Mono<Hotel> save(Hotel hotel) {
        return cassandraTemplate.insert(hotel);
    }
}

仅保存服务电话Hotel后,系统不保存HotelByLetter。 调试后我发现:

ReactiveCqlTemplate方法createFlux中正确调用ReactiveSessionCallback两次。

protected <T> Flux<T> createFlux(ReactiveSessionCallback<T> callback) {

    Assert.notNull(callback, "ReactiveStatementCallback must not be null");

    ReactiveSession session = getSession();

    return Flux.defer(() -> callback.doInSession(session));
}

但是,callback.doInSession(session)仅执行一次插入新酒店。 我也尝试扩展ReactiveCrudRepository,但同样的问题。

我正在使用:org.springframework.data/spring-data-cassandra/2.0.0.RELEASE

1 个答案:

答案 0 :(得分:0)

TL; DR;

您需要使用每个发布商运营商的结果来应用创建Publisher的实际操作。

说明

Project Reactor的基本概念是永远不会通过运算符变异Publisher,而是返回一个新实例。与Future之类的CompletableFuture相比,您可以注册回调,而且您没有义务重复使用回调注册方法的结果使它工作。

HotelServiceImpl的代码应如下所示:

class HotelServiceImpl implements HotelService {

    // …

    @Override
    public Mono<Hotel> save(Hotel hotel) {
        if (hotel.getId() == null) {
            hotel.setId(UUID.randomUUID());
        }
        Mono<Hotel> saved = hotelRepository.save(hotel);
        return saved.then(hotelByLetterRepository.save(new HotelByLetter(hotel)));
    }
}

致电saved.then(…)会创建一个新的Mono。删除(不使用)Mono将导致不执行.then(…)运算符。相反,返回saved.then(…)的结果也会保存HotelByLetter