Search code examples
androidandroid-roomrx-java2

Create parent entity then create children entities with parent ID


In my code, a Hero has many Power. To create a Power object, I need a heroId. In this case, I'm trying to create a hero and then give the hero multiple powers.

Thus, the HeroDao:

@Dao
public interface HeroDao {
    @Insert
    Single<Long> create(Hero hero);
}

And the PowerDao:

@Dao
public interface PowerDao {
    @Insert
    Completable create(Power power);
}

So,

Completable createHero(List<Power> powers) {
    return heroDao.create(new Hero())
            .flatMapCompletable(heroId -> Observable.fromIterable(powers)
                    .flatMapCompletable(power -> {
                        power.heroId = heroId;
                        return powerDao.create(power);
                    }))
            .subscribeOn(Schedulers.io());
}

But that instead throws an exception:

io.reactivex.exceptions.UndeliverableException: The exception could not be delivered to the consumer because it has already canceled/disposed the flow or the exception has nowhere to go to begin with.

That exception also provides a link that explains more about that particular error but the details aren't making sense to me since I'm a beginner with limited experience using RxJava.

What's going on?

UPDATE: In my ViewModel, the subscription looks like this:

createHero(powers)
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(this::success, this::error);

Solution

  • Update your createHero() to log errors:

    Completable createHero(List<Power> powers) {
        return heroDao.create(new Hero())
                // add explicit error log
                .doOnError(e -> Log.e("ERROR", "insert hero error", e))
                .flatMapCompletable(heroId -> Observable.fromIterable(powers)
                        .flatMapCompletable(power -> {
                            power.setHeroId(heroId);
                            return create(power)
                                    .doOnError(e -> Log.e("ERROR", "insert power error", e))
                        }))
    }
    

    You should now see what error is really thrown.