gpt4 book ai didi

java - 您如何使用 Spring Integration 处理 EmptyResultDataAccessException?

转载 作者:行者123 更新时间:2023-11-30 07:58:39 25 4
gpt4 key购买 nike

我有一种情况,在处理输入文件之前,我想检查数据库中是否设置了某些信息。在这种特殊情况下,它是用于处理的客户端名称和参数。如果不设置该信息,则文件导入失败。

在许多 StackOverflow 页面中,用户通过在 Java 代码中捕获由 queryForObject 不返回任何行而生成的 EmptyResultDataAccessException 异常来解决这些异常。

问题是 Spring Integration 在我的代码捕获异常之前就捕获了它,理论上,我无法从任何数量的 EmptyResultDataAccessException 异常中分辨出这个错误,这些异常可能与代码中的其他查询一起抛出。

显示 try...catch with queryForObject 的示例代码段:

    MapSqlParameterSource mapParameters = new MapSqlParameterSource();

// Step 1 check if client exists at all
mapParameters.addValue("clientname", clientName);
try {
clientID = this.namedParameterJdbcTemplate.queryForObject(FIND_BY_NAME, mapParameters, Long.class);
} catch (EmptyResultDataAccessException e) {
SQLException sqle = (SQLException) e.getCause();
logger.debug("No client was found");
logger.debug(sqle.getMessage());
return null;
}

return clientID;

在上面的代码中,没有返回任何行,我想正确处理它(我还没有对那部分进行编码)。相反,永远不会触发 catch block ,而是触发我的通用错误处理程序和关联的错误 channel 。

来自文件 BatchIntegrationConfig.java 的片段:

    @Bean
@ServiceActivator(inputChannel="errorChannel")
public DefaultErrorHandlingServiceActivator errorLauncher(JobLauncher jobLauncher){
logger.debug("====> Default Error Handler <====");
return new DefaultErrorHandlingServiceActivator();
}

来自文件 DefaultErrorHandlingServiceActivator.java 的片段:

public class DefaultErrorHandlingServiceActivator {
@ServiceActivator
public void handleThrowable(Message<Throwable> errorMessage) throws Throwable {
// error handling code should go here
}
}

测试事实:

  1. queryForObject 期望返回一行并将抛出一个否则异常,因此您必须处理异常或使用返回一行的不同查询。
  2. Spring Integration 正在监视异常并在之前捕获它们我自己的代码可以交给他们。

我想做的事情:

  • 捕捉非常具体的情况并将其记录下来,或者让最终用户知道他们需要做什么来解决问题。

根据@Artem 的建议于 2016 年 10 月 26 日编辑:

将我现有的输入 channel 更改为 Spring 提供的处理程序建议:

@Transformer(inputChannel = "memberInputChannel", outputChannel = "commonJobGateway", adviceChain="handleAdvice")  

为通知添加了支持Bean和方法:

    @Bean
ExpressionEvaluatingRequestHandlerAdvice handleAdvice() {
ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
advice.setOnFailureExpression("payload");
advice.setFailureChannel(customErrorChannel());
advice.setReturnFailureExpressionResult(true);
advice.setTrapException(true);
return advice;
}

private QueueChannel customErrorChannel() {
return new DirectChannel();
}

我最初在连接此功能时遇到了一些问题,但最后,我意识到它正在创建另一个 channel ,需要监视错误并进行适当处理。为简单起见,我选择此时不使用其他 channel 。

最佳答案

虽然可能不是最好的解决方案,但我转而检查行数而不是返回实际数据。这样就避免了数据异常。

上面的主要代码移到了:

    MapSqlParameterSource mapParameters = new MapSqlParameterSource();
mapParameters.addValue("clientname", clientName);

// Step 1 check if client exists at all; if exists, continue
// Step 2 check if client enrollment rules are available
if (this.namedParameterJdbcTemplate.queryForObject(COUNT_BY_NAME, mapParameters, Integer.class) == 1) {
if (this.namedParameterJdbcTemplate.queryForObject(CHECK_RULES_BY_NAME, mapParameters, Integer.class) != 1) return null;
} else return null;

return findClientByName(clientName);

然后我在返回到 Spring Batch 中的调用方法时检查数据:

        if (clientID != null) {
logger.info("Found client ID ====> " + clientID);
}
else {
throw new ClientSetupJobExecutionException("Client " +
fileNameParts[1] + " does not exist or is improperly setup in the database.");
}

虽然不需要,但我创建了一个自定义 Java 异常,它在以后的某个时间点可能会有用。

关于java - 您如何使用 Spring Integration 处理 EmptyResultDataAccessException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40246251/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com