0
@Bean
public IntegrationFlow reimInvJpaOutbound() {
    return IntegrationFlows
                    .from("reimInvProcessChannel")
                    .handle(reimJpaHandlers.reimStgInsertJpaHandler())
                    .log()
                    .get(); 
}

@Component
@Transactional
public class ReIMJpaHandlers {
Logger logger = LoggerFactory.getLogger(this.getClass()); 

@PersistenceContext
protected EntityManager entityManager;

@Autowired
ReIMHistInvHdrStgRepository histRepo; 

@Autowired
ReIMInvHdrStgRepository stgRepo; 

@Autowired
ReIMErrInvHdrStgRepository errRepo; 

String responseQueryString = "select * from RMS16DEV.TSC_IM_DOC_HEAD_TEMP where error_ind != null"; 

@Bean
public JpaUpdatingOutboundEndpointSpec reimStgInsertJpaHandler() {
    System.out.println("Writing to reim stg");
    return Jpa
        .updatingGateway(entityManager)
        .entityClass(TSC_IM_DOC_HEAD_TEMP.class)
        ; 
}

@Bean
public JpaPollingChannelAdapter reimStgResponseJpaInboundAdapter() {
    return Jpa
            .inboundAdapter(entityManager)
            .nativeQuery(responseQueryString)
            .maxResults(100)
            .get(); 
}
}

But I am getting below error:

javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'merge' call
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:292) ~[spring-orm-5.1.5.RELEASE.jar:5.1.5.RELEASE]
at com.sun.proxy.$Proxy189.merge(Unknown Source) ~[na:na]
Guru
  • 2,739
  • 1
  • 25
  • 27

1 Answers1

1

Your

@Component
@Transactional
public class ReIMJpaHandlers {

doesn't matter for the

@Bean
public JpaUpdatingOutboundEndpointSpec reimStgInsertJpaHandler() {

The last one is a bean and it lives in its own lifecycle and all its method calls are happened already outside of your @Transactional on the ReIMJpaHandlers.

You need to consider to configure a TX manager exactly for the .handle(reimJpaHandlers.reimStgInsertJpaHandler()):

.handle(reimJpaHandlers.reimStgInsertJpaHandler(), e -> e.transactional())

assuming that you have a bean with the transactionManager name.

The @Transactional on the class is applied for the business methods, but not @Bean methods which are called only once when we create a bean.

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • Thanks Artem. Too bad I skipped the basics, but transactionManager seems to be available (auto-configured) in spring boot. Further, for the above handler with e-> e.transactional, how do we handle advice (on success and failure)? – Guru Apr 02 '19 at 16:35
  • You just call `advice()` after `transactional()` and all your advises are going to be invoked within TX. If you need otherwise, then call `transactional()` after `advice()`. – Artem Bilan Apr 02 '19 at 16:42