2016-07-14 3 views
1

Я пытаюсь реализовать неблокирующий слой DAO для моего приложения, развивающегося в игровой среде (2.5.4). Это дает мне ошибку в deleteById()Ошибка генерации Java Generics Lambda

нет экземпляра (ов) переменной (ы) существует U так, что пустота соответствует U

abstract class BaseDao<E extends BaseModel> { 
    JPAApi jpaApi; 
    private Class<E> entityClazz; 

    BaseDao(JPAApi jpaApi, Class<E> entityClazz) { 
     this.jpaApi = jpaApi; 
     this.entityClazz = entityClazz; 
    } 

    public CompletionStage<E> save(E entity) { 
     return CompletableFuture.supplyAsync(() -> { 
      jpaApi.em().persist(entity); 
      return entity; 
     }); 
    } 

    public CompletionStage<Optional<E>> findById(String id) { 
     return CompletableFuture.supplyAsync(() -> Optional.ofNullable(jpaApi.em().find(entityClazz, id)) 
     ); 
    } 


    public void deleteById(String id) { 
     findById(id).thenApply(
       result -> result.ifPresent(
         //HERE IS WHERE MY IDE COMPLAINTS 
         entity -> { 
          entity.setActive(false); 
          save(entity); 
         } 

       ) 
     ); 
    } 
} 

Любая помощь или предложение будет оценено.

ответ

1

Просто, чтобы понять, почему произошла ошибка

  • Optional.ifPresent() принимает Потребитель, который возвращает void
  • CompletionStage.thenApply() занимает Function<T, U>. Тип возврата U должен соответствовать типу возврата тела лямбда - в этом случае Optional.ifPresent().
  • void является примитивным типом и не имеет эквивалента в штучной упаковке, поэтому компилятор имеет тупик.

Единственное, что вы могли бы сделать, это преобразовать выражение lambda в блок лямбда, который возвращает какое-то значение. , например.

findById(id).thenApply(
      result -> { 
         result.ifPresent(
          entity -> { 
           entity.setActive(false); 
           save(entity); 
          } 
         ); 
         return 1; 
        } 
    ); 

Это должно позволить компилятору связать типы - thenApply() будет принимать Function возвращающий Integer, в то время как ifPresent() все еще в состоянии принять Consumer возвращающегося пустоту.

В качестве альтернативы, и, вероятно, предпочтительно, можно использовать метод thenAccept() на CompletionStage(), который принимает Consumer, а не Function ...

findById(id).thenAccept(
      result -> result.ifPresent(
        entity -> { 
         entity.setActive(false); 
         save(entity); 
        } 
      ) 
    ); 
+0

Спасибо за хорошее объяснение. – DonkeyKong

Смежные вопросы