Eclipselink更新现有表

26

也许我理解错了,但我认为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 Warning]: 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: 表 'account' 已经存在
错误代码: 1050
调用: 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) default 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) default 0 NOT NULL, PRIMARY KEY (ID))")
[EL Warning]: 2010-05-31 14:39:06.074--ServerSession(16053322)--异常 [EclipseLink-4002] (Eclipse Persistence Services - 2.1.0.v20100517-r7246): org.eclipse.persistence.exceptions.DatabaseException

接着是以下内容。

我做错了什么还是这是一个bug?

4个回答

36

自 EclipseLink 2.4 起,您可以在持久化单元的规范中使用此功能:

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

6
当使用create-tables值时,这是预期的行为。关于eclipselink.ddl-generation属性的文档中写到以下内容:

使用EclipseLink JPA扩展进行模式生成

以下是用于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将尝试删除所有表,然后创建所有表。如果遇到任何问题,则EclipseLink将遵循特定数据库和JDBC驱动程序组合的默认行为,然后继续下一条语句。(另请参见eclipselink.create-ddl-jdbc-file-nameeclipselink.drop-ddl-jdbc-file-name)。
因此,您可能希望选择drop-and-create-tables

我想保留我的当前数据。有没有更新现有表格(alter语句)的方法?没有类似于Hibernate的更新选项吗? - javydreamercsw
@javydreamercsw,我不知道有直接相等的东西。 - Pascal Thivent
@PascalThivent,这是一个旧的问题,但请看一下被接受的答案。他们似乎在您的回答之后添加了它。您可能需要进行更新。 - Magnilex

2
Hibernate JPA实现可以完全满足您的需求。这里是启用该行为的属性:
property name="hibernate.hbm2ddl.auto" value="update"

我知道这一点,但我希望能够使用标准的JPA和/或JPA2。 - javydreamercsw
我意识到在现实生活中,我不需要更新表格。如果我仍在开发阶段,那么我可以随时删除并创建表格。如果表格有数据而我不想删除它,最好的做法是自己更改表格。这主要是在实时环境中,我不希望表格被自动更新。 - joshua
5
@joshua: 实际上,即使在运行中的系统上,也有更新数据库结构的解决方案,但它们是独立于JPA/Hibernate的。其中一种解决方案是Google Flyway(http://code.google.com/p/flyway/);或者搜索“数据库版本控制”、“数据库迁移”。 - sleske
1
Flyway看起来很有趣。已经加入我的工具箱了。谢谢!把它作为答案,你应该是我选择的人。 - javydreamercsw

0

create-or-extend-tables 可以解决问题


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