2014-09-03 3 views
1

У меня есть интеграция с пружиной int-jpa: retriving-outbound-gateway с использованием запроса jpa. Вставка занимает менее секунды, и чтение строки, которая существует, занимает меньше секунды. Однако, когда я ищу значение, которого нет в БД, или если я ищу пустой БД, запрос занимает больше минуты, чтобы завершить, что вызывает тайм-аут в моем приложении. Я также пробовал собственный запрос и тот же результат. Я выполнил собственный запрос в pgadmin и заработал 17 мс.Производительность JPA на пустом DB

Может ли кто-нибудь пролить свет на это явление для меня? Поток интеграции начинается с шлюза, в котором каждый из crud-действий отображается на конкретный канал. интерфейс службы принимает объект и возвращает сообщение типа.

<int-jpa:retrieving-outbound-gateway id="select-in" 
    entity-manager-factory="entityManagerFactory" request-channel="eselect-in-channel" 
    jpa-query="${db.query.select.in}" expect-single-result="false" > 
    <int-jpa:parameter expression="payload.myKey" name="myKey"/> 
    <int-jpa:parameter expression="payload.myIds" name="myIds"/> 
</int-jpa:retrieving-outbound-gateway> 

вот JPA запрос:

db.query.select=SELECT x FROM MyEntity x WHERE x.myId IN :myIds AND x.myKey = :myKey 

--EDIT--

Приложение находится в стадии разработки, так что все работает на локальном хосте. Размер БД не прошел более 5 или 10 записей в тестировании, которое я сделал до сих пор. Вся БД состоит из одной таблицы с myId и myKey как составной ПК. остальная часть таблицы состоит из временной метки, обозначающей время вставки и type_description типа VARCHAR

- EDIT -

После глядя на AbstractReplyProducingMessageHandler сообщение Handle внутренний метод имеет результат нулевой, поэтому ничего публикуется на выходном канале. В моем случае нет канала вывода/ответа, поэтому пустой список должен быть возвращен вызывающему абоненту, который является моим шлюзом. но поскольку запись не существует, результат равен нулю, и обработчик результата никогда не будет вызван, и вызывающий абонент никогда не будет уведомлен и, наконец, истечет.

if (result != null) { 
     MessageHeaders requestHeaders = message.getHeaders(); 
     this.handleResult(result, requestHeaders); 
    } 
    else if (this.requiresReply) { 
     throw new ReplyRequiredException(message, "No reply produced by handler '" + 
       this.getComponentName() + "', and its 'requiresReply' property is set to true."); 
    } 
    else if (logger.isDebugEnabled()) { 
     logger.debug("handler '" + this + "' produced no reply for request Message: " + message); 
    } 

Я был под впечатлением, что пустой список должен был быть возвращен, когда результаты не были найдены http://forum.spring.io/forum/spring-projects/integration/124469-jpa-retrieving-outbound-gateway-produced-no-reply-when-zero-entities-in-database

+0

Можете ли вы дать дополнительную информацию. например, сколько записей у вас в db, каковы индексы. Отрасль сервера приложений отделена от сервера базы данных (или они находятся на одном сервере) и так далее. – pms

+0

Я предлагаю вам взять дамп потока, пока он «висел» (jstack или visualVM). –

+0

Привет @GaryRussell Вы могли бы прокомментировать ответ ниже? Я бы очень хотел получить ваш вклад. – peekay

ответ

1

Ok так вот мой HACK, чтобы сделать эту работу:

<gateway id="persistence-gateway" 
    service-interface="com.service.JPAService" 
    default-request-timeout="${default.request.timeout}" default-reply-timeout="${default.reply.timeout}" 
    error-channel="jpaErrorChannel"> 
    <method name="executeSelectIn" request-channel="select-in-channel"/> 
</gateway> 

<channel id="select-in-channel" /> 

<int-jpa:retrieving-outbound-gateway id="select-in" 
    entity-manager-factory="entityManagerFactory" request-channel="select-in-channel" 
    jpa-query="${db.query.select.in}" expect-single-result="false" > 
    <int-jpa:parameter expression="payload.myKey" name="myKey"/> 
    <int-jpa:parameter expression="payload.myIds" name="myIds"/> 
</int-jpa:retrieving-outbound-gateway> 

<!-- Error preprocessing --> 
<channel id="jpaErrorChannel" /> 

<payload-type-router id="jpaErrorRouter" 
    input-channel="jpaErrorChannel" 
    default-output-channel="jpaErrorProcessorChannel"> 
    <mapping type="org.springframework.integration.handler.ReplyRequiredException" channel="jpaErrorPassthroughChannel"/> 
</payload-type-router> 

<channel id="jpaErrorPassthroughChannel" /> 

<transformer id="jpaErrorPassthroughTransformer" 
    input-channel="jpaErrorPassthroughChannel" 
    expression="T(java.util.Collections).emptyList()"/> 

и вот запрос jpa:

db.query.select=SELECT x FROM MyEntity x WHERE x.myId IN :myIds AND x.myKey = :myKey 

Я дона Это нравится, но пока это работает. Я считаю, что это ошибка весны AbstractReplyProducingMessageHandler, но я хотел бы знать, что думает Весенний Гуру.

+0

Простейшее обходное решение находится здесь: https://jira.spring.io/browse/INT-3333. И как вы еще не исправлены. Скорее всего, мы поговорим об этом в ближайшее время. –

+0

Спасибо @Artem - еще одна простая работа (в данном случае) - установить «default-reply-timeout =« 0 »на шлюзе и обработать« null »так же, как пустой список. –

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