Camel split () с нулевым или пустым списком вызывает неправильную агрегацию - PullRequest
0 голосов
/ 12 марта 2019

Это относится к предыдущему вопросу о реализации split().Я добавил пример приложения на github , который показывает как рабочий сценарий, так и сломанный

enter image description here

Учитывая структуру, подобную:

public class A {
    private List<B> bList;
}

public class B {
    private List<C> cList;
}

И разделить работу, чтобы я мог обработать каждый экземпляр C (и повторить только эту часть в случае сбоя), , затем агрегировать обратно , применяя некоторыебизнес-логика.

    from("{{route.from}}")
        .autoStartup(true)
        .threads(1, 5)
        .setProperty("originalA", body())
        .split(ExpressionBuilder.beanExpression(new ClassSplitter(), "getBList"), new MyAggregationStrategy())
            .streaming()
            .setProperty("originalB", body())
            .split(ExpressionBuilder.beanExpression(new ClassSplitter(), "getCList"), new MyAggregationStrategy())
                .streaming()
                .bean(service)
            .end()
            .bean(service, "updateBWithCResults(${property.originalB}, ${body})")
        .end()
        .bean(service, "updateAWithBResults(${property.originalA}, ${body})")
        .to("seda:out")
    .end();

служба:

@Handler
public C doWork(C c) {
    //..
    return c;
}

@SuppressWarnings("unused")
public A updateAWithBResults(A a, List<B> bResults) {
    a.setBList(bResults);
    for (B b: a.getBList()) {
        for (C c: b.getCList()) {
            // do stuff
        }
    }
    return a;
}

@SuppressWarnings("unused")
public B updateBWithCResults(B b, List<C> cResults) {
    b.setCList(cResults);
    return b;
}

Агрегирование:

@Override
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
    List list;
    if (oldExchange == null) {
        list = new ArrayList<>();
    } else {
        list =  oldExchange.getIn().getBody(ArrayList.class);
    }
    list.add(newExchange.getIn().getBody());
    newExchange.getIn().setBody(list);
    return newExchange;
}

Проблема возникает только при заполнении экземпляра A пустым списком B или пустымC списком.Это можно заметить, когда цикл в updateAWithBResults, где один из циклов будет выбрасывать ClassCastException, в основном экземпляр B как-то сохраняется в list<C>.

java.lang.ClassCastException: класс com.github.paizo.camelsplit.pojo.B не может быть приведен к классу com.github.paizo.camelsplit.pojo.C (com.github.paizo.camelsplit.pojo.B и com.github.paizo.camelsplit.pojo.C находятся в неназванном модуле загрузчика 'app') по адресу com.github.paizo.camelsplit.service.MyService.updateAWithBResults (MyService.java:27) ~ [классы /: нет]

Неисправная строка: for (C c: b.getCList()) {

Как это возможно?Как я могу быть уверен, что заново построю А в конце маршрута?

...