Java 使用@Async会引发org.springframework.aop.aop异常

Java 使用@Async会引发org.springframework.aop.aop异常,java,spring,asynchronous,Java,Spring,Asynchronous,我有一个方法,在DB中一个接一个地将数据保存在多个表中。该方法用@Async注释。此方法依次调用另一个DAO类,该类实际将数据存储在DB中 问题是数据确实成功地存储在数据库中的所有表中,但我在服务器日志中看到以下异常 例外情况: org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: public long com

我有一个方法,在DB中一个接一个地将数据保存在多个表中。该方法用
@Async
注释。此方法依次调用另一个
DAO
类,该类实际将数据存储在DB中

问题是数据确实成功地存储在数据库中的所有表中,但我在服务器日志中看到以下异常

例外情况:

org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: public long com.ebayenterprise.publicapi.events.service.EventLogService.saveEventData(int,java.lang.String,java.lang.String,java.sql.Timestamp,java.sql.Timestamp,java.lang.String)
        at org.springframework.aop.framework.CglibAopProxy.processReturnType(CglibAopProxy.java:351)
        at org.springframework.aop.framework.CglibAopProxy.access$000(CglibAopProxy.java:83)
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:646)
        at com.ebayenterprise.publicapi.events.service.EventLogService$$EnhancerBySpringCGLIB$$b06a3b16.saveEventData(<generated>)
        at com.ebayenterprise.publicapi.events.PublicApiMessageHandler.logEventData(PublicApiMessageHandler.java:91)
        at com.ebayenterprise.publicapi.events.PublicApiMessageHandler.handleMessage(PublicApiMessageHandler.java:80)
        at com.ebayenterprise.publicapi.events.jms.MessageHandler.onMessage(MessageHandler.java:30)
        at com.ebayenterprise.publicapi.events.jms.MessageListenerContainer.onMessage(MessageListenerContainer.java:54)
        at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:562)
        at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:500)
        at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:468)
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:325)
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1102)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1094)
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:991)
        at java.lang.Thread.run(Thread.java:745)
EventLogService.java

  if (eventDBLoggingEnabled) {
                long eventId = 0L;
                try {
                    logger.info("Saving event data in DB now........");
                    eventId =  eventLogService.saveEventData(routeId, incomingEventMessage, outgoingEventMessage, 
            incomingEventTimestamp, outgoingEventTimestamp, userId);
                } catch (Exception e) {
                    logger.error("Some error occured while storing data in event log tables for eventId: "
                            + eventId + " - " + e.getMessage(), e);
                }
            }
   @Async
public long saveEventData(int routeId, String incomingEventMessage, String outgoingEventMessage,
        Timestamp incomingEventTimestamp, Timestamp outgoingEventTimestamp, String userId) throws SQLException {
    String orderId = GenericUtil.extractOrderId(incomingEventMessage);
    EventType eventType = buildEventTypeData(incomingEventMessage);
    EventLog eventLog = eventBuilderService.buildEvent(eventType, routeId, orderId,
            incomingEventMessage, outgoingEventMessage, incomingEventTimestamp, outgoingEventTimestamp);
    long eventId = eventLogDao.save(eventLog, userId);
    if (eventId == 0L) {
        throw new RuntimeException(ERROR_MSG);
    }
    return eventId;
}
@Repository
public class EventLogDao extends BaseEventLogDao {

    public EventLogDao(DataSource dataSource, PlatformTransactionManager transactionManager) {
        super(dataSource, transactionManager);
    }

    public long save(EventLog eventLog, String userId) {
        TransactionDefinition txDef = new DefaultTransactionDefinition();
        TransactionStatus txStatus = transactionManager.getTransaction(txDef);
        long eventId = 0L;
        try {
            eventId = getNextEventIdSequence();
            saveEventLogData(eventId, eventLog);
            saveEventLogMessageData(eventId, eventLog.getEventLogMessage());
            saveEventLogAuditData(eventId, userId, eventLog.getOutgoingEventTimestamp());
            transactionManager.commit(txStatus);
            return eventId;
        } catch (TransactionException ex) {
            transactionManager.rollback(txStatus);
            throw new RuntimeException("Error occurred during tx management in event log tables...", ex);
        }
    }

}
public abstract class BaseEventLogDao {

    protected final JdbcTemplate jdbcTemplate;
    protected final PlatformTransactionManager transactionManager;

    public BaseEventLogDao(DataSource dataSource, PlatformTransactionManager transactionManager) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
        this.transactionManager = transactionManager;
    }

    public void saveEventLogData(long eventId, EventLog eventLog) {
        Object[] parameters = {eventId, eventLog.getRouteId(), eventLog.getEventType().getEventTypeId(),
            eventLog.getOrderId(), eventLog.getIncomingEventTimestamp(), eventLog.getOutgoingEventTimestamp()};
        int[] types = {Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.TIMESTAMP, Types.TIMESTAMP};
        int rowsAffected = jdbcTemplate.update(INSERT_EVENT_LOG_SQL, parameters, types);
    }

    public int saveEventLogMessageData(long eventId, EventLogMessage eventLogMessage) {
        Object[] parameters = {eventId, eventLogMessage.getIncomingEventMessage(), eventLogMessage.getOutgoingEventMessage()};
        int[] types = {Types.INTEGER, Types.VARCHAR, Types.VARCHAR};
        int rowsAffected = jdbcTemplate.update(EventLogConstants.INSERT_EVENT_LOG_MESSAGE_SQL, parameters, types);
        return rowsAffected;
    }

    public int saveEventLogAuditData(long eventId, String userId, Timestamp outgoingEventTimestamp) {
        long eventAuditId = getNextEventAuditIdSequence();
        Object[] parameters = {eventAuditId, eventId, userId, outgoingEventTimestamp};
        int[] types = {Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.TIMESTAMP};
        int rowsAffected = jdbcTemplate.update(INSERT_EVENT_LOG_AUDIT_SQL, parameters, types);
        return rowsAffected;
    }

    public long getNextEventIdSequence() {
        return jdbcTemplate.queryForLong(SELECT_EVENT_LOG_SEQUENCE_SQL);
    }

    public long getNextEventAuditIdSequence() {
        return jdbcTemplate.queryForLong(SELECT_EVENT_LOG_AUDIT_SEQUENCE_SQL);
    }

    public List<EventLog> getEventLogDetails() {
        return jdbcTemplate.query(SELECT_EVENT_LOG_SQL, new BaseEventLogDao.EventLogRowMapper());
    }

   //extra code removed for brevity
}
EventLogDao.java

  if (eventDBLoggingEnabled) {
                long eventId = 0L;
                try {
                    logger.info("Saving event data in DB now........");
                    eventId =  eventLogService.saveEventData(routeId, incomingEventMessage, outgoingEventMessage, 
            incomingEventTimestamp, outgoingEventTimestamp, userId);
                } catch (Exception e) {
                    logger.error("Some error occured while storing data in event log tables for eventId: "
                            + eventId + " - " + e.getMessage(), e);
                }
            }
   @Async
public long saveEventData(int routeId, String incomingEventMessage, String outgoingEventMessage,
        Timestamp incomingEventTimestamp, Timestamp outgoingEventTimestamp, String userId) throws SQLException {
    String orderId = GenericUtil.extractOrderId(incomingEventMessage);
    EventType eventType = buildEventTypeData(incomingEventMessage);
    EventLog eventLog = eventBuilderService.buildEvent(eventType, routeId, orderId,
            incomingEventMessage, outgoingEventMessage, incomingEventTimestamp, outgoingEventTimestamp);
    long eventId = eventLogDao.save(eventLog, userId);
    if (eventId == 0L) {
        throw new RuntimeException(ERROR_MSG);
    }
    return eventId;
}
@Repository
public class EventLogDao extends BaseEventLogDao {

    public EventLogDao(DataSource dataSource, PlatformTransactionManager transactionManager) {
        super(dataSource, transactionManager);
    }

    public long save(EventLog eventLog, String userId) {
        TransactionDefinition txDef = new DefaultTransactionDefinition();
        TransactionStatus txStatus = transactionManager.getTransaction(txDef);
        long eventId = 0L;
        try {
            eventId = getNextEventIdSequence();
            saveEventLogData(eventId, eventLog);
            saveEventLogMessageData(eventId, eventLog.getEventLogMessage());
            saveEventLogAuditData(eventId, userId, eventLog.getOutgoingEventTimestamp());
            transactionManager.commit(txStatus);
            return eventId;
        } catch (TransactionException ex) {
            transactionManager.rollback(txStatus);
            throw new RuntimeException("Error occurred during tx management in event log tables...", ex);
        }
    }

}
public abstract class BaseEventLogDao {

    protected final JdbcTemplate jdbcTemplate;
    protected final PlatformTransactionManager transactionManager;

    public BaseEventLogDao(DataSource dataSource, PlatformTransactionManager transactionManager) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
        this.transactionManager = transactionManager;
    }

    public void saveEventLogData(long eventId, EventLog eventLog) {
        Object[] parameters = {eventId, eventLog.getRouteId(), eventLog.getEventType().getEventTypeId(),
            eventLog.getOrderId(), eventLog.getIncomingEventTimestamp(), eventLog.getOutgoingEventTimestamp()};
        int[] types = {Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.TIMESTAMP, Types.TIMESTAMP};
        int rowsAffected = jdbcTemplate.update(INSERT_EVENT_LOG_SQL, parameters, types);
    }

    public int saveEventLogMessageData(long eventId, EventLogMessage eventLogMessage) {
        Object[] parameters = {eventId, eventLogMessage.getIncomingEventMessage(), eventLogMessage.getOutgoingEventMessage()};
        int[] types = {Types.INTEGER, Types.VARCHAR, Types.VARCHAR};
        int rowsAffected = jdbcTemplate.update(EventLogConstants.INSERT_EVENT_LOG_MESSAGE_SQL, parameters, types);
        return rowsAffected;
    }

    public int saveEventLogAuditData(long eventId, String userId, Timestamp outgoingEventTimestamp) {
        long eventAuditId = getNextEventAuditIdSequence();
        Object[] parameters = {eventAuditId, eventId, userId, outgoingEventTimestamp};
        int[] types = {Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.TIMESTAMP};
        int rowsAffected = jdbcTemplate.update(INSERT_EVENT_LOG_AUDIT_SQL, parameters, types);
        return rowsAffected;
    }

    public long getNextEventIdSequence() {
        return jdbcTemplate.queryForLong(SELECT_EVENT_LOG_SEQUENCE_SQL);
    }

    public long getNextEventAuditIdSequence() {
        return jdbcTemplate.queryForLong(SELECT_EVENT_LOG_AUDIT_SEQUENCE_SQL);
    }

    public List<EventLog> getEventLogDetails() {
        return jdbcTemplate.query(SELECT_EVENT_LOG_SQL, new BaseEventLogDao.EventLogRowMapper());
    }

   //extra code removed for brevity
}
BaseEventLogDao.java

  if (eventDBLoggingEnabled) {
                long eventId = 0L;
                try {
                    logger.info("Saving event data in DB now........");
                    eventId =  eventLogService.saveEventData(routeId, incomingEventMessage, outgoingEventMessage, 
            incomingEventTimestamp, outgoingEventTimestamp, userId);
                } catch (Exception e) {
                    logger.error("Some error occured while storing data in event log tables for eventId: "
                            + eventId + " - " + e.getMessage(), e);
                }
            }
   @Async
public long saveEventData(int routeId, String incomingEventMessage, String outgoingEventMessage,
        Timestamp incomingEventTimestamp, Timestamp outgoingEventTimestamp, String userId) throws SQLException {
    String orderId = GenericUtil.extractOrderId(incomingEventMessage);
    EventType eventType = buildEventTypeData(incomingEventMessage);
    EventLog eventLog = eventBuilderService.buildEvent(eventType, routeId, orderId,
            incomingEventMessage, outgoingEventMessage, incomingEventTimestamp, outgoingEventTimestamp);
    long eventId = eventLogDao.save(eventLog, userId);
    if (eventId == 0L) {
        throw new RuntimeException(ERROR_MSG);
    }
    return eventId;
}
@Repository
public class EventLogDao extends BaseEventLogDao {

    public EventLogDao(DataSource dataSource, PlatformTransactionManager transactionManager) {
        super(dataSource, transactionManager);
    }

    public long save(EventLog eventLog, String userId) {
        TransactionDefinition txDef = new DefaultTransactionDefinition();
        TransactionStatus txStatus = transactionManager.getTransaction(txDef);
        long eventId = 0L;
        try {
            eventId = getNextEventIdSequence();
            saveEventLogData(eventId, eventLog);
            saveEventLogMessageData(eventId, eventLog.getEventLogMessage());
            saveEventLogAuditData(eventId, userId, eventLog.getOutgoingEventTimestamp());
            transactionManager.commit(txStatus);
            return eventId;
        } catch (TransactionException ex) {
            transactionManager.rollback(txStatus);
            throw new RuntimeException("Error occurred during tx management in event log tables...", ex);
        }
    }

}
public abstract class BaseEventLogDao {

    protected final JdbcTemplate jdbcTemplate;
    protected final PlatformTransactionManager transactionManager;

    public BaseEventLogDao(DataSource dataSource, PlatformTransactionManager transactionManager) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
        this.transactionManager = transactionManager;
    }

    public void saveEventLogData(long eventId, EventLog eventLog) {
        Object[] parameters = {eventId, eventLog.getRouteId(), eventLog.getEventType().getEventTypeId(),
            eventLog.getOrderId(), eventLog.getIncomingEventTimestamp(), eventLog.getOutgoingEventTimestamp()};
        int[] types = {Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.TIMESTAMP, Types.TIMESTAMP};
        int rowsAffected = jdbcTemplate.update(INSERT_EVENT_LOG_SQL, parameters, types);
    }

    public int saveEventLogMessageData(long eventId, EventLogMessage eventLogMessage) {
        Object[] parameters = {eventId, eventLogMessage.getIncomingEventMessage(), eventLogMessage.getOutgoingEventMessage()};
        int[] types = {Types.INTEGER, Types.VARCHAR, Types.VARCHAR};
        int rowsAffected = jdbcTemplate.update(EventLogConstants.INSERT_EVENT_LOG_MESSAGE_SQL, parameters, types);
        return rowsAffected;
    }

    public int saveEventLogAuditData(long eventId, String userId, Timestamp outgoingEventTimestamp) {
        long eventAuditId = getNextEventAuditIdSequence();
        Object[] parameters = {eventAuditId, eventId, userId, outgoingEventTimestamp};
        int[] types = {Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.TIMESTAMP};
        int rowsAffected = jdbcTemplate.update(INSERT_EVENT_LOG_AUDIT_SQL, parameters, types);
        return rowsAffected;
    }

    public long getNextEventIdSequence() {
        return jdbcTemplate.queryForLong(SELECT_EVENT_LOG_SEQUENCE_SQL);
    }

    public long getNextEventAuditIdSequence() {
        return jdbcTemplate.queryForLong(SELECT_EVENT_LOG_AUDIT_SEQUENCE_SQL);
    }

    public List<EventLog> getEventLogDetails() {
        return jdbcTemplate.query(SELECT_EVENT_LOG_SQL, new BaseEventLogDao.EventLogRowMapper());
    }

   //extra code removed for brevity
}
公共抽象类BaseEventLogDao{
受保护的最终JdbcTemplate JdbcTemplate;
受保护的最终平台transactionManager transactionManager;
public BaseEventLogDao(数据源数据源平台transactionManager transactionManager){
this.jdbcTemplate=新的jdbcTemplate(数据源);
this.transactionManager=transactionManager;
}
public void saveEventLogData(长事件ID、事件日志事件日志){
Object[]参数={eventId,eventLog.getRouteId(),eventLog.getEventType().getEventTypeId(),
eventLog.getOrderId(),eventLog.getIncomingEventTimestamp(),eventLog.getOutgoingEventTimestamp()};
int[]types={types.INTEGER,types.INTEGER,types.VARCHAR,types.TIMESTAMP,types.TIMESTAMP};
int rowsAffected=jdbcTemplate.update(插入事件日志SQL、参数、类型);
}
public int saveEventLogMessageData(长eventId、EventLogMessage EventLogMessage){
Object[]参数={eventId,eventLogMessage.getIncomingEventMessage(),eventLogMessage.getOutgoingEventMessage()};
int[]types={types.INTEGER,types.VARCHAR,types.VARCHAR};
int rowsAffected=jdbcTemplate.update(EventLogConstants.INSERT\u EVENT\u LOG\u MESSAGE\u SQL、参数、类型);
返回受影响的行;
}
public int saveEventLogAuditData(长事件ID、字符串用户ID、时间戳outgoingEventTimestamp){
long-eventAuditId=getNextEventTauditidSequence();
Object[]参数={eventAudid,eventId,userId,outgoingEventTimestamp};
int[]types={types.INTEGER,types.INTEGER,types.VARCHAR,types.TIMESTAMP};
int rowsAffected=jdbcTemplate.update(插入事件、日志、审计、SQL、参数、类型);
返回受影响的行;
}
公共长GetNextEventdSequence(){
返回jdbcTemplate.queryForLong(选择\事件\日志\序列\ SQL);
}
公共长GetNextEventTauditidSequence(){
返回jdbcTemplate.queryForLong(选择事件、日志、审计、序列、SQL);
}
公共列表getEventLogDetails(){
返回jdbcTemplate.query(选择事件日志SQL,新建BaseEventLogDao.EventLogRowMapper());
}
//为简洁起见,删除了额外代码
}

找到问题并修复。这是因为没有使用Java7中可用的
Future
特性和具有返回类型的方法。从这篇文章中找到了解决方案()

我的变化如下所述

PublicApiMessageHandler.java(已更新)

if(eventDBLoggingEnabled){
长事件ID=0L;
试一试{
logger.info(“立即将事件数据保存在DB中……”;
eventId=logEventData(route.getRouteId()、消息、transformedMessage、incomingEventTimestamp、,
outgoingEventTimestamp,默认用户ID);
}捕获(例外e){
logger.error(“在eventId的事件日志表中存储数据时发生了一些错误:”
+eventId+“-”+e.getMessage(),e);
errorAlertService.sendAlert(e,路由,消息,Alert.AlertType.ERROR_500);
}
}
}
返回MessageHandler.Status.OK;
}
专用长logEventData(int routeId、字符串incomingEventMessage、字符串outgoingEventMessage、,
时间戳incomingEventTimestamp,时间戳outgoingEventTimestamp,字符串userId)
抛出SQLException,异常{
长事件ID=0L;
Future Future=eventLogService.saveEventData(routeId、incomingEventMessage、outgoingEventMessage、,
输入事件时间戳、输出事件时间戳、用户ID);
while(true){
if(future.isDone()){
eventId=future.get();
打破
}
}
返回事件ID;
}
EventLogService.java(已更新)

@Async
public Future saveEventData(int routeId、字符串incomingEventMessage、字符串outgoingEventMessage、,
Timestamp incomingEventTimestamp,Timestamp outgoingEventTimestamp,String userId)抛出SQLException{
String orderId=GenericUtil.extractOrderId(incomingEventMessage);
EventType EventType=buildEventTypeData(incomingEventMessage);
EventLog EventLog=eventBuilderService.buildEvent(eventType、routeId、orderId、,
incomingEventMessage、outgoingEventMessage、incomingEventTimestamp、outgoingEventTimestamp);
long eventId=eventLogDao.save(eventLog,userId);
如果(eventId==0L){
抛出新的运行时异常(错误消息);
}
返回新的异步结果(eventId);
}

您知道在哪一行之后引发异常吗?对eventLogService的实际调用是从PublicApiMessageHandler.java类中进行的,并且异常也概述了相同的类。我已经更新了我的原始帖子,添加了PublicApiMessageHandler.java类中的一些代码片段。这是引发异常的位置。您是否尝试调试它?执行是否命中了其中的catch块?是的,它命中了,并且我看到了错误消息:
在eventId:0的事件日志表中存储数据时发生了一些错误-通知中的Null返回值与:public long com.ebayenter的基元返回类型不匹配。。。。。。。。。。。。。。。。