当我的查询在ResultSet
内返回null或零结果时,我遇到了问题。
我有int-jdbc:inbound-channel-adapter
rowMapper
<int-jdbc:inbound-channel-adapter query="SELECT * FROM ENGINE_LOGS WHERE COUNTRY_ID = 2 AND BUSINESS_ID = 100 and rownum < 10"
channel="oracle.db.resultSet.engineLogs"
update=""
row-mapper="engineLogsRowMapper"
data-source="jdbcTemplate">
<!-- Cron Time -->
<int:poller fixed-rate="5" time-unit="SECONDS"></int:poller>
</int-jdbc:inbound-channel-adapter>`
当查询返回null o zero(0)结果时,行映射器类或变换器(带有输入通道:oracle.db.resultSet.engineLogs
)从不调用。
如果查询在数据库中找不到记录,我是否需要在辅助数据库中执行更新,是否可以添加路由器或其他东西来解决我的问题?
此致
答案 0 :(得分:1)
这是对的。使用null
payload
的消息对于消息传递系统没有意义,例如Spring Integration。实际上没有一个现有的消息传递协议支持null
有效负载。
因此,当没有来自底层系统的数据(例如您的JDBC中的JDBC)时,许多result-aware
适配器不执行任何操作是标准行为。
代码如下:
private Object poll() {
List<?> payload = doPoll(this.sqlQueryParameterSource);
if (payload.size() < 1) {
payload = null;
}
if (payload != null && updateSql != null) {
if (this.updatePerRow) {
for (Object row : payload) {
executeUpdateQuery(row);
}
}
else {
executeUpdateQuery(payload);
}
}
return payload;
}
如您所见update
为空时无法访问ResultSet
。
有一个钩子可以满足您的要求。可以使用<poller>
配置<advice-chain>
,其中和建议适用于Callable<Boolean>.call()
中的AbstractPollingEndpoint
方法。在该自定义MethodInterceptor
中,您可以检查invocation.proceed()
的结果,如果基础true
(在我们的情况下为MessageSource
)返回数据,则为JdbcPollingChannelAdapter
使用false
结果,你真的可以在辅助数据库中执行UPDATE
。
顺便说一下,我们有一个开放的issue来支持null
个有效负载。我对解决方案有一个想法,使用Java 8的Optional<?>
,它可以被转换为目标对象,用于下游POJO服务激活器,变换器,分离器等。
随意添加任何评论!
<强>更新强>
如何实现此类com.service.ValidateResultAdvice?
public class ValidateResultAdvice implements MethodInterceptor {
private JdbcTemplate jdbcTemplate;
public Object invoke(MethodInvocation invocation) throws Throwable {
Boolean result = (Boolean) invocation.proceed();
if (!result) {
this.jdbcTemplate.update(...);
}
return result;
}
}
类似的东西。
答案 1 :(得分:0)
我处于类似情况,在空结果集上我需要停止相同的jdbc端点,所以这是一个使用Spring Integration 5的示例。
Spring上下文配置:
<int-jdbc:inbound-channel-adapter role="jdbc-endpoint" auto-startup="false"
data-source="dbDataSource" channel="resultSetsIn"
query="SELECT ... FROM ... WHERE ..."
update="UPDATE ... SET ... WHERE id IN (:id)"
max-rows-per-poll="1">
<int:poller fixed-rate="5000">
<int:advice-chain>
<bean class="services.EmptySourceService" />
</int:advice-chain>
</int:poller>
</int-jdbc:inbound-channel-adapter>
建议实施:
package services;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.aop.AbstractMessageSourceAdvice;
import org.springframework.integration.core.MessageSource;
import org.springframework.integration.support.SmartLifecycleRoleController;
import org.springframework.messaging.Message;
public class EmptySourceService extends AbstractMessageSourceAdvice {
@Autowired
private SmartLifecycleRoleController roleController;
@Override
public boolean beforeReceive(MessageSource<?> source) {
return true;
}
@Override
public Message<?> afterReceive(Message<?> result, MessageSource<?> source) {
if(result == null) {
// empty query result logic
roleController.stopLifecyclesInRole("jdbc-endpoint");
}
return result;
}
}
端点停止按照Endpoint roles中的说明完成。