【问题标题】:Hibernate unable to create schema automatically on Heroku postgresHibernate 无法在 Heroku postgres 上自动创建模式
【发布时间】:2016-11-06 20:03:46
【问题描述】:

我有一个 play 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>

过程文件

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

【问题讨论】:

    标签: hibernate postgresql heroku playframework java-8


    【解决方案1】:

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

    db.default.url=${?JDBC_DATABASE_URL}
    

    欲了解更多信息,请参阅Heroku DevCenter

    【讨论】:

    • 我试过它确实有效,事实上我尝试回显上面的变量它什么都不显示,但 heroku 配置显示了 DATABASE_URL 的值。这就是我使用它的原因。同样在检查heroku日志时,Heroku postgres db已连接但未创建表。
    • $ heroku buildpacks 的输出是什么?
    • 抱歉,在 Windows 上运行 heroku run "echo $JDBC_DATABASE_URL"(无需转义 $
    • 更新问题。我尝试使用JDBC_DATABASE_URL 部署到heroku,但它的行为与DATABASE_URL 相同,应用程序已启动但未创建表
    • 我认为检查 JDBC_DATABASE_URL 时的错误是侥幸。无论如何,我现在不确定。我添加了另一个答案尝试
    【解决方案2】:

    我不确定 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

    【讨论】:

    • 再次感谢您的帮助。我遇到了同样的问题,我从 pgAdmin 连接了我的 heroku db,我已经添加了你的代码,但它仍然没有在 pgAdmin 中显示任何表。使用本地数据库它运行良好。我想我缺少一些配置,但找不到。
    【解决方案3】:

    终于想通了。

    我没有仔细阅读Play 2.4.x JavaJPA docs


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

    PlayKeys.externalizeResources := false
    

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

    【讨论】:

      【解决方案4】:

      如果你使用标志

      PlayKeys.externalizeResources := false
      

      分发 zip 是在没有 conf 文件夹的情况下创建的,因此不包含 META-INF/persistence.xml 文件。我猜在这种情况下,Play 通过扫描所有 DB 注释来检测 JPA 模型。 如果您在 conf 文件夹中有用于现场编辑的配置文件,则不适合没有 conf 文件夹的分发包。

      要在没有 PlayKeys.externalizeResources 标志的情况下解决您的数据库问题,您应该将您的数据库模型映射添加到 persistence.xml。请参阅another answer中的示例

      【讨论】:

      • 感谢您的帮助,它成功了。你能把我链接到一些官方来源吗,因为我在这里很困惑。你说在我的情况下 conf 没有创建,这是否意味着对 appication.conf 的任何更改都不会在生产中起作用,因为没有创建 conf 文件夹。
      • 您可以在 PlayKeys.externalizeResources 的值之后阅读您发现的那个链接 (playframework.com/documentation/2.4.x/…)。您的配置将嵌入到 jar 中,内容与源相同,但不可编辑。这就是为什么我不使用这种技术的原因。
      猜你喜欢
      • 2015-08-03
      • 1970-01-01
      • 1970-01-01
      • 2013-11-17
      • 1970-01-01
      • 2018-10-17
      • 1970-01-01
      • 2016-01-16
      • 2020-07-23
      相关资源
      最近更新 更多