修改persistence.xml适配PostgreSQL,解决非Spring Boot应用Heroku部署问题
Hey there! I get it—trying to adapt a Spring Boot tutorial for a plain Spring app can be tricky, especially when it comes to environment variables on Heroku. Let's break down what's going wrong and how to fix your persistence.xml setup.
The Core Issue
Spring Boot automatically handles ${variable} placeholders in application.properties by pulling values from environment variables. But plain Spring apps don't have this built-in support, so your persistence.xml isn't resolving JDBC_DATABASE_URL, JDBC_DATABASE_USERNAME, and JDBC_DATABASE_PASSWORD to Heroku's actual database credentials.
Fixes to Try
Option 1: Use Maven/Gradle Resource Filtering (Build-Time Replacement)
This approach lets your build tool replace the placeholders in persistence.xml with Heroku's environment variables during deployment.
For Maven:
Add this to your pom.xml to enable filtering on your persistence.xml:
<build> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <includes> <include>META-INF/persistence.xml</include> </includes> </resource> </resources> </build>
Your existing persistence.xml can stay as-is—Maven will automatically replace the ${...} placeholders with the corresponding environment variables when Heroku builds your app.
Note for local development: You can pass local database credentials via Maven commands, like:
mvn clean install -DJDBC_DATABASE_URL=jdbc:postgresql://localhost:5432/your_db -DJDBC_DATABASE_USERNAME=your_user -DJDBC_DATABASE_PASSWORD=your_pass
Option 2: Pass Environment Variables as System Properties (Runtime Replacement)
Hibernate can resolve ${variable} placeholders from system properties. So you can map Heroku's environment variables to system properties when starting your app.
Step 1: Keep your persistence.xml unchanged
Your current configuration is correct—Hibernate will pick up the system properties if they're set.
Step 2: Update your Heroku startup command
Create a Procfile in your project root with this command (adjust the jar name to match your app):
web: java -DJDBC_DATABASE_URL=$JDBC_DATABASE_URL -DJDBC_DATABASE_USERNAME=$JDBC_DATABASE_USERNAME -DJDBC_DATABASE_PASSWORD=$JDBC_DATABASE_PASSWORD -jar target/your-app-name.jar
This command takes Heroku's environment variables and passes them as Java system properties, which Hibernate will use to populate the persistence.xml values.
Additional Checks
- PostgreSQL Driver Dependency: Make sure you have the PostgreSQL driver in your
pom.xml(orbuild.gradle):<dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.6.0</version> <!-- Use the latest stable version --> </dependency> - Verify Persistence Unit Name: Double-check that your code references the correct persistence unit name (
passwordsPersistenceUnit) when creating anEntityManagerFactory. - Heroku PostgreSQL Add-on: Ensure you've added the PostgreSQL add-on to your Heroku app:
heroku addons:create heroku-postgresql:hobby-dev
Either of these options should get your persistence.xml working with Heroku's environment variables. Give them a try and let me know if you run into any snags!
内容的提问来源于stack exchange,提问作者Piotr Dawidziuk

