我们遇到的问题仅出现在生产环境中。
RowHandler应该执行大约63行,但它无法处理1到3行。
我们的RowHandler中没有连接/光标关闭。
Caused by: java.sql.SQLException: Result set already closed
at weblogic.jdbc.wrapper.ResultSet.checkResultSet(ResultSet.java:144)
at weblogic.jdbc.wrapper.ResultSet.preInvocationHandler(ResultSet.java:97)
at weblogic.jdbc.wrapper.ResultSet_oracle_jdbc_driver_OracleResultSetImpl.next(Unknown Source)
at com.ibatis.sqlmap.engine.execution.SqlExecutor.handleResults(SqlExecutor.java:383)
at com.ibatis.sqlmap.engine.execution.SqlExecutor.handleMultipleResults(SqlExecutor.java:300)
at com.ibatis.sqlmap.engine.execution.SqlExecutor.executeQuery(SqlExecutor.java:189)
at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.sqlExecuteQuery(MappedStatement.java:222)
at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryWithCallback(MappedStatement.java:191)
at com.ibatis.sqlmap.engine.mapping.statement.MappedStatement.executeQueryWithRowHandler(MappedStatement.java:149)
at com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate.queryWithRowHandler(SqlMapExecutorDelegate.java:601)
at com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl.queryWithRowHandler(SqlMapSessionImpl.java:157)
at com.ibatis.sqlmap.engine.impl.SqlMapClientImpl.queryWithRowHandler(SqlMapClientImpl.java:133)
我的RowHandler看起来像:
public class CustomerRowHandler extends AbstractRowHandler {
private UserContextTiny userCtx;
private MarketingActionData mrkData;
private TaskManager taskManager;
private Logger logger = new Logger(getClass());
public CustomerRowHandler(UserContextTiny userCtx, TaskData task, MarketingActionData mrkData) {
this.userCtx = userCtx;
this.mrkData = mrkData;
this.taskManager = new TaskManager(task.getId());
}
public void handleRow(Object valueObject) {
String methodName = "handleRow";
MarketingPersonalData recipient = (MarketingPersonalData)valueObject;
try {
MarketingActionDataSource ds = new MarketingActionDataSource();
Account account = recipient.getAccount();
Customer customer = recipient.getCustomer();
if (account != null) {
Long tierId = AccountDAO.getInstance().getAccountTier(account.getAccId(), DateTimeProvider.getInstance().getCurrentDate());
DictionaryObject tier = (DictionaryObject) CLMCacheHolder.getGlobal().getRegion(EJBCacheRegions.TIERS).getElement(tierId);
account.setAccTierCode(tier.getCode());
account.setAccTierName(tier.getName().getValue(customer.getCusLngCode()));
account.setTierId(tierId);
}
ds.setAccountData(account);
ds.setCustomerData(customer);
ds.setProspectData(recipient.getProspect());
GeneratedMessageData genMsg = MessageProcessor.generateMessage(NotificationTemplateData.Type.MARKETING_ACTION, recipient.getCustomer().getCusLngCode(), mrkData.getChnCode(), mrkData.getNtmId(), ds);
SendNotificationData sendDto = new SendNotificationData(genMsg);
sendDto.setMrkId(mrkData.getId());
sendDto.setToCusId(recipient.getCustomer().getCusId());
sendDto.setAdvId(mrkData.getAdvId());
sendDto.setType(CommunicationData.Type.MARKETING_ACTION);
sendDto.setExternalId(CommunicationDAO.generateExternalId(sendDto.getType(), mrkData.getId(), mrkData.getCreateDate()));
if (mrkData.getExpirationDate() != null) {
sendDto.setExpirationDate(new Timestamp(mrkData.getExpirationDate().getTime()));
}
if (mrkData.getSendAfterDate() != null) {
sendDto.setSentAfter(new Timestamp(mrkData.getSendAfterDate().getTime()));
}
if (NotificationTemplateData.Handler.SOAP.equals(genMsg.getNtmHandler()) || NotificationTemplateData.Handler.SYNC.equals(genMsg.getNtmHandler()) || Channels.SMS.equals(mrkData.getChnCode())) {
sendDto.setStatus(CommunicationData.Status.PENDING);
}
sendDto.setChannel(mrkData.getChnCode());
// attach coupons generated in this communication
sendDto.setCoupons(new ArrayList<Long>());
if (ds.isCouponDataAvailable()) {
for (CouponData coupon : ds.getCoupons()) {
sendDto.getCoupons().add(coupon.getId());
}
}
// send notification
notificationManager.sendNotification(userCtx, sendDto, mrkData.isPermissionIgnore(), false, false);
sendCount++;
} catch (ApplicationException e) {
rejectCount++;
logger.info(methodName, "Mailing not sent due to: " + e.getMessage(), e);
taskManager.taskLog("Mailing not sent to customer \"" + recipient.getCustomer().getCusFirstName() + " " + recipient.getCustomer().getCusLastName() + "\" (id: " + recipient.getCustomer().getCusId() + ") due to: " + e.getMessage(), INFO);
} catch (SystemException e) {
rejectCount++;
logger.info(methodName, "Mailing not sent due to: " + e.getMessage(), e);
taskManager.taskLog("Mailing not sent to customer \"" + recipient.getCustomer().getCusFirstName() + " " + recipient.getCustomer().getCusLastName() + "\" (id: " + recipient.getCustomer().getCusId() + ") due to: " + e.getMessage(), INFO);
throw e;
}
}
}
它被用于:
public void selectMarketingPersonalData(UserContextTiny userCtx, Long mrkId, RowHandler rh) {
getSqlMapClientTemplate().queryWithRowHandler("MARKETING_ACTION.selectMarketingPersonalData", mrkId, rh);
}
查询执行的内容:
<select id="selectMarketingPersonalData" parameterClass="java.lang.Long" resultMap="MarketingPersonalDataResultMap">
SELECT ACC_FIRST_ISS_DATE, ACC_FIRST_RED_DATE, ACC_ID, ACC_ISS_POINTS, ACC_LAST_ISS_DATE, ACC_LAST_RED_DATE,
ACC_NO, ACC_NUM_OF_CARDS, ACC_POINTS_BALANCE, ACC_RED_POINTS, ACC_REGISTER_DATE, ACC_STATUS, ACC_TRN_COUNT,
CUS_BIRTH_DATE, PKG_ACCOUNTS.GetCusDynamicEarn(CUS_ID) CUS_DYNAMIC_EARN, CUS_FIRST_NAME, CUS_ID, CUS_LAST_NAME, CUS_LNG_CODE, CUS_PARTICIPANT_ID, CUS_TITLE,
CUS_PERMISSION_EMAIL, CUS_PERMISSION_SMS, CUS_PERMISSION_POST, CUS_PERMISSION_PHONE, CUS_SALUTATION, CUS_DOCUMENT_ID, CUS_DOCUMENT_TYPE,
CUS_CIF_NUMBER, CUS_CST_ID, CUS_BRANCH_NUMBER, CUS_DEPENDENT_NBR, CUS_GENDER, CUS_MARITAL_STATUS, CUS_OPEN_DATE,
CUS_PREF_COM_CHANNEL, CUS_SECOND_NAME, CUS_SEGMENT, CUS_SUB_SEGMENT, CUS_BANK_OFFICER,
ADR_ID, ADR_TYPE, ADR_COUNTRY, ADR_STATE, ADR_CITY, ADR_ZIP_CODE, ADR_STREET_NAME, ADR_STREET_NAME_2, ADR_HOUSE_NO, ADR_HOME_PHONE,
ADR_MOBILE, ADR_EMAIL, ADR_ADDITIONAL_INFO, ADR_POSTAL_BOUNCED_FLAG, ADR_EMAIL_BOUNCED_FLAG, ADR_SCORING,
ADR_SCORING_DATE, ADR_STREET_PREFIX, ADR_FAX, ADR_SECOND_EMAIL, ADR_SECOND_PHONE, ADR_ALTERNATE_PHONE,
ADR_BUSINESS_PHONE, ADR_CITIZENSHIP_CODE,ADR_ADDRESS_1,ADR_ADDRESS_2,ADR_ADDRESS_3,ADR_ADDRESS_4,
ADR_MOBILE_BOUNCED_FLAG, ADR_POSTAL_BOUNCED_REASON, ADR_POSTAL_DATE, ADR_MOBILE_DATE, ADR_EMAIL_DATE,
PPS_ID, PPS_FIRST_NAME, PPS_LAST_NAME, PPS_EMAIL, PPS_DATA_USAGE_FLAG, PPS_PERMISSION_POSTAL,
PPS_SOURCE, PPS_DATE, PPS_TEXT_1, PPS_TEXT_2, PPS_TEXT_3, PPS_TEXT_4, PPS_TEXT_5, PPS_DATE_1, PPS_DATE_2,
PPS_DATE_3, PPS_DATE_4, PPS_DATE_5, PPS_NUMERIC_1, PPS_NUMERIC_2, PPS_NUMERIC_3, PPS_NUMERIC_4, PPS_NUMERIC_5,
PPS_SALUTATION
FROM LCT_MARKETING_ACTION_TMP
LEFT OUTER JOIN LCT_ACCOUNTS ON MAT_ACC_ID = ACC_ID
LEFT OUTER JOIN LCT_CUSTOMERS ON MAT_CUS_ID = CUS_ID
LEFT OUTER JOIN LCT_PROSPECTS ON MAT_PPS_ID = PPS_ID
LEFT OUTER JOIN LCT_ADDRESSES ON MAT_ADR_ID = ADR_ID
WHERE MAT_MRK_ID = #value#
</select>
这个问题可能是什么原因?我们无法在测试环境中重现它。
答案 0 :(得分:-1)
在很多情况下,结果集会自动关闭,就像生成它的Statement对象被关闭,重新执行或用于从多个结果序列中检索下一个结果一样。
有关详细信息,请查看official documentation
如果您可以在问题中提供代码而不是堆栈跟踪,那会更好。