Java 应用程序必须提供JDBC连接—将Play2.4.2(使用JPA+;Hibernate)部署到Heroku

Java 应用程序必须提供JDBC连接—将Play2.4.2(使用JPA+;Hibernate)部署到Heroku,java,hibernate,jpa,heroku,playframework,Java,Hibernate,Jpa,Heroku,Playframework,我正在尝试将Play Framework(2.4.2)应用程序部署到Heroku。我正在使用JPA(Hibernate4.3.10和Postgres)。我也在运行JDK8 很抱歉发了这么长的帖子,但我想提供尽可能多的信息 我在尝试访问应用程序时遇到此错误: Caused by: java.lang.UnsupportedOperationException: The application must supply JDBC connections 2015-09-18T09:23:46.5331

我正在尝试将Play Framework(2.4.2)应用程序部署到Heroku。我正在使用JPA(Hibernate4.3.10和Postgres)。我也在运行JDK8

很抱歉发了这么长的帖子,但我想提供尽可能多的信息

我在尝试访问应用程序时遇到此错误:

Caused by: java.lang.UnsupportedOperationException: The application must supply JDBC connections
2015-09-18T09:23:46.533143+00:00 app[web.1]:    at org.hibernate.engine.jdbc.connections.internal.UserSuppliedConnectionProviderImpl.getConnection(UserSuppliedConnectionProviderImpl.java:61) ~[org.hibernate.hibernate-core-4.3.10.Final.jar:4.3.10.Final]
2015-09-18T09:23:46.533144+00:00 app[web.1]:    at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:380) ~[org.hibernate.hibernate-core-4.3.10.Final.jar:4.3.10.Final]
2015-09-18T09:23:46.533146+00:00 app[web.1]:    at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.obtainConnection(LogicalConnectionImpl.java:228) ~[org.hibernate.hibernate-core-4.3.10.Final.jar:4.3.10.Final]
2015-09-18T09:23:46.533147+00:00 app[web.1]:    at org.hibernate.engine.jdbc.internal.LogicalConnectionImpl.getConnection(LogicalConnectionImpl.java:171) ~[org.hibernate.hibernate-core-4.3.10.Final.jar:4.3.10.Final]
2015-09-18T09:23:46.533148+00:00 app[web.1]:    at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doBegin(JdbcTransaction.java:67) ~[org.hibernate.hibernate-core-4.3.10.Final.jar:4.3.10.Final]
2015-09-18T09:23:46.533149+00:00 app[web.1]:    at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.begin(AbstractTransactionImpl.java:162) ~[org.hibernate.hibernate-core-4.3.10.Final.jar:4.3.10.Final]
我在类中翻来覆去,它似乎工作正常,因为实现只是抛出了一个异常,这让我相信配置有问题,因为该类没有任何有用的功能,所以我永远不会到达该代码路径

我已经跟踪了有关的文档

因此,我的Procfile如下所示:

web: target/universal/stage/bin/myapp -Dhttp.port=${PORT} -DapplyEvolutions.default=false -Ddb.default.driver=org.postgresql.Driver -Ddb.default.url=${DATABASE_URL}
db.default.driver=org.postgresql.Driver
db.default.url=${?JDBC_DATABASE_URL}
db.default.username=${?JDBC_DATABASE_USERNAME}
db.default.password=${?JDBC_DATABASE_PASSWORD}
db.default.jndiName=myDS
jpa.default=myDS
我也尝试过(注意{}),但没有成功

web: target/universal/stage/bin/myapp -Dhttp.port=$PORT -DapplyEvolutions.default=false -Ddb.default.driver=org.postgresql.Driver -Ddb.default.url=$DATABASE_URL
My build.sbt文件包括postgres和hibernate:

libraryDependencies ++= Seq(
  javaJdbc,
  cache,
  javaWs,
  javaJpa,
  "org.hibernate" % "hibernate-entitymanager" % "4.3.10.Final",
  "org.postgresql" % "postgresql" % "9.4-1201-jdbc41" withSources(),
  //other stuff
)
我的
application.conf
包括以下内容:

web: target/universal/stage/bin/myapp -Dhttp.port=${PORT} -DapplyEvolutions.default=false -Ddb.default.driver=org.postgresql.Driver -Ddb.default.url=${DATABASE_URL}
db.default.driver=org.postgresql.Driver
db.default.url=${?JDBC_DATABASE_URL}
db.default.username=${?JDBC_DATABASE_USERNAME}
db.default.password=${?JDBC_DATABASE_PASSWORD}
db.default.jndiName=myDS
jpa.default=myDS
我的persistence.xml文件(在conf/META-INF中)如下所示(请阅读下文,了解此文件上没有url/user/password属性的原因):

我知道这个类正在运行,因为println出现在Heroku的日志中。我试过很多不同的方法,但都有不同程度的失败。我似乎很清楚,这与数据源/数据库的配置有关,但我一直无法确定,如果您能提供任何帮助,我将不胜感激

在本地,我有一个工作的应用程序,但使用标准的Play配置(没有数据库URL),我尝试在本地Play环境中匹配Heroku的配置,问题似乎是一样的

我在谷歌上搜索了很多(在stackoverflow上发现了几个问题,它们都有相同的症状,但我无法找到在我的特定情况下可能导致这种情况的原因)

编辑

通过@codefinger的指针和更多的谷歌搜索,我已经取得了突破,但我不明白为什么它是这样工作的

在尝试使应用程序在本地工作时,我发现它与数据库URL不兼容,因此我遵循@codefinger的建议,问题仍然存在(即运行
heroku local web
),但如果我在persistence.xml文件中有我的属性,则一切正常(运行
activator run
)。碰巧我在GlobalSettings文件中尝试了以下操作:

System.setProperty("javax.persistence.jdbc.url", System.getenv("JDBC_DATABASE_URL"));
System.setProperty("javax.persistence.jdbc.user", System.getenv("JDBC_DATABASE_USERNAME"));
System.setProperty("javax.persistence.jdbc.password", System.getenv("JDBC_DATABASE_PASSWORD"));
System.setProperty("javax.persistence.jdbc.driver", "org.postgresql.Driver");
System.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");

System.setProperty("hibernate.connection.driver_class", "org.postgresql.Driver");
System.setProperty("hibernate.connection.url", System.getenv("JDBC_DATABASE_URL"));
System.setProperty("hibernate.connection.username", System.getenv("JDBC_DATABASE_USERNAME"));
System.setProperty("hibernate.connection.password", System.getenv("JDBC_DATABASE_PASSWORD"));
通过传递
javax.persistence.*
hibernate.connection.*
连接属性,显然它现在可以访问数据库了。 但我似乎无法理解,在本地运行时,仅使用
persistence.xml
文件上的
javax.persistene.*
属性,它工作正常


我正在继续我的实验,试图找到合适的配置。

您是否使用
数据库URL
环境变量在本地进行了测试?我不确定您对
数据库URL
的解析是否正确。下面是一个示例,您可以将其包含在
build.sbt
中,如下所示:

"com.heroku.sdk" % "heroku-jdbc" % "0.1.1"
一般来说,它是这样做的:

val dbUri = new URI(System.getenv("DATABASE_URL"))
val username = dbUri.getUserInfo.split(":")(0)
val password = dbUri.getUserInfo.split(":")(1)
val dbUrl = s"jdbc:postgresql://${dbUri.getHost}:${dbUri.getPort()}${dbUri.getPath}"
或者,您可以在
Global
类中使用
JDBC\u DATABASE\u URL
(注意,下面的代码只是示例,因为它没有检查
null
s):

我建议在项目根目录中的文件
.env
中添加一个
数据库\u URL
条目,如下所示:

DATABASE_URL=postgres://user:pass@localhost:5432/dbName
然后使用
sbt stage
构建应用程序,并使用
heroku本地网站运行它。这将使您能够轻松地使用
数据库\u URL
进行测试


Heroku
数据库的URL
实际上遵循。但是大多数JDBC库只使用JDBC URL。

谢谢你的回复codefinger,有了你的输入,我无法让它工作,但它让我走上了一条不同的道路。我已经把我的发现贴在了原来的帖子上,你知道会是什么吗?
DATABASE_URL=postgres://user:pass@localhost:5432/dbName