JPA和TopLink如何在表不存在时创建表?

6

看起来jpa是一个让我产生很多问题的东西。

添加了这个之后

<property name="toplink.ddl-generation" value="create-tables"/>

我的JPA应用程序每次运行时都会创建表,如果表已经存在,则会导致异常。我希望JPA检查表是否已经存在,如果不存在则创建它们,但是我无法找到可以做到这一点的属性值。
因此,如果我关闭它,是否有方法可以在某个时间点手动告诉JPA创建所有表格?
更新:这是我得到的异常。
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'tags' already exists
Error Code: 1050
Call: CREATE TABLE tags (ID BIGINT AUTO_INCREMENT NOT NULL, NAME VARCHAR(255), OCCURRENCE INTEGER, PRIMARY KEY (ID))

MySQLSyntaxErrorException?!这肯定是错误的


你最终是忽略了打印的异常还是采取了一些变通方法? - simgineer
看看我提出这个问题的时间...解决这个问题的一种方法可能是扩展构建脚本,在构建/部署之前删除表。 - Nils
3个回答

5
根据http://www.oracle.com/technology/products/ias/toplink/JPA/essentials/toplink-jpa-extensions.html#Java2DBSchemaGen,toplink没有更新现有表的选项,即使有这个选项,我也不确定它是否能够正确处理。 您可以配置toplink生成一个SQL脚本,然后手动执行以创建所有表格。文件名和位置可以像这样配置:
<property name="toplink.ddl-generation" value="create-tables"/>
<property name="toplink.ddl-generation.output-mode" value="sql-script"/>
<property name="toplink.create-ddl-jdbc-file-name" value="createDDL.sql"/>
<property name="toplink.drop-ddl-jdbc-file-name" value="dropDDL.sql"/>
<property name="toplink.application-location" value="/tmp"/>

2
我希望[JPA提供程序]检查表是否已经存在,如果不存在则创建它们,但是我找不到上述属性的值来实现这一点。
奇怪的是,根据TopLink Essentials文档中关于toplink.ddl-generation扩展的说明,create-table应该保持现有表不变。

TopLink JPA扩展用于模式生成

指定您要为JPA实体执行的数据描述语言(DDL)生成操作。要指定DDL生成目标,请参见toplink.ddl-generation.output-mode

有效值:oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider

如果您正在使用EJB容器外的持久性,并希望在不创建表的情况下创建DDL文件,还需要定义一个Java系统属性INTERACT_WITH_DB并将其值设置为false


我这里没有使用EJB(甚至没有应用服务器),只是在运行时注意到了一些异常,并且数据库已经存在,但感谢您指出这一点。 - Nils
@Nils:我不确定是否理解你的评论。上述内容也适用于在Java SE环境中使用TopLink Essentials作为JPA提供程序,我认为你可能误读了文档的最后一句话。这个回答严格涵盖了你在这里提出的问题(并不是关于更新现有表格的问题)。 - Pascal Thivent

0

Liquibase (http://www.liquibase.org) 在这方面非常出色。虽然需要一些时间来完全掌握它,但我认为它值得投入精力。

Liquibase 的方式与使用哪个 JPA 持久化提供程序无关。实际上,它甚至是与数据库无关的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接