Hibernate在MySQL中生成无效的SQL查询

11
我有如下的JPA实体类(示例),一个房子只属于一条街道,而一条街道可以有多个房子。
@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;
}

我将生成类型设置为identity,这应该会自动分配一个新的ID。

在创建一个新的House和一个新的Street时,我必须先创建并持久化Street,然后再创建House。这是因为我没有设置CascadeType为PERSIST,所以必须手动完成[1]。但是,在插入一个新创建的Street时:

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

Hibernate/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 in Action第318-319页。

4个回答

14
如果您的SQL语句没有错误,那么您可能需要检查表列名,因为它可能包含Mysql使用的预定义名称,例如“column”,不能用作表列名。

1
我把“key”和“value”作为列名使用了。糟糕。 - Ian Newland

13

标准SQL规定了INSERT的可选语法:

INSERT INTO <Table Name> DEFAULT VALUES

这是合法的SQL语法,例如Microsoft SQL ServerPostgreSQLSQLite都支持,但Oracle、IBM DB2或MySQL不支持。

MySQL支持其他实现相同结果的语法:

INSERT INTO <Table Name> () VALUES ()

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

在Hibernate中,你应该适当地配置SQL方言,并且由Hibernate生成适用于目标RDBMS品牌的有效SQL语句。

import org.hibernate.cfg.Configuration;

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

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


9

当表中使用了保留字作为列名时,可能会出现此异常。例如,“to”和“from”在MySQL中不适合用作列名。很明显,Hibernate存在缺陷,它没有检查这样的列,并且即使表未创建也继续工作而不报错。


1
这真的是一个很大的提示。 - kailash gaur

0

请确保spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect的版本正确,与MySQL相匹配


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接