I am working with SpringBatch and JPARepository. I have 2 Connections DB2 & Postgres. I need to switch the DataSources inside a JpaRepository
So, to hold the DataSource Context, I followed the link : [AbstractRoutingDataSource][1] So here below is the code
public class ClientDatabaseContextHolder {
private static ThreadLocal<ClientDatabase> CONTEXT
= new ThreadLocal<>();
public static void set(ClientDatabase clientDatabase) {
Assert.notNull(clientDatabase, "clientDatabase cannot be null");
CONTEXT.set(clientDatabase);
}
public static ClientDatabase getClientDatabase() {
return CONTEXT.get();
}
public static void clear() {
CONTEXT.remove();
}
}
Then, In my RepositoryItemReader I want to set to My 1st DataSource Client
@Component
public class ClientReader extends RepositoryItemReader<Client> {
public ClientReader(final ClientModelsRepository clientRepository) {
DataSourceContextHolder.set("client"); // <===== SET HERE MY 1st Datasource
this.setRepository(clientRepository);
this.setMethodName("findAllWithFriends");
this.setSort(new HashMap<>());
this.setPageSize(5000);
}
}
Then In my JPARepository, I would like to change the DataSource to the 2nd.
@Transactional(Transactional.TxType.NOT_SUPPORTED)
default Page<Client> findAllWithFriends(final Pageable pageable) {
final Page<Client> clients = this.findAll(pageable);
if (clients.hasContent()) {
DataSourceContextHolder.set("friends"); // <== I WANT TO CHANGE THE DATASOURCE THERE
final List<Friend> friends = AppContext.getBean(FriendRepository.class).findByClientCodeIn(clientStringList);
clients.getContent().forEach(c -> { c.setFriends(friends); });
}
return clients;
}
My question is how to change of datasource when reading a chunck. I dont think it is possible to set 2 different datasources and methods in the ClientReader. I have also tried to set the 2nd datasource inside the FriendRepository.class but it doesn't work too. I don't want to do it in the Processor because I want to get all friends matching for the 5000 Client codes. Do you have any ideas ? [1]: https://www.baeldung.com/spring-abstract-routing-data-source
we finally found that :
@Transactional(Transactional.TxType.REQUIRES_NEW) List findByClientCodeIn(List codes);
REQUIRES_NEW creates new transactions every time the method is called