7

JPA 2.0 と Hibernate 3.5.2-Final をプロバイダー (および MySQL 5.1.41) として使用して、JEE6 アプリケーションを開発しています。私のアプリケーション サーバーは Glassfish V3.0.1 です。私はすでに、いくつかのエンティティと関係を備えた動作中の CRUD アプリを持っています。

ここで、「グループ」という名前の (非常に単純な) エンティティを追加しました。エンティティ クラスは次のようになります。

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
}

編集 dbインスタンスで予約された単語を使用する場合は、JPA 2.0の方法に関する@Pascalsの回答を参照してください。

于 2010-06-30T10:23:55.277 に答える
2

一部のJPA実装では、そのような名前のクラスを使用できます。JPA実装は、適切な処理を実行し、任意のSQLで名前を「引用」します(Paul Whelanが指摘した予約語であるため)。そのため、受け入れられます。DataNucleusは確かにこれを問題なく許可します。

于 2010-06-30T10:41:33.907 に答える