Spring Boot에서 Heroku Postgres에 연결
JPA/하이버네이트를 사용하여 스프링 부트 앱에서 헤로쿠 포스트그레스에 연결하는 가장 간단하고 깨끗한 방법을 찾고 있습니다.
Heroku 또는 Spring Boot 설명서에서 이 조합에 대한 좋은 완전한 예제가 보이지 않으므로 스택 오버플로에 대해 문서화하려고 합니다.
저는 다음과 같은 것을 시도하고 있습니다.
@Configuration
public class DataSourceConfig {
Logger log = LoggerFactory.getLogger(getClass());
@Bean
@Profile("postgres")
public DataSource postgresDataSource() {
String databaseUrl = System.getenv("DATABASE_URL")
log.info("Initializing PostgreSQL database: {}", databaseUrl);
URI dbUri;
try {
dbUri = new URI(databaseUrl);
}
catch (URISyntaxException e) {
log.error(String.format("Invalid DATABASE_URL: %s", databaseUrl), e);
return null;
}
String username = dbUri.getUserInfo().split(":")[0];
String password = dbUri.getUserInfo().split(":")[1];
String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + ':'
+ dbUri.getPort() + dbUri.getPath();
// fully-qualified class name to distuinguish from javax.sql.DataSource
org.apache.tomcat.jdbc.pool.DataSource dataSource
= new org.apache.tomcat.jdbc.pool.DataSource();
dataSource.setUrl(dbUrl);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
저는 제가 원하는 것과 잘 맞는 프로파일을 사용하고 있습니다: 헤로쿠에서.SPRING_PROFILES_ACTIVE
으로 설정됨postgres
을 하는 .spring.profiles.active
이라h2
H2 인 메모리 데이터베이스를 사용합니다(여기에서는 구성이 생략됨).이 방법은 잘 작동하는 것 같습니다.
application-postgres.properties
(프로파일별 속성):
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.driverClassName=org.postgresql.Driver
DataSource
Tomcat은 기본 종속성에 포함되어 있고 Spring Boot 참조 가이드에 다음과 같이 나와 있기 때문에 좋은 옵션처럼 보였습니다.
성능과 동시성을 위해 Tomcat 풀링 데이터 소스를 선호하기 때문에 가능하다면 항상 선택합니다.
있어요.BasicDataSource
스프링 부트와 함께 사용되는 Commons DBCP에서.그러나 기본 종속성에 Commons DBCP가 포함되어 있지 않기 때문에 이것이 가장 깨끗한 선택으로 보이지 않습니다.그리고 일반적으로 2015년에 Apache Commons가 Postgres에 연결하는 권장 방법이 될 수 있는지 궁금합니다.또한 헤로쿠 문서는 "BasicDataSource
이러한 시나리오에 대해 "봄에"; 나는 봄 자체에서 그러한 클래스를 보지 않기 때문에 이것이 Commons DBCP를 가리키는 것이라고 추측합니다.)
종속성:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.4-1205-jdbc42</version>
</dependency>
현재 상태: "DriverClassName 속성이 null인 JDBC 드라이버를 로드하지 않음"으로 인해 실패했습니다.
eConfig$$EnhancerBySpringCGLIB$$463388c1 : Initializing PostgreSQL database: postgres:[...]
j.LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found
[...]
o.a.tomcat.jdbc.pool.PooledConnection : Not loading a JDBC driver as driverClassName property is null.
o.a.tomcat.jdbc.pool.PooledConnection : Not loading a JDBC driver as driverClassName property is null.
[...]
org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect
로그에서 나는 그것을 봅니다.postgresDataSource
그냥 좋아요, 그리고 그 포스트그리는.SQL Dialect가 사용 중입니다(이 기능이 없으면 "방언 해상도 액세스"가 실패했습니다).'hibernate.dialect'가 설정되지 않은 경우 정보는 null일 수 없습니다.").
나의 구체적인 질문
- 어떻게 하면 잘 될 수 있을까요?설정 중입니다.
spring.datasource.driverClassName
그렇다면 "driverClassName 속성이 null이므로 JDBC 드라이버를 로드하지 않음"은 이유는 무엇입니까? - Tomcat을 입니까?
DataSource
좋아요, 아니면 다른 것을 추천하시겠습니까? - 정의할 필요가 있습니까?
postgresql
위와 같은 특정 버전과의 종속성?(이것이 없으면 "적절한 드라이버를 찾을 수 없습니다" 오류가 발생했습니다.) - (자바 코드 및/또는 속성을 고수하면서) 이 모든 것을 할 수 있는 더 간단한 방법이 있습니까? XML은 필요 없습니다.
Heroku & Postgres와 함께하는 가장 간단한 스프링 부트 2.x 청소 방법
저는 모든 답을 읽었지만 Jonik이 무엇을 찾고 있는지 찾지 못했습니다.
JPA/Hibernate를 사용하여 봄 부팅 앱에서 Heroku Postgres에 연결하는 가장 간단하고 깨끗한 방법을 찾고 있습니다.
대부분의 사람들이 Spring Boot & Heroku와 함께 사용하기를 원하는 개발 프로세스에는 테스트 및 빠른 개발 주기를 위한 로컬 H2 인 메모리 데이터베이스와 Heroku에서 스테이징 및 프로덕션을 위한 Heroku Postgres 데이터베이스가 포함되어 있습니다.
- 첫 번째는 스프링 프로필을 사용할 필요가 없다는 것입니다!
- 두 번째: 코드를 작성/변경할 필요가 없습니다!
우리가 해야 할 일을 차근차근 살펴보도록 하겠습니다.Postgres를 위해 완전히 작동하는 Heroku 배포 및 구성을 제공하는 예제 프로젝트가 있습니다. github.com/jonashackt/spring-boot-vuejs .
pom.xml
다음과 같은 종속성이 필요합니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- In-Memory database used for local development & testing -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<!-- Switch back from Spring Boot 2.x standard HikariCP to Tomcat JDBC,
configured later in Heroku (see https://stackoverflow.com/a/49970142/4964553) -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</dependency>
<!-- PostgreSQL used in Staging and Production environment, e.g. on Heroku -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.2</version>
</dependency>
여기서 한 가지 까다로운 점은 의 사용입니다.tomcat-jdbc
잠시 후에 말씀드리겠습니다.
Heroku에서 환경 변수 구성
Heroku 환경에서는 변수 이름이 지정됩니다.Config Vars
맞습니다. 이제 환경 변수를 구성하기만 하면 됩니다.우리는 정확한 것만 있으면 됩니다.따라서 https://data.heroku.com/ 으로 이동합니다(이미 Heroku 앱용으로 구성된 Postgres 데이터베이스가 있으며 이는 기본 동작입니다).
이제 프로그램의 해당 항목을 클릭합니다.Datastore
고리다로전다니환합으음으로 합니다.Settings
tab.그에 를 하세요.View Credentials...
다음과 같이 유사하게 보여야 합니다.
새 의 Heroku 응용 프로그램으로 합니다.Settings
탭도 있습니다.을 Reveal Config Vars
다음 환경 변수를 생성합니다.
SPRING_DATASOURCE_URL
jdbc:postgresql://YourPostgresHerokuHostName여기:5432/YourPostgresHerokuDatabaseName여기(앞에 주의)jdbc:
리고그고.ql
에postgres
!)SPRING_DATASOURCE_USERNAME
귀하의 사용자 이름Heroku 사용자 이름여기서SPRING_DATASOURCE_PASSWORD
당신의 는 Password Here Heroku입니다.SPRING_DATASOURCE_DRIVER-CLASS-NAME
=org.postgresql.Driver
(Spring Boot은 URL에서 대부분의 데이터베이스에 대해 이를 추론할 수 있기 때문에 항상 필요한 것은 아닙니다.)SPRING_JPA_DATABASE-PLATFORM
=org.hibernate.dialect.PostgreSQLDialect
SPRING_DATASOURCE_TYPE
=org.apache.tomcat.jdbc.pool.DataSource
SPRING_JPA_HIBERNATE_DDL-AUTO
=update
은 당신의으로 당신의 테이블을 것입니다, - 을 할가 없기 입니다. 정말 좋습니다. 왜냐하면 당신은 허들을 사용할 필요가 없기 때문입니다.CREATE
SQL 문 또는 DDL 파일)
Heroku에서 이것은 다음과 같습니다.
이제 당신이 해야 할 일은 그것뿐입니다!구성 변수를 변경할 때마다 Heroku 앱이 다시 시작되므로 이제 앱이 H2를 로컬로 실행하고 Postgre와 연결할 준비가 되어 있어야 합니다.Heroku에 배포할 경우 SQL.
만약 당신이 묻고 싶은 것.Hikari 대신 Tomcat JDBC를 구성하는 이유는 무엇입니까?
눈치채셨겠지만, 우리는 다음을 추가했습니다.tomcat-jdbc
및 pom.xml에 입니다.SPRING_DATASOURCE_TYPE=org.apache.tomcat.jdbc.pool.DataSource
환경 변수로 사용할 수 있습니다.이 말에 대한 문서에는 약간의 힌트가 있을 뿐입니다.
이 알고리즘을 완전히 무시하고 spring.datasource.type 속성을 설정하여 사용할 연결 풀을 지정할 수 있습니다.Tomcat 컨테이너에서 응용 프로그램을 실행하는 경우 특히 중요합니다.
스프링 부트 2.x 표준 HikariCP를 사용하는 대신 Tomcat 풀링 데이터 소스로 다시 전환한 몇 가지 이유가 있습니다.여기서 이미 설명했듯이, 만약 당신이 명시하지 않는다면,spring.datasource.url
은 우리의 Postgre im-memory H2 대신 하려고 할 입니다.SQL 1. 그고히카문오것한다입니다는지원만직리제는의리▁supports다▁sql▁it,것▁only만 지원한다는 것입니다.spring.datasource.jdbc-url
.
둘째, 만약 내가 히카리에 대해 표시된 것처럼 헤로쿠 구성을 사용하려고 한다면 (그래서 생략).SPRING_DATASOURCE_TYPE
그리고 변화.SPRING_DATASOURCE_URL
SPRING_DATASOURCE_JDBC-URL
과 같은 예외가
Caused by: java.lang.RuntimeException: Driver org.postgresql.Driver claims to not accept jdbcUrl, jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
그래서 저는 HikariCP와 함께 Heroku & Postgres를 작업하는 Spring Boot 2.x가 아니라 Tomcat JDBC와 함께 작업했습니다. 그리고 저는 또한 앞에서 설명한 로컬 H2 데이터베이스를 포함하는 개발 프로세스를 중단하고 싶지 않습니다.기억:우리는 JPA/하이버네이트를 사용하여 봄 부팅 앱에서 Heroku Postgres에 연결하는 가장 간단하고 깨끗한 방법을 찾고 있었습니다!
가장 단순한 스프링 부트 / Heroku / 최대 절전 모드 구성
▁▁apart을외.DATABASE_URL
Heroku는 Runtime에서 3개의 환경 변수를 생성합니다.다음과 같습니다.
JDBC_DATABASE_URL
JDBC_DATABASE_USERNAME
JDBC_DATABASE_PASSWORD
은 Spring Boot을 합니다.spring.datasource.*
application.properties
입니다. application.properties 파일입니다.
spring.datasource.url=${JDBC_DATABASE_URL}
spring.datasource.username=${JDBC_DATABASE_USERNAME}
spring.datasource.password=${JDBC_DATABASE_PASSWORD}
spring.jpa.show-sql=false
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
최대 절전 모드/최대 절전 모드 종속성
에는 HibernateHibernate" ("Hibernate" ("Hibernate"))를 사용합니다.spring-boot-starter-jpa
Postgre Postgre와 SQL을 사용하여 SQL에 했습니다.build.gradle
:
dependencies {
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile('org.postgresql:postgresql:9.4.1212')
}
데이터베이스 연결이 안정적으로 작동하도록 하기 위해 질문에서 설명한 설정에서 두 가지가 누락되었습니다.
- jny가 지적했듯이 JDBC 드라이버를 명시적으로 설정해야 했습니다.
dataSource.setDriverClassName("org.postgresql.Driver");
- 는 사용자 하고 Spring의 기본값을 하여 내 ("Spring"의 Spring"을
spring.datasource.driverClassName
효력이 없는 속성.그리고 Heroku의 동적 특성으로 인해 이를 작동시키기 위해 맞춤형 데이터 소스가 필요한 것으로 알고 있습니다.)
- 이 후 연결은 작동했지만 안정적이지 않았습니다. 저는 연결하기 시작했습니다.
org.postgresql.util.PSQLException: This connection has been closed.
앱이 잠시 실행된 후.다소 놀라운 솔루션(이 답변을 기반으로 함)은 Tomcat DataSource와 같은 특정 테스트를 활성화하는 것이었습니다.dataSource.setTestOnBorrow(true); dataSource.setTestWhileIdle(true); dataSource.setTestOnReturn(true); dataSource.setValidationQuery("SELECT 1");
그래서, 내 데이터 소스 구성의 고정 버전:
@Configuration
public class DataSourceConfig {
Logger log = LoggerFactory.getLogger(getClass());
@Bean
@Profile("postgres")
public DataSource postgresDataSource() {
String databaseUrl = System.getenv("DATABASE_URL")
log.info("Initializing PostgreSQL database: {}", databaseUrl);
URI dbUri;
try {
dbUri = new URI(databaseUrl);
}
catch (URISyntaxException e) {
log.error(String.format("Invalid DATABASE_URL: %s", databaseUrl), e);
return null;
}
String username = dbUri.getUserInfo().split(":")[0];
String password = dbUri.getUserInfo().split(":")[1];
String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + ':'
+ dbUri.getPort() + dbUri.getPath();
org.apache.tomcat.jdbc.pool.DataSource dataSource
= new org.apache.tomcat.jdbc.pool.DataSource();
dataSource.setDriverClassName("org.postgresql.Driver");
dataSource.setUrl(dbUrl);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setTestOnBorrow(true);
dataSource.setTestWhileIdle(true);
dataSource.setTestOnReturn(true);
dataSource.setValidationQuery("SELECT 1");
return dataSource;
}
}
이것만 들어 있는 상태에서.application-postgres.properties
:
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
이제, 제가 가진 두 가지 문제 모두 Tomcat의 데이터 소스에만 국한된 것일 수 있습니다.org.apache.tomcat.jdbc.pool
Basic DataSource(Commons DBCP)는 보다 합리적인 기본값을 가지고 있습니다.그러나 질문에서 언급했듯이, 저는 특히 참조 가이드에서 강력하게 지지하는 것처럼 기본적으로 스프링 부트와 함께 제공되는 것을 사용했습니다.
저는 경쟁력 있는/더 간단한/더 나은 솔루션을 선호합니다. 특히 질문의 마지막 부분에서 2-4개의 의문점을 해결할 수 있다면 언제든지 게시하십시오.
용사를 합니다.JDBC_DATABASE_*
대신
를 사용합니다. : 를 사용합니다.JDBC_DATABASE_*
이 답변에서 지적한 바와 같이 위보다 훨씬 단순합니다.오랫동안 나는 그들이 그들을DATABASE_URL
더 선호되어야 하지만, 요즘은 더 이상 확신할 수 없습니다.
JDBC_DATABASE_URL을 사용해 보십시오.spring.datasource.url
DATABASE_URL을 구문 분석하는 대신
DATABASE_URL을 구문 분석하는 것이 권장되지만 작동할 수 없는 경우 JDBC_DATABASE_URL은 정상입니다.
이것은 Heroku가 제공하는 샘플 Java Application에 대한 Postgres 문제에 대한 최고 답변입니다.
이 단계는 이를 실현하기 위해 수행한 것입니다(Windows 7).
1.) 운영 서버 application.properties 파일에 시스템 환경이 포함됩니다(이 파일이 커밋되었는지 확인).
spring.datasource.url=${JDBC_DATABASE_URL}
spring.datasource.username=${JDBC_DATABASE_USERNAME}
spring.datasource.password=${JDBC_DATABASE_PASSWORD}
2.) 이제 합니다.git update-index --assume-unchanged .\src\main\resources\application.properties
합니다.3.) application.properties를 변경합니다.은 raw 값을 할 수 .heroku run env
spring.datasource.url=jdbc://..
spring.datasource.username=XYZ
spring.datasource.password=ABC
이것은 제가 제 애플리케이션의 로컬 복사본을 작동시키기 위해 필요한 것입니다.더 좋은 방법을 찾은 사람이 있다면 공유해주세요!
@Configuration
@Component
public class HerokuConfigCloud {
private static final Logger logger =
LoggerFactory.getLogger(HerokuConfigCloud .class);
@Bean()
//@Primary this annotation to be used if more than one DB Config was used. In that case,
// using @Primary would give precedence to a the particular "primary" config class
@Profile("heroku")
public DataSource dataSource(
@Value("${spring.datasource.driverClassName}") final String driverClass,
@Value("${spring.datasource.url}") final String jdbcUrl,
@Value("${spring.datasource.username}") final String username,
@Value("${spring.datasource.password}") final String password
) throws URISyntaxException {
return DataSourceBuilder
.create()
.username(username)
.password(password)
.url(url)
.driverClassName(driverClass)
.build();
}
}
이것을 쉽게 하기 위해 도서관을 지었습니다: https://github.com/vic-cw/heroku-postgres-helper
빌드 스크립트와 응용프로그램 논리 모두에서 데이터베이스에 액세스해야 하는 경우 이 기능이 더욱 유용합니다.이유를 확인해 보십시오.
용도:
build.gradle:
// If using connection string in build script:
buildscript {
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
classpath 'com.github.vic-cw:heroku-postgres-helper:0.1.0'
}
}
import com.github.viccw.herokupostgreshelper.HerokuPostgresHelper;
// Use connection string in build script:
flyway {
url = HerokuPostgresHelper.getDatabaseJdbcConnectionString()
driver = 'org.postgresql.Driver'
}
// If using connection string inside application logic:
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
compile group: 'com.github.vic-cw', name: 'heroku-postgres-helper', version: '0.1.0'
}
Java 응용 프로그램 코드:
import com.github.viccw.herokupostgreshelper.HerokuPostgresHelper;
...
String databaseConnectionString = HerokuPostgresHelper.getDatabaseJdbcConnectionString();
언급URL : https://stackoverflow.com/questions/33633243/connecting-to-heroku-postgres-from-spring-boot
'source' 카테고리의 다른 글
Sublime Text를 Git의 기본 편집기로 만들려면 어떻게 해야 합니까? (0) | 2023.06.26 |
---|---|
What's the difference between "squash" and "fixup" in Git/Git Extension? (0) | 2023.06.26 |
오라클에서 날짜는 어떻게 저장됩니까? (0) | 2023.06.26 |
하위 쿼리 문제별 Oracle SQL 순서 지정! (0) | 2023.06.26 |
ASP.NET에서 XML을 반환하는 방법은 무엇입니까? (0) | 2023.06.26 |