Java 应用程序必须提供JDBC连接—将Play2.4.2(使用JPA+;Hibernate)部署到Heroku
我正在尝试将Play Framework(2.4.2)应用程序部署到Heroku。我正在使用JPA(Hibernate4.3.10和Postgres)。我也在运行JDK8 很抱歉发了这么长的帖子,但我想提供尽可能多的信息 我在尝试访问应用程序时遇到此错误: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
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