diff --git a/build.gradle b/build.gradle
index 4d4cb73d5b..069988cd88 100644
--- a/build.gradle
+++ b/build.gradle
@@ -740,7 +740,9 @@ project('spring-integration-jdbc') {
testImplementation "org.apache.derby:derbyclient:$derbyVersion"
testImplementation "org.postgresql:postgresql:$postgresVersion"
testImplementation "mysql:mysql-connector-java:$mysqlVersion"
- testImplementation "org.apache.commons:commons-dbcp2:$commonsDbcp2Version"
+ testImplementation ("org.apache.commons:commons-dbcp2:$commonsDbcp2Version") {
+ exclude group: 'commons-logging'
+ }
testImplementation 'org.testcontainers:mysql'
testImplementation 'org.testcontainers:postgresql'
diff --git a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/lock/DefaultLockRepository.java b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/lock/DefaultLockRepository.java
index 7d317bbb85..4b977ff6df 100644
--- a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/lock/DefaultLockRepository.java
+++ b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/lock/DefaultLockRepository.java
@@ -20,6 +20,7 @@ import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.UUID;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.sql.DataSource;
@@ -29,6 +30,8 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.SmartLifecycle;
+import org.springframework.core.log.LogAccessor;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
@@ -45,6 +48,12 @@ import org.springframework.util.Assert;
* Otherwise, it opens a possibility to break {@link java.util.concurrent.locks.Lock} contract,
* where {@link JdbcLockRegistry} uses non-shared {@link java.util.concurrent.locks.ReentrantLock}s
* for local synchronizations.
+ *
+ * This class implements {@link SmartLifecycle} and calls
+ * {@code SELECT COUNT(REGION) FROM %sLOCK} query
+ * according to the provided prefix on {@link #start()} to check if required table is present in DB.
+ * The application context will fail to start if the table is not present.
+ * This check can be disabled via {@link #setCheckDatabaseOnStart(boolean)}.
*
* @author Dave Syer
* @author Artem Bilan
@@ -56,7 +65,10 @@ import org.springframework.util.Assert;
* @since 4.3
*/
public class DefaultLockRepository
- implements LockRepository, InitializingBean, ApplicationContextAware, SmartInitializingSingleton {
+ implements LockRepository, InitializingBean, ApplicationContextAware, SmartInitializingSingleton,
+ SmartLifecycle {
+
+ private static final LogAccessor LOGGER = new LogAccessor(DefaultLockRepository.class);
/**
* Default value for the table prefix property.
@@ -72,6 +84,8 @@ public class DefaultLockRepository
private final JdbcTemplate template;
+ private final AtomicBoolean started = new AtomicBoolean();
+
private Duration ttl = DEFAULT_TTL;
private String prefix = DEFAULT_TABLE_PREFIX;
@@ -116,6 +130,10 @@ public class DefaultLockRepository
WHERE REGION=? AND LOCK_KEY=? AND CLIENT_ID=?
""";
+ private String countAllQuery = """
+ SELECT COUNT(REGION) FROM %sLOCK
+ """;
+
private ApplicationContext applicationContext;
private PlatformTransactionManager transactionManager;
@@ -126,6 +144,8 @@ public class DefaultLockRepository
private TransactionTemplate serializableTransactionTemplate;
+ private boolean checkDatabaseOnStart = true;
+
/**
* Constructor that initializes the client id that will be associated for
* all the locks persisted by the store instance to a random {@link UUID}.
@@ -293,6 +313,7 @@ public class DefaultLockRepository
this.insertQuery = String.format(this.insertQuery, this.prefix);
this.countQuery = String.format(this.countQuery, this.prefix);
this.renewQuery = String.format(this.renewQuery, this.prefix);
+ this.countAllQuery = String.format(this.countAllQuery, this.prefix);
}
@Override
@@ -325,6 +346,41 @@ public class DefaultLockRepository
this.serializableTransactionTemplate = new TransactionTemplate(this.transactionManager, transactionDefinition);
}
+ /**
+ * The flag to perform a database check query on start or not.
+ * @param checkDatabaseOnStart false to not perform the database check.
+ * @since 6.2
+ */
+ public void setCheckDatabaseOnStart(boolean checkDatabaseOnStart) {
+ this.checkDatabaseOnStart = checkDatabaseOnStart;
+ if (!checkDatabaseOnStart) {
+ LOGGER.info("The 'DefaultLockRepository' won't be started automatically " +
+ "and required table is not going be checked.");
+ }
+ }
+
+ @Override
+ public boolean isAutoStartup() {
+ return this.checkDatabaseOnStart;
+ }
+
+ @Override
+ public void start() {
+ if (this.started.compareAndSet(false, true) && this.checkDatabaseOnStart) {
+ this.template.queryForObject(this.countAllQuery, Integer.class); // If no table in DB, an exception is thrown
+ }
+ }
+
+ @Override
+ public void stop() {
+ this.started.set(false);
+ }
+
+ @Override
+ public boolean isRunning() {
+ return this.started.get();
+ }
+
@Override
public void close() {
this.defaultTransactionTemplate.executeWithoutResult(
diff --git a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/metadata/JdbcMetadataStore.java b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/metadata/JdbcMetadataStore.java
index f27b28578d..41d4dc7b92 100644
--- a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/metadata/JdbcMetadataStore.java
+++ b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/metadata/JdbcMetadataStore.java
@@ -16,9 +16,13 @@
package org.springframework.integration.jdbc.metadata;
+import java.util.concurrent.atomic.AtomicBoolean;
+
import javax.sql.DataSource;
import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.SmartLifecycle;
+import org.springframework.core.log.LogAccessor;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.integration.metadata.ConcurrentMetadataStore;
@@ -34,6 +38,12 @@ import org.springframework.util.Assert;
* where * is the target database type.
*
* The transaction management is required to use this {@link ConcurrentMetadataStore}.
+ *
+ * This class implements {@link SmartLifecycle} and calls
+ * {@code SELECT COUNT(METADATA_KEY) FROM %sMETADATA_STORE} query
+ * according to the provided prefix on {@link #start()} to check if required table is present in DB.
+ * The application context will fail to start if the table is not present.
+ * This check can be disabled via {@link #setCheckDatabaseOnStart(boolean)}.
*
* @author Bojan Vukasovic
* @author Artem Bilan
@@ -41,7 +51,9 @@ import org.springframework.util.Assert;
*
* @since 5.0
*/
-public class JdbcMetadataStore implements ConcurrentMetadataStore, InitializingBean {
+public class JdbcMetadataStore implements ConcurrentMetadataStore, InitializingBean, SmartLifecycle {
+
+ private static final LogAccessor LOGGER = new LogAccessor(JdbcMetadataStore.class);
private static final String KEY_CANNOT_BE_NULL = "'key' cannot be null";
@@ -52,6 +64,8 @@ public class JdbcMetadataStore implements ConcurrentMetadataStore, InitializingB
private final JdbcOperations jdbcTemplate;
+ private final AtomicBoolean started = new AtomicBoolean();
+
private String tablePrefix = DEFAULT_TABLE_PREFIX;
private String region = "DEFAULT";
@@ -93,6 +107,12 @@ public class JdbcMetadataStore implements ConcurrentMetadataStore, InitializingB
HAVING COUNT(*)=0
""";
+ private String countQuery = """
+ SELECT COUNT(METADATA_KEY) FROM %sMETADATA_STORE
+ """;
+
+ private boolean checkDatabaseOnStart = true;
+
/**
* Instantiate a {@link JdbcMetadataStore} using provided dataSource {@link DataSource}.
* @param dataSource a {@link DataSource}
@@ -137,7 +157,7 @@ public class JdbcMetadataStore implements ConcurrentMetadataStore, InitializingB
* Specify a row lock hint for the query in the lock-based operations.
* Defaults to {@code FOR UPDATE}. Can be specified as an empty string,
* if the target RDBMS doesn't support locking on tables from queries.
- * The value depends from RDBMS vendor, e.g. SQL Server requires {@code WITH (ROWLOCK)}.
+ * The value depends on the RDBMS vendor, e.g. SQL Server requires {@code WITH (ROWLOCK)}.
* @param lockHint the RDBMS vendor-specific lock hint.
* @since 5.0.7
*/
@@ -154,6 +174,42 @@ public class JdbcMetadataStore implements ConcurrentMetadataStore, InitializingB
this.replaceValueByKeyQuery = String.format(this.replaceValueByKeyQuery, this.tablePrefix);
this.removeValueQuery = String.format(this.removeValueQuery, this.tablePrefix);
this.putIfAbsentValueQuery = String.format(this.putIfAbsentValueQuery, this.tablePrefix, this.tablePrefix);
+ this.countQuery = String.format(this.putIfAbsentValueQuery, this.tablePrefix);
+ }
+
+ /**
+ * The flag to perform a database check query on start or not.
+ * @param checkDatabaseOnStart false to not perform the database check.
+ * @since 6.2
+ */
+ public void setCheckDatabaseOnStart(boolean checkDatabaseOnStart) {
+ this.checkDatabaseOnStart = checkDatabaseOnStart;
+ if (!checkDatabaseOnStart) {
+ LOGGER.info("The 'DefaultLockRepository' won't be started automatically " +
+ "and required table is not going be checked.");
+ }
+ }
+
+ @Override
+ public boolean isAutoStartup() {
+ return this.checkDatabaseOnStart;
+ }
+
+ @Override
+ public void start() {
+ if (this.started.compareAndSet(false, true) && this.checkDatabaseOnStart) {
+ this.jdbcTemplate.queryForObject(this.countQuery, Integer.class); // If no table in DB, an exception is thrown
+ }
+ }
+
+ @Override
+ public void stop() {
+ this.started.set(false);
+ }
+
+ @Override
+ public boolean isRunning() {
+ return this.started.get();
}
@Override
@@ -162,7 +218,7 @@ public class JdbcMetadataStore implements ConcurrentMetadataStore, InitializingB
Assert.notNull(key, KEY_CANNOT_BE_NULL);
Assert.notNull(value, "'value' cannot be null");
while (true) {
- //try to insert if does not exists
+ //try to insert if the entry does not exist
int affectedRows = tryToPutIfAbsent(key, value);
if (affectedRows > 0) {
//it was not in the table, so we have just inserted
@@ -218,7 +274,7 @@ public class JdbcMetadataStore implements ConcurrentMetadataStore, InitializingB
Assert.notNull(key, KEY_CANNOT_BE_NULL);
Assert.notNull(value, "'value' cannot be null");
while (true) {
- //try to insert if does not exist, if exists we will try to update it
+ //try to insert if the entry does not exist, if it exists we will try to update it
int affectedRows = tryToPutIfAbsent(key, value);
if (affectedRows == 0) {
//since value is not inserted, means it is already present
diff --git a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/JdbcChannelMessageStore.java b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/JdbcChannelMessageStore.java
index 6f179626eb..cde3b6c546 100644
--- a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/JdbcChannelMessageStore.java
+++ b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/JdbcChannelMessageStore.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -31,6 +32,7 @@ import java.util.function.Supplier;
import javax.sql.DataSource;
import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.SmartLifecycle;
import org.springframework.core.log.LogAccessor;
import org.springframework.core.log.LogMessage;
import org.springframework.core.serializer.Deserializer;
@@ -73,6 +75,11 @@ import org.springframework.util.StringUtils;
* The SQL scripts for creating the table are packaged
* under {@code org/springframework/integration/jdbc/schema-*.sql},
* where {@code *} denotes the target database type.
+ *
+ * This class implements {@link SmartLifecycle} and calls {@link #getMessageGroupCount()}
+ * on {@link #start()} to check if required table is present in DB.
+ * The application context will fail to start if the table is not present.
+ * This check can be disabled via {@link #setCheckDatabaseOnStart(boolean)}.
*
* @author Gunnar Hillert
* @author Artem Bilan
@@ -83,7 +90,7 @@ import org.springframework.util.StringUtils;
* @since 2.2
*/
@ManagedResource
-public class JdbcChannelMessageStore implements PriorityCapableChannelMessageStore, InitializingBean {
+public class JdbcChannelMessageStore implements PriorityCapableChannelMessageStore, InitializingBean, SmartLifecycle {
private static final LogAccessor LOGGER = new LogAccessor(JdbcChannelMessageStore.class);
@@ -121,6 +128,8 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
private final Lock idCacheWriteLock = this.idCacheLock.writeLock();
+ private final AtomicBoolean started = new AtomicBoolean();
+
private ChannelMessageStoreQueryProvider channelMessageStoreQueryProvider;
private String region = DEFAULT_REGION;
@@ -145,6 +154,8 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
private boolean priorityEnabled;
+ private boolean checkDatabaseOnStart = true;
+
/**
* Convenient constructor for configuration use.
*/
@@ -411,6 +422,41 @@ public class JdbcChannelMessageStore implements PriorityCapableChannelMessageSto
this.jdbcTemplate.afterPropertiesSet();
}
+ /**
+ * The flag to perform a database check query on start or not.
+ * @param checkDatabaseOnStart false to not perform the database check.
+ * @since 6.2
+ */
+ public void setCheckDatabaseOnStart(boolean checkDatabaseOnStart) {
+ this.checkDatabaseOnStart = checkDatabaseOnStart;
+ if (!checkDatabaseOnStart) {
+ LOGGER.info("The 'DefaultLockRepository' won't be started automatically " +
+ "and required table is not going be checked.");
+ }
+ }
+
+ @Override
+ public boolean isAutoStartup() {
+ return this.checkDatabaseOnStart;
+ }
+
+ @Override
+ public void start() {
+ if (this.started.compareAndSet(false, true) && this.checkDatabaseOnStart) {
+ getMessageGroupCount(); // If no table in DB, an exception is thrown
+ }
+ }
+
+ @Override
+ public void stop() {
+ this.started.set(false);
+ }
+
+ @Override
+ public boolean isRunning() {
+ return this.started.get();
+ }
+
/**
* Store a message in the database. The groupId identifies the channel for which
* the message is to be stored.
diff --git a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/JdbcMessageStore.java b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/JdbcMessageStore.java
index 2f70853758..26f1fb8c14 100644
--- a/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/JdbcMessageStore.java
+++ b/spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/store/JdbcMessageStore.java
@@ -26,11 +26,13 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;
import javax.sql.DataSource;
import org.springframework.beans.factory.BeanClassLoaderAware;
+import org.springframework.context.SmartLifecycle;
import org.springframework.core.serializer.Deserializer;
import org.springframework.core.serializer.Serializer;
import org.springframework.core.serializer.support.SerializingConverter;
@@ -66,6 +68,11 @@ import org.springframework.util.StringUtils;
* please consider using the channel-specific {@link JdbcChannelMessageStore} instead.
* This implementation is intended for correlation components (e.g. {@code }),
* {@code } and similar.
+ *
+ * This class implements {@link SmartLifecycle} and calls {@link #getMessageGroupCount()}
+ * on {@link #start()} to check if required tables are present in DB.
+ * The application context will fail to start if the table is not present.
+ * This check can be disabled via {@link #setCheckDatabaseOnStart(boolean)}.
*
* @author Dave Syer
* @author Oleg Zhurakousky
@@ -77,7 +84,8 @@ import org.springframework.util.StringUtils;
*
* @since 2.0
*/
-public class JdbcMessageStore extends AbstractMessageGroupStore implements MessageStore, BeanClassLoaderAware {
+public class JdbcMessageStore extends AbstractMessageGroupStore
+ implements MessageStore, BeanClassLoaderAware, SmartLifecycle {
/**
* Default value for the table prefix property.
@@ -234,6 +242,8 @@ public class JdbcMessageStore extends AbstractMessageGroupStore implements Messa
private final Map queryCache = new ConcurrentHashMap<>();
+ private final AtomicBoolean started = new AtomicBoolean();
+
private String region = "DEFAULT";
private String tablePrefix = DEFAULT_TABLE_PREFIX;
@@ -247,6 +257,8 @@ public class JdbcMessageStore extends AbstractMessageGroupStore implements Messa
private LobHandler lobHandler = new DefaultLobHandler();
+ private boolean checkDatabaseOnStart = true;
+
/**
* Create a {@link MessageStore} with all mandatory properties.
* @param dataSource a {@link DataSource}
@@ -331,6 +343,41 @@ public class JdbcMessageStore extends AbstractMessageGroupStore implements Messa
this.deserializer.addAllowedPatterns(patterns);
}
+ /**
+ * The flag to perform a database check query on start or not.
+ * @param checkDatabaseOnStart false to not perform the database check.
+ * @since 6.2
+ */
+ public void setCheckDatabaseOnStart(boolean checkDatabaseOnStart) {
+ this.checkDatabaseOnStart = checkDatabaseOnStart;
+ if (!checkDatabaseOnStart) {
+ logger.info("The 'DefaultLockRepository' won't be started automatically " +
+ "and required table is not going be checked.");
+ }
+ }
+
+ @Override
+ public boolean isAutoStartup() {
+ return this.checkDatabaseOnStart;
+ }
+
+ @Override
+ public void start() {
+ if (this.started.compareAndSet(false, true) && this.checkDatabaseOnStart) {
+ getMessageGroupCount(); // If no table in DB, an exception is thrown
+ }
+ }
+
+ @Override
+ public void stop() {
+ this.started.set(false);
+ }
+
+ @Override
+ public boolean isRunning() {
+ return this.started.get();
+ }
+
@Override
public Message> removeMessage(UUID id) {
Message> message = getMessage(id);
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcMessageStoreParserTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcMessageStoreParserTests.java
index cf4ca64767..4fa54f2889 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcMessageStoreParserTests.java
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/JdbcMessageStoreParserTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2022 the original author or authors.
+ * Copyright 2016-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,8 +20,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import org.junit.After;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.serializer.DefaultDeserializer;
@@ -81,7 +81,7 @@ public class JdbcMessageStoreParserTests {
assertThat(ReflectionTestUtils.getField(store, "lobHandler")).isEqualTo(context.getBean(LobHandler.class));
}
- @After
+ @AfterEach
public void tearDown() {
if (context != null) {
context.close();
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/StoredProcMessageHandlerParserTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/StoredProcMessageHandlerParserTests.java
index a1f527c4bb..6871b58f01 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/StoredProcMessageHandlerParserTests.java
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/StoredProcMessageHandlerParserTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,8 +19,8 @@ package org.springframework.integration.jdbc.config;
import java.sql.Types;
import java.util.List;
-import org.junit.After;
-import org.junit.Test;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.context.ConfigurableApplicationContext;
@@ -42,6 +42,8 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Gunnar Hillert
* @author Gary Russell
+ * @author Artem Bilan
+ *
* @since 2.1
*
*/
@@ -54,7 +56,7 @@ public class StoredProcMessageHandlerParserTests {
private static volatile int adviceCalled;
@Test
- public void testProcedureNameIsSet() throws Exception {
+ public void testProcedureNameIsSet() {
setUp("basicStoredProcOutboundChannelAdapterTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.consumer);
@@ -72,7 +74,7 @@ public class StoredProcMessageHandlerParserTests {
@SuppressWarnings("unchecked")
@Test
- public void testProcedurepParametersAreSet() throws Exception {
+ public void testProcedureParametersAreSet() {
setUp("basicStoredProcOutboundChannelAdapterTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.consumer);
@@ -114,7 +116,7 @@ public class StoredProcMessageHandlerParserTests {
@SuppressWarnings("unchecked")
@Test
- public void testSqlParametersAreSet() throws Exception {
+ public void testSqlParametersAreSet() {
setUp("basicStoredProcOutboundChannelAdapterTest.xml", getClass());
DirectFieldAccessor accessor = new DirectFieldAccessor(this.consumer);
@@ -161,15 +163,15 @@ public class StoredProcMessageHandlerParserTests {
}
@Test
- public void adviceCalled() throws Exception {
+ public void adviceCalled() {
setUp("advisedStoredProcOutboundChannelAdapterTest.xml", getClass());
MessageHandler handler = TestUtils.getPropertyValue(this.consumer, "handler", MessageHandler.class);
- handler.handleMessage(new GenericMessage("foo"));
+ handler.handleMessage(new GenericMessage<>("foo"));
assertThat(adviceCalled).isEqualTo(1);
}
- @After
+ @AfterEach
public void tearDown() {
if (context != null) {
context.close();
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/advisedStoredProcOutboundChannelAdapterTest.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/advisedStoredProcOutboundChannelAdapterTest.xml
index dc654431e1..09ff1757b3 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/advisedStoredProcOutboundChannelAdapterTest.xml
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/advisedStoredProcOutboundChannelAdapterTest.xml
@@ -12,9 +12,7 @@
-
-
-
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/basicStoredProcOutboundChannelAdapterTest.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/basicStoredProcOutboundChannelAdapterTest.xml
index e0535239ca..f7f61e4755 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/basicStoredProcOutboundChannelAdapterTest.xml
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/basicStoredProcOutboundChannelAdapterTest.xml
@@ -1,30 +1,29 @@
-
-
-
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/defaultJdbcMessageStore.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/defaultJdbcMessageStore.xml
index c0b59d2d15..41b9ddb10f 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/defaultJdbcMessageStore.xml
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/defaultJdbcMessageStore.xml
@@ -7,7 +7,10 @@
http://www.springframework.org/schema/integration/jdbc https://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
-
+
+
+
+
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/jdbcOperationsJdbcMessageStore.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/jdbcOperationsJdbcMessageStore.xml
index 2861735b43..10833741ba 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/jdbcOperationsJdbcMessageStore.xml
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/jdbcOperationsJdbcMessageStore.xml
@@ -7,8 +7,11 @@
http://www.springframework.org/schema/integration/jdbc https://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
-
-
+
+
+
+
+
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/serializerJdbcMessageStore.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/serializerJdbcMessageStore.xml
index d02a3d824f..54b5bb7bc0 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/serializerJdbcMessageStore.xml
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/serializerJdbcMessageStore.xml
@@ -5,7 +5,10 @@
http://www.springframework.org/schema/integration/jdbc https://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
-
+
+
+
+
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/soupedUpJdbcMessageStore.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/soupedUpJdbcMessageStore.xml
index c614b7cb7c..d5e6a89002 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/soupedUpJdbcMessageStore.xml
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/config/soupedUpJdbcMessageStore.xml
@@ -2,15 +2,19 @@
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/lock/JdbcLockRegistryTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/lock/JdbcLockRegistryTests.java
index f9ac8fe0e3..0e6be45ac1 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/lock/JdbcLockRegistryTests.java
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/lock/JdbcLockRegistryTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2022 the original author or authors.
+ * Copyright 2016-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,17 +29,20 @@ import java.util.concurrent.locks.Lock;
import javax.sql.DataSource;
+import org.h2.jdbc.JdbcSQLSyntaxErrorException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextException;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.util.UUIDConverter;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
+import org.springframework.transaction.PlatformTransactionManager;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -68,6 +71,9 @@ public class JdbcLockRegistryTests {
@Autowired
private DataSource dataSource;
+ @Autowired
+ private PlatformTransactionManager transactionManager;
+
@Autowired
private ApplicationContext context;
@@ -483,6 +489,20 @@ public class JdbcLockRegistryTests {
toUUID("foo:5"));
}
+ @Test
+ void noTableThrowsExceptionOnStart() {
+ try (TestUtils.TestApplicationContext testApplicationContext = TestUtils.createTestApplicationContext()) {
+ DefaultLockRepository client = new DefaultLockRepository(this.dataSource);
+ client.setPrefix("TEST_");
+ client.setTransactionManager(this.transactionManager);
+ testApplicationContext.registerBean("client", client);
+ assertThatExceptionOfType(ApplicationContextException.class)
+ .isThrownBy(testApplicationContext::refresh)
+ .withRootCauseExactlyInstanceOf(JdbcSQLSyntaxErrorException.class)
+ .withStackTraceContaining("Table \"TEST_LOCK\" not found");
+ }
+ }
+
@SuppressWarnings("unchecked")
private static Map getRegistryLocks(JdbcLockRegistry registry) {
return TestUtils.getPropertyValue(registry, "locks", Map.class);
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/metadata/JdbcMetadataStoreTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/metadata/JdbcMetadataStoreTests.java
index effbc22ee3..bb637ad376 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/metadata/JdbcMetadataStoreTests.java
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/metadata/JdbcMetadataStoreTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017-2022 the original author or authors.
+ * Copyright 2017-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,15 +18,19 @@ package org.springframework.integration.jdbc.metadata;
import javax.sql.DataSource;
+import org.apache.derby.shared.common.error.StandardException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContextException;
+import org.springframework.integration.test.util.TestUtils;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.transaction.annotation.Transactional;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Bojan Vukasovic
@@ -105,4 +109,17 @@ public class JdbcMetadataStoreTests {
assertThat(bar).isEqualTo("bar");
}
+ @Test
+ void noTableThrowsExceptionOnStart() {
+ try (TestUtils.TestApplicationContext testApplicationContext = TestUtils.createTestApplicationContext()) {
+ JdbcMetadataStore jdbcMetadataStore = new JdbcMetadataStore(this.dataSource);
+ jdbcMetadataStore.setTablePrefix("TEST_");
+ testApplicationContext.registerBean("jdbcMetadataStore", jdbcMetadataStore);
+ assertThatExceptionOfType(ApplicationContextException.class)
+ .isThrownBy(testApplicationContext::refresh)
+ .withRootCauseExactlyInstanceOf(StandardException.class)
+ .withStackTraceContaining("Table/View 'TEST_METADATA_STORE' does not exist");
+ }
+ }
+
}
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/mysql/MySqlContainerTest.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/mysql/MySqlContainerTest.java
index 69c5e3b964..b5089d985a 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/mysql/MySqlContainerTest.java
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/mysql/MySqlContainerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2021-2022 the original author or authors.
+ * Copyright 2021-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,9 @@
package org.springframework.integration.jdbc.mysql;
+import javax.sql.DataSource;
+
+import org.apache.commons.dbcp2.BasicDataSource;
import org.junit.jupiter.api.BeforeAll;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.junit.jupiter.Testcontainers;
@@ -57,4 +60,13 @@ public interface MySqlContainerTest {
return MY_SQL_CONTAINER.getPassword();
}
+ static DataSource dataSource() {
+ BasicDataSource dataSource = new BasicDataSource();
+ dataSource.setDriverClassName(getDriverClassName());
+ dataSource.setUrl(getJdbcUrl());
+ dataSource.setUsername(getUsername());
+ dataSource.setPassword(getPassword());
+ return dataSource;
+ }
+
}
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/mysql/MySqlJdbcMessageStoreTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/mysql/MySqlJdbcMessageStoreTests.java
index 7c6b3d3718..979ad02c7b 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/mysql/MySqlJdbcMessageStoreTests.java
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/mysql/MySqlJdbcMessageStoreTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@ import java.util.UUID;
import javax.sql.DataSource;
-import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.jupiter.api.AfterEach;
@@ -509,12 +508,7 @@ public class MySqlJdbcMessageStoreTests implements MySqlContainerTest {
@Bean
DataSource dataSource() {
- BasicDataSource dataSource = new BasicDataSource();
- dataSource.setDriverClassName(MySqlContainerTest.getDriverClassName());
- dataSource.setUrl(MySqlContainerTest.getJdbcUrl());
- dataSource.setUsername(MySqlContainerTest.getUsername());
- dataSource.setPassword(MySqlContainerTest.getPassword());
- return dataSource;
+ return MySqlContainerTest.dataSource();
}
@Bean
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/JdbcMessageStoreTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/JdbcMessageStoreTests.java
index 4734b02021..5976824b54 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/JdbcMessageStoreTests.java
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/JdbcMessageStoreTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,11 +37,13 @@ import org.apache.commons.dbcp2.PoolingDataSource;
import org.apache.commons.pool2.ObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
+import org.hsqldb.HsqlException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.context.ApplicationContextException;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.SynthesizingMethodParameter;
import org.springframework.integration.IntegrationMessageHeaderAccessor;
@@ -51,6 +53,7 @@ import org.springframework.integration.history.MessageHistory;
import org.springframework.integration.store.MessageGroup;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.test.predicate.MessagePredicate;
+import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.util.UUIDConverter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
@@ -62,6 +65,7 @@ import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Dave Syer
@@ -577,6 +581,19 @@ public class JdbcMessageStoreTests {
pooledMessageStore.removeMessageGroup(groupId);
}
+ @Test
+ void noTableThrowsExceptionOnStart() {
+ try (TestUtils.TestApplicationContext testApplicationContext = TestUtils.createTestApplicationContext()) {
+ JdbcMessageStore jdbcMessageStore = new JdbcMessageStore(this.dataSource);
+ jdbcMessageStore.setTablePrefix("TEST_");
+ testApplicationContext.registerBean("jdbcMessageStore", jdbcMessageStore);
+ assertThatExceptionOfType(ApplicationContextException.class)
+ .isThrownBy(testApplicationContext::refresh)
+ .withRootCauseExactlyInstanceOf(HsqlException.class)
+ .withStackTraceContaining("user lacks privilege or object not found: TEST_MESSAGE_GROUP");
+ }
+ }
+
public void methodForCollectionOfPayloads(Collection payloads) {
}
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/AbstractJdbcChannelMessageStoreTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/AbstractJdbcChannelMessageStoreTests.java
index 54e540d776..ea8e3db81b 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/AbstractJdbcChannelMessageStoreTests.java
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/AbstractJdbcChannelMessageStoreTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,9 +21,8 @@ import java.sql.SQLException;
import javax.sql.DataSource;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.serializer.support.SerializingConverter;
@@ -33,7 +32,7 @@ import org.springframework.jdbc.support.lob.DefaultLobHandler;
import org.springframework.jdbc.support.lob.LobHandler;
import org.springframework.messaging.Message;
import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
@@ -50,13 +49,13 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Artem Bilan
*/
-@RunWith(SpringRunner.class)
+@SpringJUnitConfig
@DirtiesContext
public abstract class AbstractJdbcChannelMessageStoreTests {
protected static final String TEST_MESSAGE_GROUP = "AbstractJdbcChannelMessageStoreTests";
- private static final String REGION = "AbstractJdbcChannelMessageStoreTests";
+ protected static final String REGION = "AbstractJdbcChannelMessageStoreTests";
@Autowired
protected DataSource dataSource;
@@ -69,8 +68,8 @@ public abstract class AbstractJdbcChannelMessageStoreTests {
@Autowired
protected ChannelMessageStoreQueryProvider queryProvider;
- @Before
- public void init() throws Exception {
+ @BeforeEach
+ public void init() {
messageStore = new JdbcChannelMessageStore(dataSource);
messageStore.setRegion(REGION);
messageStore.setChannelMessageStoreQueryProvider(queryProvider);
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/DataSource-common-context.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/DataSource-common-context.xml
index d3590a290e..5291a91ffd 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/DataSource-common-context.xml
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/DataSource-common-context.xml
@@ -1,16 +1,11 @@
+ xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
-
-
+
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/DataSource-mysql-context.xml b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/DataSource-mysql-context.xml
index 64be219c5c..9c00bb28db 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/DataSource-mysql-context.xml
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/DataSource-mysql-context.xml
@@ -1,22 +1,22 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns:jdbc="http://www.springframework.org/schema/jdbc"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/jdbc https://www.springframework.org/schema/jdbc/spring-jdbc.xsd">
-
+
-
-
-
-
-
-
-
+
-
+
+
+
+
+
+
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/H2JdbcChannelMessageStoreTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/H2JdbcChannelMessageStoreTests.java
index c750dd4be0..b19112f38f 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/H2JdbcChannelMessageStoreTests.java
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/H2JdbcChannelMessageStoreTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2016-2019 the original author or authors.
+ * Copyright 2016-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,37 @@
package org.springframework.integration.jdbc.store.channel;
+import org.h2.jdbc.JdbcSQLSyntaxErrorException;
+import org.junit.jupiter.api.Test;
+
+import org.springframework.context.ApplicationContextException;
+import org.springframework.integration.jdbc.store.JdbcChannelMessageStore;
+import org.springframework.integration.test.util.TestUtils;
+import org.springframework.test.context.ContextConfiguration;
+
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+
/**
* @author Gunnar Hillert
* @author Manuel Jordan
* @since 4.3
*/
+@ContextConfiguration
public class H2JdbcChannelMessageStoreTests extends AbstractJdbcChannelMessageStoreTests {
+ @Test
+ void noTableThrowsExceptionOnStart() {
+ try (TestUtils.TestApplicationContext testApplicationContext = TestUtils.createTestApplicationContext()) {
+ JdbcChannelMessageStore jdbcChannelMessageStore = new JdbcChannelMessageStore(this.dataSource);
+ jdbcChannelMessageStore.setTablePrefix("TEST_");
+ jdbcChannelMessageStore.setRegion(REGION);
+ jdbcChannelMessageStore.setChannelMessageStoreQueryProvider(this.queryProvider);
+ testApplicationContext.registerBean("jdbcChannelMessageStore", jdbcChannelMessageStore);
+ assertThatExceptionOfType(ApplicationContextException.class)
+ .isThrownBy(testApplicationContext::refresh)
+ .withRootCauseExactlyInstanceOf(JdbcSQLSyntaxErrorException.class)
+ .withStackTraceContaining("Table \"TEST_CHANNEL_MESSAGE\" not found");
+ }
+ }
+
}
diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/MySqlJdbcChannelMessageStoreTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/MySqlJdbcChannelMessageStoreTests.java
index 7bcdae182d..e90a8a2a60 100644
--- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/MySqlJdbcChannelMessageStoreTests.java
+++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/store/channel/MySqlJdbcChannelMessageStoreTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,15 +16,15 @@
package org.springframework.integration.jdbc.store.channel;
-import org.junit.Ignore;
-
+import org.springframework.integration.jdbc.mysql.MySqlContainerTest;
import org.springframework.test.context.ContextConfiguration;
/**
* @author Gunnar Hillert
+ * @author Artem Bilan
*/
-@Ignore
@ContextConfiguration
-public class MySqlJdbcChannelMessageStoreTests extends AbstractJdbcChannelMessageStoreTests {
+public class MySqlJdbcChannelMessageStoreTests extends AbstractJdbcChannelMessageStoreTests
+ implements MySqlContainerTest {
}
diff --git a/src/reference/asciidoc/jdbc.adoc b/src/reference/asciidoc/jdbc.adoc
index 39e4464261..868ecc83b7 100644
--- a/src/reference/asciidoc/jdbc.adoc
+++ b/src/reference/asciidoc/jdbc.adoc
@@ -386,6 +386,7 @@ Furthermore, the index for `PriorityChannel` is commented out because it is not
NOTE: When using the `OracleChannelMessageStoreQueryProvider`, the priority channel index **must** be added because it is included in a hint in the query.
+[[jdbc-db-init]]
==== Initializing the Database
Before starting to use JDBC message store components, you should provision a target database with the appropriate objects.
@@ -397,6 +398,10 @@ A common way to use these scripts is to reference them in a https://docs.spring.
Note that the scripts are provided as samples and as specifications of the required table and column names.
You may find that you need to enhance them for production use (for, example, by adding index declarations).
+Starting with version 6.2, the `JdbcMessageStore`, `JdbcChannelMessageStore`, `JdbcMetadataStore`, and `DefaultLockRepository` implement `SmartLifecycle` and perform a`SELECT COUNT` query, on their respective tables, in the `start()` method to ensure that the required table (according to the provided prefix) is present in the target database.
+If the required table does not exist, the application context fails to start.
+The check can be disabled via `setCheckDatabaseOnStart(false)`.
+
[[jdbc-message-store-generic]]
==== The Generic JDBC Message Store
diff --git a/src/reference/asciidoc/whats-new.adoc b/src/reference/asciidoc/whats-new.adoc
index ddde6a9abe..4ede4b68b8 100644
--- a/src/reference/asciidoc/whats-new.adoc
+++ b/src/reference/asciidoc/whats-new.adoc
@@ -45,3 +45,9 @@ See <<./web-sockets.adoc#websocket-client-container-attributes, WebSockets Suppo
The `KafkaMessageSource` now extracts an `ErrorHandlingDeserializer` configuration from the consumer properties and re-throws `DeserializationException` extracted from failed record headers.
See <<./kafka.adoc#kafka-inbound-pollable, Kafka Inbound Channel Adapter>> for more information.
+
+[[x6.2-jdbc]]
+=== JDBC Support Changes
+
+The `JdbcMessageStore`, `JdbcChannelMessageStore`, `JdbcMetadataStore`, and `DefaultLockRepository` implement `SmartLifecycle` and perform a`SELECT COUNT` query, on their respective tables, in the `start()` method to ensure that the required table (according to the provided prefix) is present in the target database.
+See <<./jdbc.adoc#jdbc-db-init, Initializing the Database>> for more information.