7

我正在开发一个 JEE6 应用程序,使用 JPA 2.0 和 Hibernate 3.5.2-Final 作为提供者(和 MySQL 5.1.41)。我的应用服务器是 Glassfish V3.0.1。我已经有一个包含一些实体和关系的工作 CRUD 应用程序。

现在我添加了一个名为“Group”的(非常简单的)实体。实体类如下所示:

package model
//Imports...
@Entity
public class Group {
  @Id @GeneratedValue
  private Long id;

  @NotNull
  private String name;

  //Getters and Setters
}

当然我也把它加到了persistence.xml中,比如<class>model.Group</class>. 我的 persistence.xml 在部署时删除并重新创建所有表。

因此,当我部署我的应用程序时,会生成我所有实体的表,但表组除外。在休眠日志中,我发现了以下错误(这不会阻止应用程序的部署)

[#|2010-06-30T11:54:29.862+0200|INFO|glassfish3.0.1|org.hibernate.cfg.AnnotationBinder|_ThreadID=11;_ThreadName=Thread-1;|Binding entity from annotated class: model.Group|#]
[#|2010-06-30T11:54:29.862+0200|INFO|glassfish3.0.1|org.hibernate.cfg.annotations.EntityBinder|_ThreadID=11;_ThreadName=Thread-1;|Bind entity model.Group on table Group|#]
[#|2010-06-30T11:54:33.773+0200|SEVERE|glassfish3.0.1|org.hibernate.tool.hbm2ddl.SchemaExport|_ThreadID=11;_ThreadName=Thread-1;|Unsuccessful: create table Group (id bigint not null auto_increment, name varchar(255) not null, primary key (id))|#]
[#|2010-06-30T11:54:33.773+0200|SEVERE|glassfish3.0.1|org.hibernate.tool.hbm2ddl.SchemaExport|_ThreadID=11;_ThreadName=Thread-1;|You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Group (id bigint not null auto_increment, name varchar(255) not null, primary ke' at line 1|#]
[#|2010-06-30T11:54:54.883+0200|INFO|glassfish3.0.1|org.hibernate.cfg.AnnotationBinder|_ThreadID=25;_ThreadName=Thread-1;|Binding entity from annotated class: model.Group|#]
[#|2010-06-30T11:54:54.884+0200|INFO|glassfish3.0.1|org.hibernate.cfg.annotations.EntityBinder|_ThreadID=25;_ThreadName=Thread-1;|Bind entity model.Group on table Group|#]
[#|2010-06-30T11:54:58.402+0200|SEVERE|glassfish3.0.1|org.hibernate.tool.hbm2ddl.SchemaExport|_ThreadID=25;_ThreadName=Thread-1;|Unsuccessful: create table Group (id bigint not null auto_increment, name varchar(255) not null, primary key (id))|#]
[#|2010-06-30T11:54:58.403+0200|SEVERE|glassfish3.0.1|org.hibernate.tool.hbm2ddl.SchemaExport|_ThreadID=25;_ThreadName=Thread-1;|You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Group (id bigint not null auto_increment, name varchar(255) not null, primary ke' at line 1|#]

现在,当我将实体重命名为“MyGroup”之类的名称(属性保持不变)时,相应地更改 persistence.xml,并重新部署我的应用程序,成功创建了“MyGroup”表!我在日志中发现以下几行表明 MyGroup 已正确创建:

[#|2010-06-30T11:58:51.456+0200|INFO|glassfish3.0.1|org.hibernate.cfg.AnnotationBinder|_ThreadID=11;_ThreadName=Thread-1;|Binding entity from annotated class: model.MyGroup|#]
[#|2010-06-30T11:58:51.456+0200|INFO|glassfish3.0.1|org.hibernate.cfg.annotations.EntityBinder|_ThreadID=11;_ThreadName=Thread-1;|Bind entity model.MyGroup on table MyGroup|#]
[#|2010-06-30T11:59:21.569+0200|INFO|glassfish3.0.1|org.hibernate.cfg.AnnotationBinder|_ThreadID=25;_ThreadName=Thread-1;|Binding entity from annotated class: model.MyGroup|#]
[#|2010-06-30T11:59:21.569+0200|INFO|glassfish3.0.1|org.hibernate.cfg.annotations.EntityBinder|_ThreadID=25;_ThreadName=Thread-1;|Bind entity model.MyGroup on table MyGroup|#]

有人知道问题是什么吗?好的,我可以将 Group 重命名为 MyGroup,但我真的很想知道这里发生了什么。我现在应该有什么限制,比如“不要调用实体组”吗?但如果是这样,为什么我的错误如此不清楚?

4

4 回答 4

16

如果您告诉 JPA 提供者对它们进行转义,则可以对数据库对象名称使用保留关键字。如规范的以下部分所述,这已在 JPA 2.0 中标准化:

2.13 数据库对象的命名

(...)

要指定分隔标识符,必须使用以下方法之一:

  • 通过在对象/关系 xml 映射文件<delimited-identifiers/>的元素中指定元素,可以指定将用于持久性单元的所有数据库标识符视为分隔标识符。persistence-unit-defaults如果 <delimited-identifiers/>指定了元素,则不能覆盖它。

  • 可以基于每个名称指定将数据库对象的名称解释为分隔标识符,如下所示:

    • 使用注释,通过将名称括在双引号中,将名称指定为定界标识符,其中内引号被转义,例如, @Table(name="\"customer\"")
    • 使用 XML 时,通过使用双引号将名称指定为分隔标识符,例如,<table name="&quot;customer&quot;"/>

所以 JPA 2.0 的方式是这样指定Table

@Entity
@Table(name="\"Group\"")
public class Group {
  @Id @GeneratedValue
  private Long id;

  @NotNull
  private String name;

  //Getters and Setters
}

Hibernate 绝对支持这一点(参见HHH-4553),这里没有泄漏抽象。

于 2010-06-30T13:00:41.163 回答
3

Group 是数据库 MySQL 中的保留字,请参见此处

package model
//Imports...
@Entity
@Table(name = "group_table")
public class Group {
  @Id @GeneratedValue
  private Long id;

  @NotNull
  private String name;

  //Getters and Setters
}

编辑 如果您想使用数据库实例中保留的字词,请参阅 @Pascals 对 JPA 2.0 方式的回答。

于 2010-06-30T10:23:55.277 回答
3

您可以使用以下 @Table 注释来引用 'group' 关键字:

@Entity
@Table(name = "`group`")
public class Group {
...
}

我知道这是一个老问题的答案,但我认为它可能对某人有所帮助。

于 2020-05-08T18:21:47.040 回答
2

对于一些 JPA 实现,您可以使用具有类似名称的类,并且 JPA 实现会做明智的事情并在任何 SQL 中“引用”名称(因为它是 Paul Whelan 指出的保留字),所以它被接受了。DataNucleus当然允许这没有问题。

于 2010-06-30T10:41:33.907 回答