簡體   English   中英

使用 Spring 引導運行 Postgres 的預先存在的 Docker 容器接線

[英]Wiring Up pre-existing Docker container running Postgres with Spring Boot

我的目標是:使用運行 Postgres 數據庫的 Docker 容器。 使用此容器構建 Spring 服務和數據訪問層。 所有這些都在我的本地環境中。

我正在通過在 Docker 容器中設置 Postgres 數據庫。 我已經啟動並運行了容器。 我已經創建了表、視圖、觸發器、序列等。據我所知,它工作正常。 我可以使用 pgAdmin 進行連接。

我現在已經開始設置 Spring 引導、存儲庫、Model 和單個表的單元測試。 該測試僅將幾條記錄插入表中。 我嘗試了幾個示例、教程和博客。

當我使用 maven 為項目構建和測試時,我收到以下錯誤。

2020-08-10 16:01:49.407  INFO 83573 --- [           main] DeferredRepositoryInitializationListener : Triggering deferred initialization of Spring Data repositories…
2020-08-10 16:01:49.771  INFO 83573 --- [           main] DeferredRepositoryInitializationListener : Spring Data repositories initialized!
2020-08-10 16:01:49.789  INFO 83573 --- [           main] n.c.p.s.repository.VendorRepositoryTest  : Started VendorRepositoryTest in 6.623 seconds (JVM running for 7.917)
2020-08-10 16:01:49.932  INFO 83573 --- [           main] o.t.d.DockerClientProviderStrategy       : Loaded org.testcontainers.dockerclient.UnixSocketClientProviderStrategy from ~/.testcontainers.properties, will try it first
2020-08-10 16:01:50.660  INFO 83573 --- [           main] o.t.d.UnixSocketClientProviderStrategy   : Accessing docker with local Unix socket
2020-08-10 16:01:50.661  INFO 83573 --- [           main] o.t.d.DockerClientProviderStrategy       : Found Docker environment with local Unix socket (unix:///var/run/docker.sock)
2020-08-10 16:01:50.816  INFO 83573 --- [           main] org.testcontainers.DockerClientFactory   : Docker host IP address is localhost
2020-08-10 16:01:50.871  INFO 83573 --- [           main] org.testcontainers.DockerClientFactory   : Connected to docker: 
  Server Version: 19.03.12
  API Version: 1.40
  Operating System: Docker Desktop
  Total Memory: 1991 MB
2020-08-10 16:01:51.966  INFO 83573 --- [           main] org.testcontainers.DockerClientFactory   : Ryuk started - will monitor and terminate Testcontainers containers on JVM exit
2020-08-10 16:01:51.966  INFO 83573 --- [           main] org.testcontainers.DockerClientFactory   : Checking the system...
2020-08-10 16:01:51.967  INFO 83573 --- [           main] org.testcontainers.DockerClientFactory   : ✔︎ Docker server version should be at least 1.6.0
2020-08-10 16:01:52.131  INFO 83573 --- [           main] org.testcontainers.DockerClientFactory   : ✔︎ Docker environment should have more than 2GB free disk space
2020-08-10 16:01:52.154  INFO 83573 --- [           main] 🐳 [postgres:9.6.12]                     : Creating container for image: postgres:9.6.12
2020-08-10 16:01:52.254  INFO 83573 --- [           main] 🐳 [postgres:9.6.12]                     : Starting container with ID: 0c1ea5de4bc47651ac2ce02d1e85590a9165d9c31b7584ea1924d88fc85eeaad
2020-08-10 16:01:52.614  INFO 83573 --- [           main] 🐳 [postgres:9.6.12]                     : Container postgres:9.6.12 is starting: 0c1ea5de4bc47651ac2ce02d1e85590a9165d9c31b7584ea1924d88fc85eeaad
2020-08-10 16:01:57.539  INFO 83573 --- [           main] 🐳 [postgres:9.6.12]                     : Container postgres:9.6.12 started in PT7.619S
Hibernate: select nextval ('vendor_tbl_vendor_id_seq')
2020-08-10 16:01:57.587 ERROR 83573 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : ERROR: relation "vendor_tbl_vendor_id_seq" does not exist
  Position: 17
Hibernate: select vendor0_.id as id1_0_, vendor0_.vendor_env as vendor_e2_0_, vendor0_.lpl_client_id as lpl_clie3_0_, vendor0_.public_key as public_k4_0_, vendor0_.secret_key as secret_k5_0_, vendor0_.vendor_name as vendor_n6_0_ from investor.vendor_tbl vendor0_
[ERROR] Tests run: 3, Failures: 0, Errors: 2, Skipped: 0, Time elapsed: 15.57 s <<< FAILURE! - in net.clouddeveloper.plaid.services.repository.VendorRepositoryTest
[ERROR] addVendor  Time elapsed: 8.052 s  <<< ERROR!
org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
        at net.clouddeveloper.plaid.services.repository.VendorRepositoryTest.addVendor(VendorRepositoryTest.java:84)
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
        at net.clouddeveloper.plaid.services.repository.VendorRepositoryTest.addVendor(VendorRepositoryTest.java:84)
Caused by: org.postgresql.util.PSQLException: 
ERROR: relation "vendor_tbl_vendor_id_seq" does not exist
  Position: 17
        at net.clouddeveloper.plaid.services.repository.VendorRepositoryTest.addVendor(VendorRepositoryTest.java:84)

[ERROR] validateDatabaseRunning  Time elapsed: 0.005 s  <<< ERROR!
java.lang.IllegalStateException: Mapped port can only be obtained after the container is started
        at net.clouddeveloper.plaid.services.repository.VendorRepositoryTest.performQuery(VendorRepositoryTest.java:56)
        at net.clouddeveloper.plaid.services.repository.VendorRepositoryTest.validateDatabaseRunning(VendorRepositoryTest.java:46)

根據我對錯誤的理解,Spring Boot 找不到表的順序,測試不能證明不能證明容器正在運行。

Docker 環境 這是我創建圖像的方式:

docker run --name plaid_postgres2 --rm -d -p 54321:5432 -e POSTGRES_PASSWORD=postgres  -e POSTGRES_DB=ach  postgres 

這更多的是環境設置。 端口和安裝

這是我設置應用程序屬性的方式:

# database connectivity
spring.jpa.open-in-view=true
spring.jpa.database=POSTGRESQL
spring.datasource.platform=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.url=jdbc:postgresql://localhost:54321/ach
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.use-new-id-generator-mappings=false
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true

這是實體聲明。 注意我在 Postgres 中為特定表使用了一個序列。

@Entity
@Table(schema = "investor", name="vendor_tbl")
public class Vendor  implements Serializable {


    private static final long serialVersionUID = -2343243243242432341L;
    @Id
    @Column(name="vendor_id")
    @SequenceGenerator(schema="investor",
                       name="vendor_tbl_vendor_id_seq",
                       sequenceName="vendor_tbl_vendor_id_seq",
                       allocationSize=1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE,  generator="vendor_tbl_vendor_id_seq")
    private long vendor_id;

這是我的測試 Class:

public class VendorRepositoryTest {

    @Autowired
    private VendorRepository repository;


   @Container
    private static final PostgreSQLContainer postgresqlContainer = new PostgreSQLContainer()
            .withDatabaseName("ach")
            .withUsername("postgres")
            .withPassword("postgres");


    @Test
    @DisplayName("Validate Database is Running")
    void validateDatabaseRunning() throws Exception {
        ResultSet resultSet = performQuery(postgresqlContainer, "SELECT 1");
        resultSet.next();
        int result = resultSet.getInt(1);
        assertEquals(1, result);

        assertTrue(postgresqlContainer.isRunning());
    }

    private ResultSet performQuery(PostgreSQLContainer protgres, String query) throws SQLException {

        String jdbcURL = postgresqlContainer.getJdbcUrl();
        String userName = postgresqlContainer.getUsername();
        String password = postgresqlContainer.getPassword();
        Connection conn = DriverManager.getConnection(jdbcURL, userName, password);
        return conn.createStatement().executeQuery(query);

    }


    @Test
    @DisplayName("Test Find All Vendors")
    public void find_all_vendors() {
        Iterable<Vendor> vendors = repository.findAll();

        int numOfCities =4;
        assertThat(vendors).isEmpty(); //.hasSize(numOfCities);
    }

    @Test
    @DisplayName("Test Add Vendor")
    public void addVendor(){
        String clientID = "blahblahblah";
        String secret_key = "blahblah";
        String public_key = "blahblah";
        String environment = "blah";
        String vendor_name = "Russ Test";
        Vendor vendor1 = new Vendor(clientID, secret_key, public_key, environment, vendor_name);
        Vendor vendor2 = new Vendor(clientID, secret_key, public_key, environment, vendor_name);
        this.repository.save(vendor1);
        this.repository.save(vendor2);
    }


}

在尋找答案兩天后,我失去了如何解決的方向。 任何建議或指導將不勝感激。

謝謝,

拉斯

您不必使用 Dockerfile 但您需要定義並傳遞給 Docker 容器用戶名、密碼和數據庫名稱。 您也可以在運行命令中執行此操作:

docker run --rm --name postgresContainer -d -p 54320:5432 -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=yourDatabase postgres

默認用戶名是 postgres,因此您無需指定。 命令中的最后一個 postgres 單詞是圖像的名稱

我也以不同的方式調用 yourDatabase,因為我認為 postgres 中有一個名為 postgres 的默認數據庫。

運行上述命令后,您可以執行以下命令來檢查您的數據庫是否正在運行:

docker exec -it postgresContainer bash

su postgres

psql

\list

這將顯示所有可用的數據庫。 現在輸入:

\c yourDatabase

並且您已連接到 postgres Docker 中的數據庫。 隨意運行創建表/選擇或其他任何東西。

要退出只需鍵入\qexit 2 次。 容器將繼續運行。


不要忘記更新您的 spring 屬性以匹配

spring.datasource.url=jdbc:postgresql://localhost:54320/yourDatabase
spring.datasource.username=postgres
spring.datasource.password=postgres

另外我認為您應該從 java 代碼中刪除schema參數,我從未使用過它,恐怕它會開始搜索“投資者”數據庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM