Является ли незаконным называть субъект JPA "Группой"? - PullRequest
7 голосов
/ 30 июня 2010

Я разрабатываю JEE6-приложение, используя JPA 2.0 и Hibernate 3.5.2-Final в качестве провайдера (и MySQL 5.1.41). Мой сервер приложений - 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|#]

Кто-нибудь понял, в чем проблема? Хорошо, я мог бы просто переименовать Группу в MyGroup, но я действительно хочу знать, что здесь происходит. Есть ли какое-то ограничение, о котором я должен сказать сейчас, например "не вызывать группу лиц"? Но если это так, то почему ошибка становится настолько неясной?

Ответы [ 3 ]

14 голосов
/ 30 июня 2010

Вы можете использовать зарезервированные ключевые слова для имен объектов базы данных, если вы скажете провайдеру JPA их исключить.Это было стандартизировано в JPA 2.0, как описано в следующем разделе спецификации:

2.13 Именование объектов базы данных

(...)

Чтобы указатьИдентификаторы с разделителями, необходимо использовать один из следующих подходов:

  • Можно указать, что все идентификаторы базы данных, используемые для модуля персистентности, будут обрабатываться как идентификаторы с разделителями, указав <delimited-identifiers/>элемент в элементе persistence-unit-defaults файла сопоставления объекта / реляционного xml.Если указан элемент <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 ), здесь нет пропускающей абстракции.

4 голосов
/ 30 июня 2010

Группа - зарезервированное слово в вашей базе данных MySQL, см. здесь

Edit:

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

  @NotNull
  private String name;

  //Getters and Setters
}
2 голосов
/ 30 июня 2010

В некоторых реализациях JPA вы можете использовать классы с такими именами, а реализация JPA делает разумную вещь и «цитирует» имя в любом SQL (так как это зарезервированное слово, как указал Пол Уилан), принято DataNucleus , безусловно, позволяет это без проблем.

...