Hibernate无法在Heroku postgres上自动创建架构

时间:2016-07-05 05:26:24

标签: hibernate postgresql heroku playframework java-8

我有一个2.4 hibernate postgresql应用程序,它在本地运行良好,最初自动创建一个表。但是当部署在heroku上时,它不会创建任何表,尽管应用程序加载时没有任何错误(从pgAdmin连接我的heroku数据库)。我的配置

build.sbt

name := "lms"

version := "1.0"

lazy val `lms` = (project in file(".")).enablePlugins(PlayJava)

scalaVersion := "2.11.7"

libraryDependencies ++= Seq(javaJdbc, cache, javaWs,
  javaJpa.exclude("org.hibernate.javax.persistence", "hibernate-jpa-2.0-api"),
  "postgresql" % "postgresql" % "9.1-901-1.jdbc4",
  "org.hibernate" % "hibernate-entitymanager" % "5.0.1.Final",
  "net.sf.dozer" % "dozer" % "5.4.0")

unmanagedResourceDirectories in Test <+= baseDirectory(_ / "target/web/public/test")

resolvers += "scalaz-bintray" at "https://dl.bintray.com/scalaz/releases"  

application.conf

# This is the main configuration file for the application.
# ~~~~~

# Secret key
# ~~~~~
# The secret key is used to secure cryptographics functions.
# If you deploy your application to several instances be sure to use the same key!
application.secret = "%APPLICATION_SECRET%"

# The application languages
# ~~~~~
application.langs = "en"

# Global object class
# ~~~~~
# Define the Global object class for this application.
# Default to Global in the root package.
# application.global=Global

# Router
# ~~~~~
# Define the Router object to use for this application.
# This router will be looked up first when the application is starting up,
# so make sure this is the entry point.
# Furthermore, it's assumed your route file is named properly.
# So for an application router like `my.application.Router`,
# you may need to define a router file `conf/my.application.routes`.
# Default to Routes in the root package (and conf/routes)
# application.router=my.application.Routes

# Database configuration
# ~~~~~
# You can declare as many datasources as you want.
# By convention, the default datasource is named `default`
#
db.default.driver=org.postgresql.Driver
db.default.url=${?DATABASE_URL}



db.default.jndiName = DefaultDS
jpa.default = defaultPersistenceUnit
db.default.hikaricp.connectionTestQuery="SELECT TRUE"
# Evolutions
# ~~~~~
# You can disable evolutions if needed
# evolutionplugin=disabled

# Logger
# ~~~~~
# You can also configure logback (http://logback.qos.ch/),
# by providing an application-logger.xml file in the conf directory.

# Root logger:
logger.root = ERROR

# Logger used by the framework:
logger.play = INFO

# Logger provided to your application:
logger.application = DEBUG


db.default.logStatements = true

的persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">

    <persistence-unit name="defaultPersistenceUnit" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <non-jta-data-source>DefaultDS</non-jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL82Dialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="javax.persistence.sql-load-script-source"
                      value="META-INF/sql/data.sql"/>
        </properties>

    </persistence-unit>

</persistence>

Procfile

web: target/universal/stage/bin/lms -Dhttp.port=${PORT} -Dplay.evolutions.db.default.autoApply=true -Ddb.default.url=${DATABASE_URL}

我最初需要做些更改才能在heroku postgres上创建数据库模式吗?可能是什么问题?

编辑:

E:\Projects\lms\LMS>heroku buildpacks
=== leadmanagementsystem Buildpack URL
heroku/scala

E:\Projects\lms\LMS>heroku config
=== leadmanagementsystem Config Vars
DATABASE_URL: postgres://aaa:111@dasdsfsv.compute-1.amazonaws.com:5432/dfregv

E:\Projects\lms\LMS>heroku run "echo $JDBC_DATABASE_URL"
Running echo $JDBC_DATABASE_URL on leadmanagementsystem... !
 !    ENOTFOUND: getaddrinfo ENOTFOUND api.heroku.com api.heroku.com:443

4 个答案:

答案 0 :(得分:1)

如果您使用旗帜

PlayKeys.externalizeResources := false

创建分发zip时没有 conf 文件夹,因此不包含META-INF / persistence.xml文件。我想在这种情况下,Play会通过扫描所有数据库注释来检测JPA模型。 如果您有 conf 文件夹配置文件(用于在网站上进行编辑),则不包含 conf 文件夹的分发包。

要修复没有标记 PlayKeys.externalizeResources 的数据库问题,您应该将数据库模型映射添加到 persistence.xml 。请参阅another answer

中的示例

答案 1 :(得分:0)

Hibernate无法识别vendor://user:password@host:port/db格式$DATABASE_URL。它需要JDBC URL。尝试将db.default.url更改为:

db.default.url=${?JDBC_DATABASE_URL}

有关详细信息,请参阅Heroku DevCenter

答案 2 :(得分:0)

我不确定Hibernate + Play是如何工作的,但如果我在传统的Java应用程序中使用Hibernate,我会像这样初始化EntityManager:

Map<String, String> env = System.getenv();
Map<String, Object> configOverrides = new HashMap<String, Object>();
for (String envName : env.keySet()) {
  if (envName.contains("JDBC_DATABASE_URL")) {
    configOverrides.put("javax.persistence.jdbc.url", env.get(envName));
  }
}

// provision persistence manager
entityManagerFactory = Persistence.createEntityManagerFactory("defaultPersistenceUnit", configOverrides);
entityManager = entityManagerFactory.createEntityManager();

也许Hibernate没有拿起db.default.url

答案 3 :(得分:0)

终于想通了。

我仔细阅读了Play 2.4.x JavaJPA docs

使用JPA在开发模式下运行Play工作正常,但是为了部署应用程序,您需要将其添加到build.sbt文件中。

PlayKeys.externalizeResources := false

添加以上行解决了这个问题。