我有一个小的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();
}
}
答案 0 :(得分:0)
对于$document.bind('click', function(event))
功能,JpaPollingChannelAdapter
具有JpaExecutor
选项。
您可以使用实体类上的Hibernate deleteAfterPoll
覆盖默认DELETE
自定义UPDATE
。
或者是的,您可以在同一个轮询事务中以单向方式使用@SQLDelete
进行JpaOutboundGateway
操作。但在这种情况下,它必须是merge
,而不是fixedDelay
不重叠任务,不要在并行线程中轮询相同的数据。