Hibernate 查询以 SQL 语法错误结束

Posted

技术标签:

【中文标题】Hibernate 查询以 SQL 语法错误结束【英文标题】:Hibernate query ends up in SQL syntax error 【发布时间】:2019-02-07 20:04:00 【问题描述】:

我创建了一个UserPreferences bean。主键是id 列。这是bean的定义:

@Entity
public class UserPreferences 

    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    @Column(unique = true)
    @ColumnDefault("")
    private String id;

    private String email;

    // Getters and Setters

现在我使用Kotlin 在这个bean 中插入数据。这是执行此操作的代码:

val newUserPreferences = UserPreferences().apply  email = newUserRequest.email 
mUserPreferenceService.save(newUserPreferences)

让我们假设newUserRequest.email 不是null。我的application.yml 中的auto-dll 设置是update。执行此代码时,我看到 Hibernate 生成以下查询以创建表:

create table user_preferences (
   id varchar(255) default  not null
   email varchar(255),
   primary key (id)
) engine=MyISAM

此时,应用程序加载失败并出现以下错误:

引起:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: 您的 SQL 语法有错误;检查手册 对应于您的 MariaDB 服务器版本,以便使用正确的语法 接近'不为空,

查看异常,很明显代码失败了,因为没有使用空的String 作为默认值,hibernate 只是在生成的查询中放置了一个空格。所以这是我的问题:

    这应该被视为 Hibernate 中的错误吗? 如何处理我希望将空字符串"" 作为列默认值的情况?

【问题讨论】:

id varchar(255) default not null后面应该加逗号吗? 是的,不知何故我错过了在我的问题中复制它 哦,好的。因为错误提到“正确的语法接近不为空”,因此引起了您的注意。 【参考方案1】:

我不是 Hibernate 用户,但我发现 https://github.com/hibernate/hibernate-orm/blob/master/documentation/src/test/java/org/hibernate/userguide/schema/ColumnDefaultTest.java 显示:

@ColumnDefault("'N/A'")

看来,当您为 SQL 字符串类型定义默认值时,您必须在 Java 字符串中使用 SQL 字符串分隔符(单引号)。在你的情况下,因为你想要一个空字符串,你会使用:

@ColumnDefault("''")

另一种定义默认值的方法是在@Column注解中设置一个属性,如另一个Stack Overflow答案所示:How to set default value in Hibernate

所以这可能不是一个错误,但它是 Hibernate 的一种用法,对某些用户来说是违反直觉的,并且可能没有明确记录。

P.S.:我认为 Hibernate 仍然使用 engine=MyISAM unless you specify the right hibernate.dialect 生成 CREATE TABLE 语句是一个错误。不推荐使用该存储引擎。在大多数情况下,MyISAM 比 InnoDB 慢,并且不支持任何 ACID 属性。 MySQL 一直在逐步淘汰 MyISAM,我不建议在任何当前项目中使用它。

【讨论】:

感谢比尔的解释。

以上是关于Hibernate 查询以 SQL 语法错误结束的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate 和 MYSQL:您的 SQL 语法有错误?

PL/SQL的基本语法

Hibernate创建表不成功,sql语法错误

在 Hibernate 中批量删除时查询语法错误

命名查询Hibernate中的坏语法错误

SQL 语句中的 Spring Boot Hibernate 语法错误