简体   繁体   中英

Configure multiple datasources in Spring Boot application with multiple docker containers

I am currently trying to configure a spring boot application to use two different docker containers (postgres images) for two different datasources. For that, I took the code from this Baeldung tutorial and copied it into a new project. I adjusted the package structure in the annotations, but I am still running into errors. While I managed to find solutions for some of them, I am now stuck. When calling docker-compose up , the startup of the application crashes with an IllegalStateException after the two postgres containers started.

spring-boot-docker-app-1        | 2022-09-23 10:01:07.835  INFO 1 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
spring-boot-docker-app-1        | 2022-09-23 10:01:07.985  INFO 1 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 141 ms. Found 1 JPA repository interfaces.
spring-boot-docker-app-1        | 2022-09-23 10:01:07.986  INFO 1 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
spring-boot-docker-app-1        | 2022-09-23 10:01:07.996  INFO 1 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 9 ms. Found 2 JPA repository interfaces.
spring-boot-docker-app-1        | 2022-09-23 10:01:08.251 ERROR 1 --- [           main] o.s.boot.SpringApplication               : Application run failed
spring-boot-docker-app-1        | 
spring-boot-docker-app-1        | java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.entityManagerFactoryBuilder
spring-boot-docker-app-1        |       at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60) ~[spring-boot-autoconfigure-2.7.2.jar!/:2.7.2]
spring-boot-docker-app-1        |       at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:193) ~[spring-context-5.3.22.jar!/
:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:153) ~[spring-context-5.3.
22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:129) ~[spring-context-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:343) ~[spring-context-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:247) ~[spring-context-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311) ~[spring-context-5.3.22.jar!/:5.
3.22]
spring-boot-docker-app-1        |       at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:112) ~[spring-context-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746) ~[spring-context-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564) ~[spring-context-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.2.jar!/:2.7.2]
spring-boot-docker-app-1        |       at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-2.7.2.jar!/:2.7.2]
spring-boot-docker-app-1        |       at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.2.jar!/:2.7.2]
spring-boot-docker-app-1        |       at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.2.jar!/:2.7.2]
spring-boot-docker-app-1        |       at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.7.2.jar!/:2.7.2]
spring-boot-docker-app-1        |       at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-2.7.2.jar!/:2.7.2]
spring-boot-docker-app-1        |       at com.example.springbootdocker.multipledb.SpringBootDockerApplication.main(SpringBootDockerApplication.java:28) ~[classes!/:0.0.1-SNAPSHOT]
spring-boot-docker-app-1        |       at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
spring-boot-docker-app-1        |       at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
spring-boot-docker-app-1        |       at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
spring-boot-docker-app-1        |       at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
spring-boot-docker-app-1        |       at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) ~[app.jar:0.0.1-SNAPSHOT]
spring-boot-docker-app-1        |       at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) ~[app.jar:0.0.1-SNAPSHOT]
spring-boot-docker-app-1        |       at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) ~[app.jar:0.0.1-SNAPSHOT]
spring-boot-docker-app-1        |       at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:65) ~[app.jar:0.0.1-SNAPSHOT]
spring-boot-docker-app-1        | Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration] from ClassLoader [org.springframework.boot.loader.La
unchedURLClassLoader@4590c9c3]
spring-boot-docker-app-1        |       at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:485) ~[spring-core-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:361) ~[spring-core-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:418) ~[spring-core-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.lambda$getTypeForFactoryMethod$2(AbstractAutowireCapableBeanFactory.java:765) ~[spring-beans-5.3.22.jar!/:5.3.22
]
spring-boot-docker-app-1        |       at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1705) ~[na:na]
spring-boot-docker-app-1        |       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:764) ~[spring-beans-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:703) ~[spring-beans-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:674) ~[spring-beans-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1670) ~[spring-beans-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:570) ~[spring-beans-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:542) ~[spring-beans-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       at org.springframework.boot.autoconfigure.condition.OnBeanCondition.collectBeanNamesForType(OnBeanCondition.java:250) ~[spring-boot-autoconfigure-2.7.2.jar!/:2.7.2]
spring-boot-docker-app-1        |       at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:243) ~[spring-boot-autoconfigure-2.7.2.jar!/:2.7.2]
spring-boot-docker-app-1        |       at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getBeanNamesForType(OnBeanCondition.java:233) ~[spring-boot-autoconfigure-2.7.2.jar!/:2.7.2]
spring-boot-docker-app-1        |       at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchingBeans(OnBeanCondition.java:181) ~[spring-boot-autoconfigure-2.7.2.jar!/:2.7.2]
spring-boot-docker-app-1        |       at org.springframework.boot.autoconfigure.condition.OnBeanCondition.getMatchOutcome(OnBeanCondition.java:156) ~[spring-boot-autoconfigure-2.7.2.jar!/:2.7.2]
spring-boot-docker-app-1        |       at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-2.7.2.jar!/:2.7.2]
spring-boot-docker-app-1        |       ... 25 common frames omitted
spring-boot-docker-app-1        | Caused by: java.lang.NoClassDefFoundError: org/hibernate/boot/model/naming/PhysicalNamingStrategy
spring-boot-docker-app-1        |       at java.base/java.lang.Class.getDeclaredMethods0(Native Method) ~[na:na]
spring-boot-docker-app-1        |       at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3167) ~[na:na]
spring-boot-docker-app-1        |       at java.base/java.lang.Class.getDeclaredMethods(Class.java:2310) ~[na:na]
spring-boot-docker-app-1        |       at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:467) ~[spring-core-5.3.22.jar!/:5.3.22]
spring-boot-docker-app-1        |       ... 41 common frames omitted
spring-boot-docker-app-1        | Caused by: java.lang.ClassNotFoundException: org.hibernate.boot.model.naming.PhysicalNamingStrategy
spring-boot-docker-app-1        |       at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471) ~[na:na]
spring-boot-docker-app-1        |       at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588) ~[na:na]
spring-boot-docker-app-1        |       at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151) ~[app.jar:0.0.1-SNAPSHOT]
spring-boot-docker-app-1        |       at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
spring-boot-docker-app-1        |       ... 45 common frames omitted
[...]

I'm hoping to have the tables for User in sourceone , and for Product in sourcetwo . For now, all I see when I look into the db containers with psql is that no relations were found (I guess that's because the application is crashing which is why I'm trying to fix that). My workflow is to run ./mvnw.exe clean install , then build a docker image with docker build -t test/multiple-db. and finally run docker-compose up .

In the process of trying to fix other errors, I added and changed some dependencies. I read that this error might also be related to a problem with the dependencies, but I did not manage to find a solution so far. Here are some snippets of the code which might help, most of it is very similar to the above mentioned tutorial ( github source ). It seemed some of the dependencies were outdated which I tried to fix but maybe I have done some bigger damage in the process.

Dockerfile

FROM adoptopenjdk/openjdk11:jdk-11.0.2.9-slim
WORKDIR /opt
COPY target/*.jar /opt/app.jar
ENTRYPOINT exec java $JAVA_OPTS -jar app.jar

docker-compose.yml

version: '3'
services:

  app:
    image: test/multiple-db
    ports:
      - "8080:8080"
    depends_on:
      - sourceone
      - sourcetwo

  sourceone:
    image: postgres
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: user

  sourcetwo:
    image: postgres
    ports:
      - "5433:5432"
    environment:
      POSTGRES_USER: product
      POSTGRES_PASSWORD: product

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>spring-boot-docker</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-docker</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-commons</artifactId>
            <version>2.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>2.7.2</version>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>
        <dependency>
            <groupId>jakarta.persistence</groupId>
            <artifactId>jakarta.persistence-api</artifactId>
            <version>2.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.2.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>4.1.4.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.2.3.Final</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

application.properties

spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create

spring.datasource.jdbcUrl=jdbc:postgresql://sourceone:5432/user
spring.datasource.username=user
spring.datasource.password=user
spring.datasource.driverClassName=org.postgresql.Driver

spring.second-datasource.jdbcUrl=jdbc:postgresql://sourcetwo:5432/product
spring.second-datasource.username=product
spring.second-datasource.password=product
spring.second-datasource.driverClassName=org.postgresql.Driver

I hope I didn't miss anything. Thanks in advance, would love to hear some input on what I've done wrong!

You are mapping both container ports to the same 5432 of host. Use 2 different ports and also include the changed ports inside application.properties file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM