Как передать параметры namedQuery в Apache Camel JPA по заголовку?

У меня есть этот верблюжий маршрут:

from("direct:getUser")
    .pollEnrich("jpa://User?namedQuery=User.findById&consumeDelete=false");

Это мой пользователь

@Entity
@NamedQueries({
    @NamedQuery(name="User.findAll", query="SELECT u FROM User u"),
    @NamedQuery(name="User.findById", query="SELECT u FROM User u WHERE u.id = :id")
})
public class User{
    @Id
    private String id;
}

Я пробовал этот маршрут, установив заголовок:

from("direct:getUser")
    .setHeader("id", simple("myid"))
    .pollEnrich("jpa://User?namedQuery=User.findById&consumeDelete=false");

Но это не работает

Есть ли способ установить свойства jpa по заголовкам? Документация верблюда цитирует это в parameters вариант, но я не нашел примеры

Опции: parameters

Эта опция основана на реестре и требует # обозначения. Это отображение ключ / значение используется для построения параметров запроса. Ожидается, что он будет иметь общий тип java.util.Map, где ключи - это именованные параметры данного запроса JPA, а значения - их соответствующие эффективные значения, для которых вы хотите выбрать. Верблюд 2.19: его можно использовать и для производителя. Когда это используется для производителя, Простое выражение может использоваться как значение параметра. Позволяет извлекать значения параметров из заголовка тела сообщения и т. Д.

1 ответ

Решение

Надеюсь, еще не поздно ответить. В любом случае у меня была похожая проблема в моем проекте, клиент выполняет HTTP GET с параметром id, который используется JPA-запросом, и результат, наконец, передается обратно клиенту HTTP. Я запускаю верблюда в приложении Spring.

Наконец-то я понял, как этого добиться достаточно чистым способом.

Это RouteBuilder где определяется маршрут:

@Override
public void configure() throws Exception {

    Class dataClass = SomeClass.class;
    JacksonDataFormat format = new JacksonDataFormat();
    format.setUnmarshalType(dataClass);

    String jpaString = String
            .format("jpa://%1$s?resultClass=%1$s&namedQuery=q1" +
                    "&parameters={\"id\":${headers.id}}", dataClass.getName());

    from("jetty://http://localhost:8080/test").toD(jpaString) // note the .toD
        .marshal(format)
}

И это StringToMapTypeConverter класс, иначе верблюд не может преобразовать {"id": X} в карту

public class StringToMapTypeConverter implements TypeConverters {

    private static final ObjectMapper mapper = new ObjectMapper();
    private static JavaType mapType;

    static {
        mapType = mapper.getTypeFactory().constructMapType(Map.class,
                String.class, Object.class);
    }

    @Converter
    public Map<String, Object> toMap(String map) throws IOException {
        return mapper.readValue(map, mapType);
    }
}

Не забудьте добавить его в контекст. Весной это что-то вроде:

<bean id="myStringToMapTypeConverter" class="....StringToMapTypeConverter" />

Refs:

Другие вопросы по тегам