JpaPollingChannelAdapter是否具有与JdbcPollingChannelAdapter的UpdateSql类似的功能?

时间:2016-12-08 22:31:25

标签: spring-integration

我有一个小的Spring Boot应用程序,它使用Spring Integration查询Oracle数据库以获取特定状态的记录。

最初,我有一个使用JdbcPollingChannelAdapter的工作POC,它还定义了一个更新语句,它更改了找到的记录的状态,因此不会重新扫描它们。

应用程序使用Hibernate,因此我想用JPA方法替换Jdbc实现。

因此,我成功实现了一个带有JpaExecutor的JpaPollingChannelAdapter,以实体形式检索结果。

我想要实现的是与Jdbc方法类似的行为,它将在与轮询器相同的事务中更新所有找到的记录。

在适配器中是否有正确的方法来实现这一点,还是应该在消息处理程序中使用实体dao?

希望这是有道理的。

更新

查看through the docs我假设我需要使用OutboundChannelAdapter或Gateway(与InboundChannelAdapter相比,因为它仅用于检索)。

我想我的问题就变成如何正确连接,如果我可以在单个处理程序中完成所有操作,或者我需要定义多个通道,1检索,另一个更新实体状态。

以下是一些基本代码:

@Configuration
public class IntegrationConfiguration {

    private final Log log = LogFactory.getLog(getClass());

    @Autowired
    private DataSource dataSource;

    @Autowired
    private EntityManager entityManager;

    @Autowired
    private Reactor rootReactor;

    @Autowired
    private RunDao runDao;

    @Bean
    @InboundChannelAdapter(channel = "notificationChannel", poller = @Poller(fixedDelay = "60000", maxMessagesPerPoll = "-1"))
    public MessageSource<?> jpaMessageSource() {
        return new JpaPollingChannelAdapter(jpaSelectExecutor());
    }

    @Bean
    @Gateway(requestChannel = "notificationChannel")
    public void updateMessageStatus() {
        JpaOutboundGateway gateway = new JpaOutboundGateway(jpaUpdateExecutor());
        gateway.setGatewayType(OutboundGatewayType.UPDATING);
    }

    @Bean
    public JpaExecutor jpaSelectExecutor() {
        JpaExecutor executor = new JpaExecutor(this.entityManager);
        executor.setJpaQuery("select R from Run R where R.notificationStatus = 'NOT_SENT' and R.runStatus.status = 'COMPLETE' and R.runConfig.notificationRecipients is not null");
        executor.setEntityClass(Run.class);
        return executor;
    }

    @Bean
    public JpaExecutor jpaUpdateExecutor() {
        JpaExecutor executor = new JpaExecutor(this.entityManager);
        executor.setJpaQuery("update Run R set R.notificationStatus = 'SENDING' where R.RunId = :RunId");
        executor.setEntityClass(Run.class);
        return executor;
    }

    @Bean
    @ServiceActivator(inputChannel = "notificationChannel")
    public MessageHandler jpaMessageHandler() {
        MessageHandler handler = new MessageHandler() {
            @Override
            public void handleMessage(Message<?> message) throws MessagingException {
                for (Run run : (ArrayList<Run>) message.getPayload()) {
                    rootReactor.notify("send-email-notification", Event.wrap(run));
                    //run.setNotificationStatus(Run.NotificationStatus.SENDING);
                    //runDao.merge(run);
                }
            }
        };

        return handler;
    }

    @Bean
    public IntegrationFlow pollingAdapterFlow() {
        return IntegrationFlows
                .from(jpaMessageSource())
                .handle(jpaMessageHandler())
                .get();
    }
}

1 个答案:

答案 0 :(得分:0)

对于$document.bind('click', function(event))功能,JpaPollingChannelAdapter具有JpaExecutor选项。

您可以使用实体类上的Hibernate deleteAfterPoll覆盖默认DELETE自定义UPDATE

或者是的,您可以在同一个轮询事务中以单向方式使用@SQLDelete进行JpaOutboundGateway操作。但在这种情况下,它必须是merge,而不是fixedDelay不重叠任务,不要在并行线程中轮询相同的数据。