如何解决使用Spring Boot连接运行Postgres的现有Docker容器
我的目标是:使用运行Postgres数据库的Docker容器。使用此容器来构建Spring Services和数据访问层。所有这些都在我的本地环境中。
我正在通过Docker容器设置Postgres数据库。我已经启动了容器。我已经创建了表,视图,触发器,序列等。据我所知,它工作正常。我可以使用pgAdmin进行连接。
我现在开始为单个表设置Spring Boot,存储库,模型和单元测试。该测试仅将几条记录插入表中。我尝试了以下几个示例,教程和博客。
当我使用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;
这是我的测试班:
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,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
两次即可。容器将继续运行。
别忘了更新弹簧属性以匹配
spring.datasource.url=jdbc:postgresql://localhost:54320/yourDatabase
spring.datasource.username=postgres
spring.datasource.password=postgres
我还认为您应该从Java代码中删除schema
参数,因为我从未使用过它,因此恐怕它将开始搜索“投资者”数据库。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。