Eclipselink 更新现有表

Posted

技术标签:

【中文标题】Eclipselink 更新现有表【英文标题】:Eclipselink update existing tables 【发布时间】:2011-02-26 02:32:29 【问题描述】:

也许我弄错了,但我虽然 JPA 能够更新现有表(模型更改添加一列)但在我的情况下不起作用。

我可以在日志中看到 eclipselink 尝试创建它但由于它已经存在而失败。而不是尝试更新以添加它继续进行的列。

<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jwrestling"/>
<property name="javax.persistence.jdbc.password" value="password"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="user"/>
<property name="eclipselink.ddl-generation" value="create-tables"/>
<property name="eclipselink.logging.logger" value="org.eclipse.persistence.logging.DefaultSessionLog"/>
<property name="eclipselink.logging.level" value="INFO"/>

这是有变化的表格(添加了在线列)

[EL 警告]:2010-05-31 14:39:06.044--ServerSession(16053322)--异常 [EclipseLink-4002] (Eclipse Persistence Services - 2.1.0.v20100517-r7246): org.eclipse.persistence.exceptions .DatabaseException 内部异常:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:表“帐户”已存在 错误代码:1050 调用:CREATE TABLE 帐户(ID INTEGER NOT NULL、USERNAME VARCHAR(32) NOT NULL、SECURITY_KEY VARCHAR(255) NOT NULL、EMAIL VARCHAR(64) NOT NULL、STATUS VARCHAR(8) NOT NULL、TIMEDATE DATETIME NOT NULL、PASSWORD VARCHAR (255) NOT NULL, ONLINE TINYINT(1) 默认 0 NOT NULL, PRIMARY KEY (ID)) 查询:DataModifyQuery(sql="CREATE TABLE account (ID INTEGER NOT NULL, USERNAME VARCHAR(32) NOT NULL, SECURITY_KEY VARCHAR(255) NOT NULL, EMAIL VARCHAR(64) NOT NULL, STATUS VARCHAR(8) NOT NULL, TIMEDATE DATETIME NOT NULL, PASSWORD VARCHAR(255) NOT NULL, ONLINE TINYINT(1) 默认 0 NOT NULL, PRIMARY KEY (ID))") [EL 警告]:2010-05-31 14:39:06.074--ServerSession(16053322)--异常 [EclipseLink-4002] (Eclipse Persistence Services - 2.1.0.v20100517-r7246): org.eclipse.persistence.exceptions .DatabaseException

在此之后,它会继续以下操作。

我做错了什么还是一个错误?

【问题讨论】:

【参考方案1】:

从 EclipseLink 2.4 开始,您可以在持久性单元的规范中使用它:

<property name="eclipselink.ddl-generation" value="create-or-extend-tables" />

【讨论】:

【参考方案2】:

这是使用 create-tables 值时的预期行为。从有关eclipselink.ddl-generation 属性的文档中:

Using EclipseLink JPA Extensions for Schema Generation

以下是有效值 在persistence.xml 文件中的使用:

none – EclipseLink 不生成 DDL;没有生成架构。 create-tables – EclipseLink 将尝试执行 CREATE TABLE 每个表的 SQL。如果表 已经存在,EclipseLink 将 遵循您的默认行为 特定的数据库和 JDBC 驱动程序 组合(当CREATE TABLE SQL 为已经存在的 桌子)。在大多数情况下,一个例外是 抛出并且没有创建表。 然后 EclipseLink 将继续 下一个声明。 (也可以看看 eclipselink.create-ddl-jdbc-file-name.) drop-and-create-tables - EclipseLink 将尝试DROP all 表,然后CREATE 所有表。如果 遇到任何问题, EclipseLink 将遵循默认设置 您的特定数据库的行为和 JDBC驱动组合,然后继续 与下一个声明。 (也可以看看 eclipselink.create-ddl-jdbc-file-nameeclipselink.drop-ddl-jdbc-file-name.)

所以你可能想要drop-and-create-tables

【讨论】:

我想保留我当前的数据。有什么方法可以更新现有表(alter 语句)。没有相当于hibernate的更新选项? @javydreamercsw 我不知道有直接的等价物。 @PascalThivent 这是一个旧的,但看看接受的答案。他们似乎在您回答后添加了它。您可能想要更新它。【参考方案3】:

Hibernate JPA 实现完全符合您的要求。这是启用该行为的属性:

property name="hibernate.hbm2ddl.auto" value="update"

【讨论】:

我知道这一点,但我希望在标准 JPA 和/或 JPA2 中有所作为 我意识到在现实生活中,我不需要更新表格。如果我仍在开发中,那么我可以随时删除并创建表格。如果表有数据并且我不想删除它,那么自己更改表是一种更好的做法。这主要是在我不希望表自动更新的实时环境中。 @joshua:实际上,即使在实时系统上也有更新数据库结构的解决方案,但它们在 JPA/Hibernate 之外。一种解决方案是 Google Flyway (code.google.com/p/flyway);或 google 搜索“数据库版本控制”、“数据库迁移”。 Flyway 看起来很有趣。添加到我的工具中。谢谢!把它作为一个答案,你应该是我选择的那个。【参考方案4】:

创建或扩展表可以解决问题

【讨论】:

以上是关于Eclipselink 更新现有表的主要内容,如果未能解决你的问题,请参考以下文章

EclipseLink/JPA 是不是有用于修改生成的 SQL 的插件框架?

Wildfly 9 上的部署失败

Eclipselink 未检测到脏实体

添加带有 JPA 注释的现有方法签名的接口会破坏 Eclipselink

使用 JPA 2.1、EclipseLink、JSF 2.0 的日志表

JPA + EclipseLink+ HSQLDB 不创建表