I have a Spring project (not using Spring Boot, if that's relevant) that I'm trying to connect to a local database using the Postgres JDBC driver. (The local database is actually Yugabyte, but that should be fully compatible with the Postgres driver.)
When starting the application, I get this error message:
java.lang.IllegalArgumentException: An AbstractMessageProducingMessageHandler may only be referenced once (org.springframework.integration.config.SplitterFactoryBean#0) - use scope="prototype"
at org.springframework.util.Assert.isTrue(Assert.java:118)
at org.springframework.integration.config.AbstractStandardMessageHandlerFactoryBean.checkReuse(AbstractStandardMessageHandlerFactoryBean.java:168)
at org.springframework.integration.config.AbstractStandardMessageHandlerFactoryBean.createHandler(AbstractStandardMessageHandlerFactoryBean.java:137)
at org.springframework.integration.config.AbstractSimpleMessageHandlerFactoryBean.createHandlerInternal(AbstractSimpleMessageHandlerFactoryBean.java:186)
at org.springframework.integration.config.AbstractSimpleMessageHandlerFactoryBean.getObject(AbstractSimpleMessageHandlerFactoryBean.java:174)
at org.springframework.integration.config.AbstractSimpleMessageHandlerFactoryBean.getObject(AbstractSimpleMessageHandlerFactoryBean.java:59)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:171)
... 52 more
I can't place this error at all. There is one similar question on Stack Overflow, but there the asker seems to actually know what they're doing and how this is related to spring integration. I, however, am not aware at all that I'm trying to 'reuse' anything. The referenced question also doesn't seem to be related to database configuration.
My setup/configuration is a bit involved, so I'll try to quote the parts that seem relevant.
I have a dao layer project that has the following gradle dependencies (among others):
implementation("org.springframework:spring-context:5.2.2.RELEASE")
implementation("org.springframework:spring-jdbc:5.2.2.RELEASE")
implementation("org.jooq:jooq-kotlin:3.14.11")
runtimeOnly("org.postgresql:postgresql:42.2.19.jre7")
In the same project, I have some configuration (in Kotlin):
@Configuration
open class Config {
@Bean
open fun jdbcTemplate(dataSource: DataSource): JdbcTemplate = JdbcTemplate(dataSource)
@Bean
open fun dslContext(): DSLContext = DefaultDSLContext(SQLDialect.POSTGRES)
@Configuration
@Profile("!unittest")
open inner class NonTestConfig {
@Bean
open fun dataSource(): DataSource {
return DriverManagerDataSource().apply {
// Hardcoded properties to be replaced by values from property file
setDriverClassName("org.postgresql.Driver")
url = "jdbc:postgresql://localhost:5433/demo"
username = "yugabyte"
password = "yugabyte"
}
}
}
}
(Notes: the DSLContext bean is used for JOOQL, included for completeness' sake. The inner class config is there because there is also a separate unit testing config for an embedded database - that one works fine!)
Now, the above project is used in my top-level project that contains the actual application. It's a maven runtime dependency there. I import the config class in this project's XML configuration, using this method:
<context:annotation-config />
<bean class="my.package.Config" />
Then trying to start the application produces the error message.