如何在JPA中映射名称为保留字的实体字段


92
@Column(name="open")

在休眠状态下使用sqlserver方言。

[SchemaUpdate] Unsuccessful: create table auth_session (id numeric(19,0) identity not null, active tinyint null, creation_date datetime not null, last_modified datetime not null, maxidle int null, maxlive int null, open tinyint null, sessionid varchar(255) not null, user_id numeric(19,0) not null, primary key (id), unique (sessionid))
[SchemaUpdate] Incorrect syntax near the keyword 'open'.

我希望休眠在创建表时使用带引号的标识符。

除了重命名字段外,还有其他任何处理方法的想法吗?


Answers:


54

遇到相同的问题,但表名为Transaction。如果您设定

hibernate.globally_quoted_identifiers=true

然后,将引用所有数据库标识符。

在这里找到我的答案 表名称中的特殊字符休眠给出错误

并在这里找到所有可用的设置 https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/appendices/Configurations.html

虽然找不到更好的文档。

就我而言,该设置位于我的Spring属性文件中。如注释中所述,它也可以位于其他与休眠相关的配置文件中。


9
这不是默认设置吗?
Josh M.

SQL可能变得不可读,并且使用关键字作为名称是一种不良做法,因此不应鼓励这样做。我认为...?
拉菲克

1
好的。我会全天候使用一个转义的保留字作为一个不合适的名称。
Josh M.

是的,您可以说Hibernate提供的抽象仅是关注的问题,而不是技术上如何实现的抽象。但是,如果您还使用Flyway或Liquibase之类的工具,那么当您需要考虑可能存在保留字时,就会增加复杂性。这是我在迁移架构时的经验。
拉菲克

2
对于那些想知道该在哪里设置的人,它可能在您persistence.xml的JBoss项目中。
艾迪生

137

使用Hibernate作为JPA 1.0提供程序,您可以通过将保留的关键字放在反引号内来对其进行转义:

@Column(name="`open`")

这是从Hiberate Core继承的语法:

5.4。SQL带引号的标识符

您可以通过将表名或列名放在映射文档的反引号中来强制Hibernate在生成的SQL中引用标识符。Hibernate将对SQL方言使用正确的引号样式。这通常是双引号,但是SQL Server使用方括号,而MySQL使用反引号。

<class name="LineItem" table="`Line Item`">
    <id name="id" column="`Item Id`"/><generator class="assigned"/></id>
    <property name="itemNumber" column="`Item #`"/>
    ...
</class>

在JPA 2.0中,语法是标准化的,并且变为:

@Column(name="\"open\"")

参考文献

相关问题


谢谢我 它解决了我遇到的一个问题。顺便说一句-参考现在在:docs.jboss.org/hibernate/stable/core/manual/en-US/html/…–
Steve

5
我不明白为什么我必须这样做,为什么Hibernate不会自动代替我这样做???
丹尼尔·哈里(DanielHári)

@DanielHári也许您发现我的答案更“自动”了?
拉菲克

1
@Rafiek:哦,是的,这是一个完美的解决方案,赞成(y)。
丹尼尔·哈里(DanielHári)

1
使用@Column(name="[open]")起来更漂亮:)
Waleed Abdalmajeed

15

如果您使用如下所示,它应该可以工作

@Column(name="[order]")
private int order;

您是在私有字段上执行此操作,而不是在getter上执行此操作?
杰克·加斯顿

4
这是特定于sqlserver的。
Alfredo M

15

手动转义保留的关键字

如果您使用的是JPA,则可以使用双引号进行转义:

@Column(name = "\"open\"")

如果您使用的是Hibernate本机API,则可以使用反引号将其转义:

@Column(name = "`open`")

自动转义保留关键字

如果要自动转义保留的关键字,则可以设置为true特定于Hibernate的hibernate.globally_quoted_identifiers配置属性:

<property
    name="hibernate.globally_quoted_identifiers"
    value="true"
/>

Yaml格式

spring:
  jpa:
    properties:
      hibernate:
        globally_quoted_identifiers: true

有关更多详细信息,请参阅本文


11
@Column(name="\"open\"")

这肯定可以工作,当我学习休眠时,我也发生了同样的问题。


4

否-更改列名称。

这是特定于数据库的,您无法创建这样的列。毕竟,休眠最终将DDL发送到数据库。如果您不能使用此列名创建有效的DDL,则意味着休眠也不能。我认为即使编写DDL,引用也不能解决问题。

即使您以某种方式成功逃脱了该名称,也请更改它。它将与此数据库一起使用,但不会与另一个数据库一起使用。


可能行得通。参见stackoverflow.com/questions/285775/…。让我们等待OP确认。
ewernli

1
这不是特定于数据库的!您可以通过`将其转义,然后将其休眠以将其转换为SQL方言的正确引用样式
DanielKäfer17年

2

一些JPA实现(例如,我使用的是DataNucleus)会自动为您引用标识符,因此您永远也不会得到它。


是的,令人惊讶的是,鉴于人们遭受它攻击的次数,Hibernate似乎仍然没有提供这样的基本功能(有人甚至不敢向您
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.