2009-01-14 48 views
10

我有以下JPA实体类(示例情况)。房子属于一条街。一条街有很多房屋。Hibernate使用MySQL生成无效的SQL查询

@Entity 
public class House { 
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    public Integer id; 

    public String name  

    @ManyToOne 
    public Street street; 
} 

@Entity 
public class Street { 
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY) 
    public Integer id; 

    @OneToMany(mappedBy="street") 
    public Set<House> houses; 
} 

我有生成类型设置为标识,应该自动分配一个新的ID。

在创建一个新街道的新房子时,我必须先创建并坚持街道,然后是房子。这是因为我没有将CascadeType设置为PERSIST,因此必须手动完成[1]。然而,当插入一个新创建的街道:

Street street = new Street(); 
entityManager.persist(street); 

休眠/ JPA产生下面的SQL查询:

insert into Street default values 

其MySQL不喜欢。

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 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 'default values' at line 1 

任何想法为什么?我使用Java 6,MySQL 5.0.67和Hibernate的JPA实现(版本3.2.1.ga)。

[1] EJB 3操作页面318-319

回答

11

标准SQL指定INSERT此可选语法:

INSERT INTO <Table Name> DEFAULT VALUES 

这是合法的SQL语法,支持,例如,通过Microsoft SQL ServerPostgreSQL ,和SQLite,但不是由Oracle,IBM DB2或MySQL。

MySQL支持其他的语法,达到相同的结果:

INSERT INTO <Table Name>() VALUES() 

INSERT INTO <Table Name> (col1, col2, col3) VALUES (DEFAULT, DEFAULT, DEFAULT) 

在Hibernate中,你应该正确configure的SQL方言,并且它是由Hibernate的生成目标RDBMS品牌有效的SQL。

import org.hibernate.cfg.Configuration; 

Configuration cfg = new Configuration(); 
cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLInnoDBDialect"); 

您还可以通过将名为hibernate.properties的文件放在类路径的根目录中来指定属性。

11

如果您的SQL语句中没有错误,那么您可能需要检查表列的名称,因为它可以包含Mysql使用的预定义名称;例如不能用作表格列名称的'列'

+0

谢谢,你救了我几个小时的辛勤工作。 – Heisenberg 2015-09-15 12:17:33

+0

我使用'key'和'value'作为列名。 Woops。 – 2016-05-07 12:47:16

7

当您可能有此异常时的另一种情况是当您将单词保留为表的列时。例如'to'和'from'不适合MySQL的clumn名称。这显然是Hibernate中的一个bug,它不检查这样的列,而且即使没有创建表也不会继续工作。