Play + JPA + Hibernate + PostgreSQL:无法创建表

Posted

技术标签:

【中文标题】Play + JPA + Hibernate + PostgreSQL:无法创建表【英文标题】:Play + JPA + Hibernate + PostgreSQL: Cannot create Tables 【发布时间】:2015-07-06 06:21:46 【问题描述】:

我一直在尝试使用 Play Framework 2.4.0、JPA 和 Hibernate 4.3.9 创建一个简单而小型的应用程序,以连接到 PostgreSQL 9.4 数据库。我希望应用程序根据在应用程序上创建的模型创建新的数据库表。到目前为止,我还没有成功。

这是我的“build.sbt”的内容:

name := """aplicacion1"""

version := "1.0-SNAPSHOT"

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

scalaVersion := "2.11.6"

libraryDependencies ++= Seq(
  javaJdbc,
  cache,
  javaJpa,
  //"org.apache.directory.api" % "apache-ldap-api" % "1.0.0-M14",
  "postgresql" % "postgresql" % "9.1-901-1.jdbc4",
  "org.hibernate" % "hibernate-core" % "4.3.9.Final",
  "org.hibernate" % "hibernate-entitymanager" % "4.3.9.Final"

)

// Play provides two styles of routers, one expects its actions to be injected, the
// other, legacy style, accesses its actions statically.
routesGenerator := InjectedRoutesGenerator

这是我描述数据库连接的“application.conf”的内容:

db.default.driver=org.postgresql.Driver
db.default.url="postgres://postgres:passsuper@localhost/tesis_play1"
db.default.jndiName=DefaultDS
jpa.default=defaultPersistenceUnit

这是我的“persistence.xml”的内容:

<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.PostgreSQL9Dialect"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>

</persistence>

这是我试图进入数据库的小型模型类:

@Entity
public class ruta 

    @Id
    public int idRuta;
    public String nombre;
    public boolean esIda;
    public boolean esvuelta;
    public String apodo1;
    public String apodo2;
    public String ref;


应用程序编译并运行没有错误,但从未在数据库上创建“ruta”表。有什么我想念的吗?感谢您的帮助!

编辑:通过“localhost:9000”访问应用程序时,控制台上会出现以下内容:

[info] Compiling 2 Java sources to C:\Users\Enrique\Desktop\tesis_2\aplicacion1\target\scala-2.11\classes...
SLF4J: The following set of substitute loggers may have been accessed
SLF4J: during the initialization phase. Logging calls during this
SLF4J: phase were not honored. However, subsequent logging calls to these
SLF4J: loggers will work as normally expected.
SLF4J: See also http://www.slf4j.org/codes.html#substituteLogger
SLF4J: org.webjars.CloseQuietly
[info] - application - Creating Pool for datasource 'default'
[info] - play.api.db.HikariCPConnectionPool - datasource [jdbc:postgresql://localhost/tesis_play1] bound to JNDI as DefaultDS
[info] - play.api.db.DefaultDBApi - Database [default] connected at jdbc:postgresql://localhost/tesis_play1
[info] - play.api.libs.concurrent.ActorSystemProvider - Starting application default Akka system: application
[info] - play.api.Play$ - Application started (Dev)

【问题讨论】:

我不是 JPA 方面的专家,但可能在您的 application.conf 中 db.default.url 行是错误的:通常它看起来更像 jdbc:postgresql://localhost:5432/test_database 以及您可能需要的密码和用户名在附加行中定义db.default.user=myusernamedb.default.password=mypassword @Kris 我这样试过,但结果是一样的:仍然没有创建表:( 如果您将&lt;property name="hibernate.show_sql" value="true"/&gt; 添加到您的persistance.xml,您的日志中有什么内容? @Kris 你的意思是控制台输出?我得到的输出与我在原始问题末尾包含的相同。 【参考方案1】:

在创建 Hibernate SessionFactory 时调用生成的 hbm2ddl 数据库更改。启动应用程序不会创建 EntityManagerFactory 和底层 Hibernate SessionFactory

创建 EntityManagerFactory 时,将在第一次调用 JPA 时对数据库进行更改。要在您的应用启动时启动 EntityManagerFactory,只需使用 JPA 调用创建 Global class:

public class Global extends GlobalSettings 

    public void onStart(Application app) 

        JPA.withTransaction(new F.Callback0() 
            @Override
            public void invoke() throws Throwable 
                play.Logger.debug("First JPA call");
            
        );


    

    public void onStop(Application app) 
    


【讨论】:

我刚刚尝试了您的建议。在控制器包中创建了一个全局类,然后在 application.conf 中添加了“application.global = controllers.Global”,但仍然没有创建表:( 还尝试将全局类移动到默认包,但仍然没有结果跨度> 您是否在 Global.onStart 中包含了 JPA.withTransaction?我已经使用与您相同的配置进行了测试,并创建了表格。 是的,我包括在内。我不知道这是否重要,但在这个项目中,我有一个带有以下 jar 的“lib”目录:hibernate-spatial-4.3、jts-1.13、jtsio-1.13、postgis-jdbc-2.1.7、postgresql -9.4-1201.jdbc41。目前没有结果 我包含了一个简单的“System.out.println("GLOBAL");"在“onStart”方法的“invoke”方法中。它没有被打印出来。我猜应用程序启动时没有执行“onStart”方法。 忽略我最后的 2 个 cmets,这是我的错误:我在包含全局对象 ("Global.java") 的文件上进行了错误的导入。我正在使用“导入控制器。应用程序;” (这是 Play 在新项目上创建的默认控制器),而它必须是“import play.Application;”。非常感谢@Pawel!你刚刚把我的电脑从窗户里扔了出去:)【参考方案2】:

也许您可以尝试将其添加到您的persistence.xml

....
<property name="hibernate.archive.autodetection" value="class, hbm"/>
...

我自己不是 JPA 专家,但这似乎是您的 persistence.xml 与我在我的项目中拥有的唯一区别。根据docs,此属性将:

确定 Hibernate Entity Manager 在解析 .par 档案时自动发现的元素。 (默认为类,hbm)。

它说它应该默认为class,hbm,但我仍然会尝试。除此之外,我唯一可以推荐的另一件事是尝试在persistence.xml 中添加数据库驱动程序和凭据,例如:

<property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
<property name="hibernate.connection.password" value="foobar"/>
<property name="hibernate.connection.url" value="jdbc:h2:mem:play"/>
<property name="hibernate.connection.username" value="sa"/>

【讨论】:

刚刚将该行添加到persistence.xml,但仍然没有结果:( @Eduardo Weird.. 也许你可以尝试做一个 play clean 然后再次运行它 刚刚对项目进行了清理,但仍然没有结果

以上是关于Play + JPA + Hibernate + PostgreSQL:无法创建表的主要内容,如果未能解决你的问题,请参考以下文章

Play 2.4 JPA/Hibernate EntityManager 不刷新到数据库

使用 play framework 1.+ 指定图像名称(使用 play.db.jpa.blob)

配置 Play 1.x/JPA 以按顺序生成实体 ID?

hibernate jpa 报错

JPA和Threads在play框架中

JPA(Hibernate)