From 0351baa0dda4904cb1867a3edc6d2f6a14c51b1d Mon Sep 17 00:00:00 2001 From: Viktor Seifert Date: Thu, 27 Apr 2023 18:14:35 +0200 Subject: [PATCH 1/5] RED-6270: Extracted common code into own methods and corrected jdbc-string generation (not all params were concatenated correctly) --- .../v1/processor/utils/jdbc/JDBCUtils.java | 140 +++++++++++------- 1 file changed, 84 insertions(+), 56 deletions(-) diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/utils/jdbc/JDBCUtils.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/utils/jdbc/JDBCUtils.java index 46c3b89fc..124634ffd 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/utils/jdbc/JDBCUtils.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/utils/jdbc/JDBCUtils.java @@ -1,5 +1,10 @@ package com.iqser.red.service.persistence.management.v1.processor.utils.jdbc; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + import com.iqser.red.service.persistence.management.v1.processor.multitenancy.entity.DatabaseConnectionEntity; import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.DatabaseConnection; @@ -8,75 +13,98 @@ import lombok.experimental.UtilityClass; @UtilityClass public class JDBCUtils { + public String buildJdbcUrl(DatabaseConnectionEntity databaseConnectionEntity) { - public String buildJdbcUrl(DatabaseConnectionEntity databaseConnectionEntity){ - StringBuilder sb = new StringBuilder("jdbc:") - .append(databaseConnectionEntity.getDriver()) - .append("://") - .append(databaseConnectionEntity.getHost()) - .append(':') - .append(databaseConnectionEntity.getPort()) - .append('/') - .append(databaseConnectionEntity.getDatabase()); + StringBuilder sb = createJdbcConnectionStringBuilder(databaseConnectionEntity.getDriver(), + databaseConnectionEntity.getHost(), + databaseConnectionEntity.getPort(), + databaseConnectionEntity.getDatabase()); - if(databaseConnectionEntity.getParams() != null) { - sb.append('?'); - databaseConnectionEntity.getParams().forEach((k, v) -> sb.append('&').append(k).append(v)); - } + Map params = getConnectionParameters(databaseConnectionEntity); + appendParams(sb, params); return sb.toString(); } - public String buildJdbcUrl(DatabaseConnection databaseConnection){ - StringBuilder sb = new StringBuilder("jdbc:") - .append(databaseConnection.getDriver()) - .append("://") - .append(databaseConnection.getHost()) - .append(':') - .append(databaseConnection.getPort()) - .append('/') - .append(databaseConnection.getDatabase()); - if(databaseConnection.getParams() != null) { - sb.append('?'); - databaseConnection.getParams().forEach((k, v) -> sb.append('&').append(k).append(v)); - } + private StringBuilder createJdbcConnectionStringBuilder(String driver, String host, String port, String database) { + + return new StringBuilder("jdbc:").append(driver).append("://").append(host).append(':').append(port).append('/').append(database); + } + + + private Map getConnectionParameters(DatabaseConnectionEntity databaseConnectionEntity) { + + var paramsMap = Optional.ofNullable(databaseConnectionEntity.getParams()); + return getParamsWithDefaults(paramsMap); + } + + + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + private Map getParamsWithDefaults(Optional> paramsMap) { + + Map params = paramsMap.orElseGet(HashMap::new); + params.put("reWriteBatchedInserts", "true"); + return params; + } + + + public String buildJdbcUrl(DatabaseConnection databaseConnection) { + + StringBuilder sb = createJdbcConnectionStringBuilder(databaseConnection.getDriver(), + databaseConnection.getHost(), + databaseConnection.getPort(), + databaseConnection.getDatabase()); + Map params = getConnectionParameters(databaseConnection); + appendParams(sb, params); return sb.toString(); } - public String buildJdbcUrlWithSchema(DatabaseConnection databaseConnection){ - StringBuilder sb = new StringBuilder("jdbc:") - .append(databaseConnection.getDriver()) - .append("://") - .append(databaseConnection.getHost()) - .append(':') - .append(databaseConnection.getPort()) - .append('/') - .append(databaseConnection.getDatabase()) - .append('?') - .append("currentSchema=") - .append(databaseConnection.getSchema()); - if(databaseConnection.getParams() != null) { - databaseConnection.getParams().forEach((k, v) -> sb.append('&').append(k).append(v)); + private void appendParams(StringBuilder sb, Map params) { + + if (!params.isEmpty()) { + sb.append("?"); + List paramsAsStrings = params.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()).toList(); + sb.append(String.join("&", paramsAsStrings)); } + } + + + public String buildJdbcUrlWithSchema(DatabaseConnection databaseConnection) { + + return createJdbcConnectionString(databaseConnection.getDriver(), + databaseConnection.getHost(), + databaseConnection.getPort(), + databaseConnection.getDatabase(), + databaseConnection.getSchema(), + getConnectionParameters(databaseConnection)); + } + + + private static String createJdbcConnectionString(String driver, String host, String port, String database, String schema, Map connectionParameters) { + + StringBuilder sb = createJdbcConnectionStringBuilder(driver, host, port, database); + connectionParameters.put("currentSchema", schema); + appendParams(sb, connectionParameters); return sb.toString(); } - public String buildJdbcUrlWithSchema(DatabaseConnectionEntity databaseConnection){ - StringBuilder sb = new StringBuilder("jdbc:") - .append(databaseConnection.getDriver()) - .append("://") - .append(databaseConnection.getHost()) - .append(':') - .append(databaseConnection.getPort()) - .append('/') - .append(databaseConnection.getDatabase()) - .append('?') - .append("currentSchema=") - .append(databaseConnection.getSchema()); - if(databaseConnection.getParams() != null) { - databaseConnection.getParams().forEach((k, v) -> sb.append('&').append(k).append(v)); - } - return sb.toString(); + + private Map getConnectionParameters(DatabaseConnection databaseConnection) { + + var params = Optional.ofNullable(databaseConnection.getParams()); + return getParamsWithDefaults(params); } + + + public String buildJdbcUrlWithSchema(DatabaseConnectionEntity databaseConnection) { + + return createJdbcConnectionString(databaseConnection.getDriver(), + databaseConnection.getHost(), + databaseConnection.getPort(), + databaseConnection.getDatabase(), + databaseConnection.getSchema(), + getConnectionParameters(databaseConnection)); + } + } From dd78b08a779a93460626d89f0ef2d33567964abf Mon Sep 17 00:00:00 2001 From: Viktor Seifert Date: Fri, 28 Apr 2023 14:39:34 +0200 Subject: [PATCH 2/5] RED-6270: Removed default connection value because it had no effect --- .../v1/processor/utils/jdbc/JDBCUtils.java | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/utils/jdbc/JDBCUtils.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/utils/jdbc/JDBCUtils.java index 124634ffd..5aecbbbbd 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/utils/jdbc/JDBCUtils.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/utils/jdbc/JDBCUtils.java @@ -34,17 +34,7 @@ public class JDBCUtils { private Map getConnectionParameters(DatabaseConnectionEntity databaseConnectionEntity) { - var paramsMap = Optional.ofNullable(databaseConnectionEntity.getParams()); - return getParamsWithDefaults(paramsMap); - } - - - @SuppressWarnings("OptionalUsedAsFieldOrParameterType") - private Map getParamsWithDefaults(Optional> paramsMap) { - - Map params = paramsMap.orElseGet(HashMap::new); - params.put("reWriteBatchedInserts", "true"); - return params; + return Optional.ofNullable(databaseConnectionEntity.getParams()).orElseGet(HashMap::new); } @@ -92,8 +82,7 @@ public class JDBCUtils { private Map getConnectionParameters(DatabaseConnection databaseConnection) { - var params = Optional.ofNullable(databaseConnection.getParams()); - return getParamsWithDefaults(params); + return Optional.ofNullable(databaseConnection.getParams()).orElseGet(HashMap::new); } From 080014021b007eb615275863432071bd2145ddff Mon Sep 17 00:00:00 2001 From: Viktor Seifert Date: Fri, 28 Apr 2023 15:33:26 +0200 Subject: [PATCH 3/5] RED-6270: Implemented the adding of dictionary entries via batch updates to improve writing speed --- ...sistenceServiceProcessorConfiguration.java | 12 +++++ .../processor/utils/jdbc/JDBCWriteUtils.java | 44 +++++++------------ .../performance/EntityPerformanceTest.java | 16 +++---- 3 files changed, 35 insertions(+), 37 deletions(-) diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/PersistenceServiceProcessorConfiguration.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/PersistenceServiceProcessorConfiguration.java index 53e4206c8..700d9242b 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/PersistenceServiceProcessorConfiguration.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/PersistenceServiceProcessorConfiguration.java @@ -1,11 +1,16 @@ package com.iqser.red.service.persistence.management.v1.processor; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.support.PageJacksonModule; import org.springframework.cloud.openfeign.support.SortJacksonModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; +import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.retry.backoff.ExponentialBackOffPolicy; import org.springframework.retry.policy.SimpleRetryPolicy; import org.springframework.retry.support.RetryTemplate; @@ -51,4 +56,11 @@ public class PersistenceServiceProcessorConfiguration { return retryTemplate; } + + @Bean + public JdbcTemplate jdbcTemplate(@Qualifier("multiTenantDataSource") @Lazy DataSource dataSource) { + + return new JdbcTemplate(dataSource); + } + } diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/utils/jdbc/JDBCWriteUtils.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/utils/jdbc/JDBCWriteUtils.java index e75bf3a22..8c6449035 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/utils/jdbc/JDBCWriteUtils.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/utils/jdbc/JDBCWriteUtils.java @@ -12,20 +12,13 @@ import java.util.Map; import java.util.stream.Collectors; import javax.persistence.Column; -import javax.persistence.EntityManager; import javax.persistence.Table; import javax.transaction.Transactional; import org.apache.commons.lang3.StringUtils; -import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.datasource.DataSourceUtils; -import org.springframework.jdbc.datasource.SingleConnectionDataSource; import org.springframework.stereotype.Service; -import com.iqser.red.service.persistence.management.v1.processor.service.persistence.mulitenancy.DynamicDataSourceBasedMultiTenantConnectionProvider; -import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext; - import lombok.AllArgsConstructor; import lombok.Data; import lombok.RequiredArgsConstructor; @@ -35,43 +28,26 @@ import lombok.SneakyThrows; @RequiredArgsConstructor public class JDBCWriteUtils { - private final String SQL_TEMPLATE = "INSERT INTO %s (%s) values (%s)"; + private static final String SQL_TEMPLATE = "INSERT INTO %s (%s) values (%s)"; private final Map, EntityMetadata> entityMetadataMap = new HashMap<>(); - private final EntityManager entityManager; + private final JdbcTemplate jdbcTemplate; @SneakyThrows @Transactional - public void saveBatch(final List entities) { + public void saveBatch(List entities) { if (entities.isEmpty()) { return; } - var metadata = getEntityMetadata(entities.iterator().next()); + var metadata = getEntityMetadata(entities.get(0)); final int batchSize = 500; - var query = entityManager.createNativeQuery(metadata.getSqlStatement()); - for (int j = 0; j < entities.size(); j += batchSize) { - - final List batchList = entities.subList(j, Math.min(j + batchSize, entities.size())); - - for (var entity : batchList) { - int paramIndex = 1; - for (var mapping : metadata.getFieldMethodMap().entrySet()) { - query.setParameter(paramIndex++, mapping.getValue().invoke(entity)); - } - - query.executeUpdate(); - - } - - } - - entityManager.clear(); + jdbcTemplate.batchUpdate(metadata.getSqlStatement(), entities, batchSize, metadata::setValues); } @@ -144,6 +120,16 @@ public class JDBCWriteUtils { private String sqlStatement; private Map fieldMethodMap; + + @SneakyThrows + public void setValues(PreparedStatement preparedStatement, Object entity) { + + int paramIndex = 1; + for (var mapping : getFieldMethodMap().entrySet()) { + preparedStatement.setObject(paramIndex++, mapping.getValue().invoke(entity)); + } + } + } } diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/performance/EntityPerformanceTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/performance/EntityPerformanceTest.java index c5d5931a6..c80ec4019 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/performance/EntityPerformanceTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/performance/EntityPerformanceTest.java @@ -101,33 +101,33 @@ public class EntityPerformanceTest extends AbstractPersistenceServerServiceTest @Test public void testWritePerformance() { - var tenKEntries = generateEntries(10_000); + final int numberOfEntries = 10_000; + var entries = generateEntries(numberOfEntries); var template = dossierTemplateTesterAndProvider.provideTestTemplate("test"); var type1 = typeProvider.testAndProvideType(template, null, "t1"); var type2 = typeProvider.testAndProvideType(template, null, "t2"); - List type1Entries = tenKEntries.stream().map(s -> new DictionaryEntryEntity(0, s, 1, false, type1.getTypeId())).collect(Collectors.toList()); + List type1Entries = entries.stream().map(s -> new DictionaryEntryEntity(0, s, 1, false, type1.getTypeId())).collect(Collectors.toList()); - List type2Entries = tenKEntries.stream().map(s -> new DictionaryEntryEntity(0, s, 1, false, type2.getTypeId())).collect(Collectors.toList()); + List type2Entries = entries.stream().map(s -> new DictionaryEntryEntity(0, s, 1, false, type2.getTypeId())).collect(Collectors.toList()); assertThat(entryRepository.count()).isEqualTo(0); long t1 = System.currentTimeMillis(); entryRepository.saveAll(type1Entries); long jpaTime = System.currentTimeMillis() - t1; - assertThat(entryRepository.count()).isEqualTo(10_000); + assertThat(entryRepository.count()).isEqualTo(numberOfEntries); t1 = System.currentTimeMillis(); jdbcWriteUtils.saveBatch(type2Entries); long jdbcTime = System.currentTimeMillis() - t1; - assertThat(entryRepository.count()).isEqualTo(20_000); + assertThat(entryRepository.count()).isEqualTo(2 * numberOfEntries); // assertThat(jpaTime).isGreaterThan(jdbcTime); - System.out.println("JPA Time: " + jpaTime + "ms for 10k entries"); - System.out.println("JDBC Time: " + jdbcTime + "ms for 10k entries"); - + log.info("JPA Time: {} ms for {} entries", jpaTime, numberOfEntries); + log.info("JDBC Time: {} ms for {} entries", jdbcTime, numberOfEntries); } } From 2bc2e487682e02579b06af7441d2c1c4ace82cf2 Mon Sep 17 00:00:00 2001 From: Viktor Seifert Date: Fri, 28 Apr 2023 16:05:13 +0200 Subject: [PATCH 4/5] RED-6270: Changed batch execution to use the batch size provided by the configuration --- .../processor/utils/jdbc/JDBCWriteUtils.java | 35 +++++++++++-------- .../src/main/resources/application.yml | 2 +- .../src/test/resources/application.yml | 3 +- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/utils/jdbc/JDBCWriteUtils.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/utils/jdbc/JDBCWriteUtils.java index 8c6449035..7c71a2a32 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/utils/jdbc/JDBCWriteUtils.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/utils/jdbc/JDBCWriteUtils.java @@ -16,6 +16,7 @@ import javax.persistence.Table; import javax.transaction.Transactional; import org.apache.commons.lang3.StringUtils; +import org.springframework.core.env.Environment; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; @@ -34,6 +35,8 @@ public class JDBCWriteUtils { private final JdbcTemplate jdbcTemplate; + private final Environment environment; + @SneakyThrows @Transactional @@ -43,43 +46,47 @@ public class JDBCWriteUtils { return; } - var metadata = getEntityMetadata(entities.get(0)); + var metadata = getEntityMetadata(entities.get(0).getClass()); - final int batchSize = 500; - - jdbcTemplate.batchUpdate(metadata.getSqlStatement(), entities, batchSize, metadata::setValues); + jdbcTemplate.batchUpdate(metadata.getSqlStatement(), entities, getBatchSize(), metadata::setValues); } - private EntityMetadata getEntityMetadata(T entity) { + private int getBatchSize() { - var existingMetadata = entityMetadataMap.get(entity.getClass()); + return environment.getProperty("spring.jpa.properties.hibernate.jdbc.batch_size", int.class, 500); + } + + + private EntityMetadata getEntityMetadata(Class entityClass) { + + var existingMetadata = entityMetadataMap.get(entityClass); if (existingMetadata != null) { return existingMetadata; } - var tableName = getTableName(entity); - var args = getArgs(entity); + var tableName = getTableName(entityClass); + var args = getArgs(entityClass); var sql = String.format(SQL_TEMPLATE, tableName, String.join(", ", args.keySet()), args.keySet().stream().map(a -> "?").collect(Collectors.joining(", "))); var metadata = new EntityMetadata(tableName, sql, args); - entityMetadataMap.put(entity.getClass(), metadata); + entityMetadataMap.put(entityClass, metadata); return metadata; } - private String getTableName(T entity) { + private String getTableName(Class entityClass) { - var tableAnnot = entity.getClass().getDeclaredAnnotation(Table.class); + var tableAnnot = entityClass.getDeclaredAnnotation(Table.class); return tableAnnot.name(); } @SneakyThrows - private Map getArgs(T entity) { + private Map getArgs(Class entityClass) { - var fields = entity.getClass().getDeclaredFields(); + var fields = entityClass.getDeclaredFields(); Map entityMethodMap = new LinkedHashMap<>(); for (var field : fields) { var annotations = field.getDeclaredAnnotations(); @@ -87,7 +94,7 @@ public class JDBCWriteUtils { if (annotation.annotationType().equals(Column.class)) { var columnAnnotation = (Column) annotation; var name = StringUtils.isEmpty(columnAnnotation.name()) ? toSnakeCase(field.getName()) : columnAnnotation.name(); - entityMethodMap.put(name, entity.getClass().getMethod(getMethodName(field))); + entityMethodMap.put(name, entityClass.getMethod(getMethodName(field))); } } } diff --git a/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yml b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yml index b8771cbb0..fc2e39edd 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yml +++ b/persistence-service-v1/persistence-service-server-v1/src/main/resources/application.yml @@ -22,7 +22,7 @@ spring: properties: hibernate: jdbc: - batch_size: 50 + batch_size: 1000 order_inserts: true order_updates: true cache: diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml b/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml index 87063e89f..d61dfe710 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml +++ b/persistence-service-v1/persistence-service-server-v1/src/test/resources/application.yml @@ -16,7 +16,6 @@ spring: scheduler: instanceId: AUTO job-store-type: JDBC - main: allow-circular-references: true # FIXME jpa: @@ -28,7 +27,7 @@ spring: properties: hibernate: jdbc: - batch_size: 50 + batch_size: 1000 order_inserts: true order_updates: true open-in-view: true From 4ad76962ec8786f518c62f57f273c4c3a37755ec Mon Sep 17 00:00:00 2001 From: Viktor Seifert Date: Tue, 2 May 2023 12:45:38 +0200 Subject: [PATCH 5/5] RED-6270: Extracted common qualifiers into a constant --- .../PersistenceServiceProcessorConfiguration.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/PersistenceServiceProcessorConfiguration.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/PersistenceServiceProcessorConfiguration.java index 700d9242b..580b42302 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/PersistenceServiceProcessorConfiguration.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/PersistenceServiceProcessorConfiguration.java @@ -9,7 +9,8 @@ import org.springframework.cloud.openfeign.support.SortJacksonModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; +import org.springframework.context.annotation.DependsOn; +import org.springframework.context.annotation.Primary; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.retry.backoff.ExponentialBackOffPolicy; import org.springframework.retry.policy.SimpleRetryPolicy; @@ -26,6 +27,9 @@ import com.iqser.red.service.persistence.management.v1.processor.settings.FileMa @EnableFeignClients(basePackageClasses = {PDFTronClient.class, StatusReportClient.class, SearchClient.class, RedactionClient.class}) public class PersistenceServiceProcessorConfiguration { + public static final String TENANT_DATA_SOURCE_QUALIFIER = "multiTenantDataSource"; + + @Bean public PageJacksonModule pageJacksonModule() { @@ -58,7 +62,9 @@ public class PersistenceServiceProcessorConfiguration { @Bean - public JdbcTemplate jdbcTemplate(@Qualifier("multiTenantDataSource") @Lazy DataSource dataSource) { + @DependsOn(TENANT_DATA_SOURCE_QUALIFIER) + @Primary + public JdbcTemplate tenantJdbcTemplate(@Qualifier(TENANT_DATA_SOURCE_QUALIFIER) DataSource dataSource) { return new JdbcTemplate(dataSource); }