[英]spring boot container not running because of dependancy on postgres container
[英]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 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 中的數據庫。 隨意運行創建表/選擇或其他任何東西。
要退出只需鍵入\q
並exit
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.