I'm developing a JEE6-application, using JPA 2.0 and Hibernate 3.5.2-Final as the Provider (and MySQL 5.1.41). My Application Server is Glassfish V3.0.1. I already have a working CRUD-app with some entities and relationships.
Now i added an (really simple) entity with the name "Group". The entity class looks like this:
package model
//Imports...
@Entity
public class Group {
@Id @GeneratedValue
private Long id;
@NotNull
private String name;
//Getters and Setters
}
Of course I also added it to the persistence.xml, like <class>model.Group</class>
. My persistence.xml drops and recreates all tables on deploy.
So when i deploy my application, the tables for all my entities are generated, except for the table group. In the hibernate logs, i discovered the following error (which doesn't prevent the application to be deployed)
[#|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|#]
Now when i rename the entity to something like "MyGroup" (the properties stay the same), alter the persistence.xml accordingly, and redeploy my app, the table "MyGroup开发者_运维技巧" is successfully created! I found the following lines in the logs showing that MyGroup is correctly created:
[#|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|#]
Anyone got an idea what the problem is? Okay, i could just rename Group to MyGroup, but i really want to know what's going on here. Is there any restriction i should now of, like "don't call an entity Group"? But if it is so, why is the error i get so unclear?
You can use reserved keywords for database objects names if you tell the JPA provider to escape them. This has been standardized in JPA 2.0 as described in the following section of the specification:
2.13 Naming of Database Objects
(...)
To specify delimited identifiers, one of the following approaches must be used:
It is possible to specify that all database identifiers in use for a persistence unit be treated as delimited identifiers by specifying the
<delimited-identifiers/>
element within thepersistence-unit-defaults
element of the object/relational xml mapping file. If the<delimited-identifiers/>
element is specified, it cannot be overridden.It is possible to specify on a per-name basis that a name for a database object is to be interpreted as a delimited identifier as follows:
- Using annotations, a name is specified as a delimited identifier by enclosing the name within double quotes, whereby the inner quotes are escaped, e.g.,
@Table(name="\"customer\"")
.- When using XML, a name is specified as a delimited identifier by use of double quotes, e.g.,
<table name=""customer""/>
So the JPA 2.0 way would be to specify the Table
like this:
@Entity
@Table(name="\"Group\"")
public class Group {
@Id @GeneratedValue
private Long id;
@NotNull
private String name;
//Getters and Setters
}
This is definitely supported by Hibernate (see HHH-4553), no leaky abstraction here.
Group is a reserved word in your database MySQL see here
package model
//Imports...
@Entity
@Table(name = "group_table")
public class Group {
@Id @GeneratedValue
private Long id;
@NotNull
private String name;
//Getters and Setters
}
edit See @Pascals answer for JPA 2.0 way if you want to use words reserved in your db instance.
You can quote the 'group' keyword by using the following @Table annotation:
@Entity
@Table(name = "`group`")
public class Group {
...
}
I know this is an answer to an old question, but I thought it may help someone.
With some JPA implementations you can use classes with names like that, and the JPA implementation does the sensible thing and "quotes" the name in any SQL (since it is a reserved word as pointed out by Paul Whelan), so it is accepted. DataNucleus certainly allows this no problem.
精彩评论