所有。 我是Play Framework的新手,也是一般的异步编程。我已经开始了一个新项目,并且在动作控制器中遇到了问题。据我所知,我在控制器中正确地注入了Http Context,就像这段代码中显示的github上的play-java-ebean-example项目一样:
private final ListBillGroupRepository groupRepository;
private final ListBillExtractDetailRepository extractRepository;
private final FormFactory formFactory;
private final HttpExecutionContext httpExecutionContext;
@Inject
public ListBillGroupController(FormFactory formFactory,
ListBillGroupRepository groupRepository,
ListBillExtractDetailRepository extractRepository,
HttpExecutionContext httpExecutionContext) {
this.extractRepository = extractRepository;
this.groupRepository = groupRepository;
this.formFactory = formFactory;
this.httpExecutionContext = httpExecutionContext;
}
我在同一个控制器中有以下操作代码似乎是问题:
public CompletionStage<Result> editGroup(Long groupId, int page, String sortBy, String order, String filter) {
CompletableFuture<PagedList<ListBillExtractDetail>> pageFuture =
extractRepository.page(groupId, page, 10, sortBy, order, filter).toCompletableFuture();
CompletableFuture<List<BigDecimal>> listFuture =
extractRepository.totals(groupId).toCompletableFuture();
return pageFuture.thenCombine(listFuture, (list, lF) ->
ok(views.html.extractDetailsList.render(list, groupId, sortBy, order, filter))
).thenApplyAsync( result ->
result, httpExecutionContext.current());
}
执行操作时,视图将按预期返回;甚至到了向前和向后滚动记录的程度。大多数情况下,我收到以下错误:
块引用
play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[CompletionException: java.lang.RuntimeException: There is no HTTP Context available from here.]]
我从控制器操作中调用数据库存储库中的以下两个方法:
public CompletionStage<PagedList<ListBillExtractDetail>> page(Long grpId, int page, int pageSize, String sortBy, String order, String filter) {
return supplyAsync(() ->
ebeanServer.find(ListBillExtractDetail.class).where()
.eq("LBWA_ID", grpId)
.ilike("EMP_ID", "%" + filter + "%")
.orderBy(sortBy + " " + order)
.fetch("group")
.setFirstRow(page * pageSize)
.setMaxRows(pageSize)
.findPagedList(), executionContext);
}
public CompletionStage<List<BigDecimal>> totals(Long grpId){
return supplyAsync(() -> {
final String sql = "SELECT SUM(\"EMP_PREM\") AS totalEmployee, SUM(\"EMPLR_CONT\") AS totalEmployer," +
" SUM(\"ACC_PREM\") AS totalPremium FROM \"lbtable\" " +
"WHERE \"LBID\"=" + grpId;
SqlQuery query = Ebean.createSqlQuery(sql);
SqlRow row = query.findOne();
List<BigDecimal> totals = new ArrayList<>();
totals.add(row.getBigDecimal("totalEmployee"));
totals.add(row.getBigDecimal("totalEmployer"));
totals.add(row.getBigDecimal("totalPremium"));
return totals;}, executionContext) ;
}
如果有人想知道,我在此操作中的目标是通过一次数据库调用将分页数据返回到视图,同时通过第二次调用将3个单独列的总和作为money(bigdecimal)总计在表格页脚中返回。 / p>
注意:当我退出第二个调用以返回3个总计列并执行以下操作时,生成的视图没有任何问题:
public CompletionStage<Result> editGroup(Long groupId, int page, String sortBy, String order, String filter) {
// Run a db operation in another thread (using DatabaseExecutionContext)
return extractRepository.page(groupId, page, 10, sortBy, order, filter).thenApplyAsync(list -> {
// This is the HTTP rendering thread context
return ok(views.html.extractDetailsList.render(list, groupId, sortBy, order, filter));
}, httpExecutionContext.current());
}
我的预感是我将两个CompletableFutures合并错误,虽然我不确定它为什么偶尔起作用。任何澄清或指示都将非常感激。