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

Posted

技术标签:

【中文标题】如何在 JPA 中映射名称为保留字的实体字段【英文标题】:How to map an entity field whose name is a reserved word in JPA 【发布时间】:2011-01-14 12:49:33 【问题描述】:
@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'.

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

除了重命名字段之外,关于如何处理这个问题的任何想法?

【问题讨论】:

参见例如hibernate.onjira.com/browse/HHH-1272 【参考方案1】:

否 - 更改列名。

这是特定于数据库的,您不能创建这样的列。毕竟hibernate最终将DDL发送到数据库。如果你不能用这个列名创建一个有效的 DDL,这意味着 hibernate 也不能。即使您正在编写 DDL,我也不认为引用会解决问题。

即使您以某种方式成功逃脱了名称 - 更改它。它可以与这个数据库一起工作,但不能与另一个数据库一起工作。

【讨论】:

可能有效。见***.com/questions/285775/…。让我们等待OP的确认。 这不是特定于数据库的!您使用 ` 对其进行转义,然后休眠将其转换为 SQL 方言的正确引用样式【参考方案2】:

如果你按如下所示使用它应该可以工作

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

【讨论】:

您只是在私有字段上而不是在 getter 上执行此操作? 这是特定于 sqlserver 的。【参考方案3】:

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

@Column(name="`open`")

这是继承自 Hiberate Core 的语法:

5.4. SQL quoted identifiers

你可以强制 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\"")

参考文献

休眠参考指南 5.4. SQL quoted identifiers JPA 2.0 规范 2.13 数据库对象的命名

相关问题

Hibernate, MySQL and table named “Repeat” - strange behaviour Automatic reserved word escaping for Hibernate tables and columns

【讨论】:

感谢我。它解决了我遇到的一个问题。顺便说一句 - 参考现在在:docs.jboss.org/hibernate/stable/core/manual/en-US/html/… 我不明白为什么我必须这样做,为什么 Hibernate 不自动而不是我这样做??? @DanielHári 也许你觉得我的回答更“自动”? @Rafiek:哦,是的,这是完美的解决方案,赞成 (y)。 使用@Column(name="[open]") 更漂亮:)【参考方案4】:

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

【讨论】:

是的,令人惊讶的是,考虑到人们被它击中的次数,Hibernate 似乎仍然没有提供这样一个基本功能(有人甚至因为你敢于在其他地方提到这可能而对你投了反对票)跨度> 【参考方案5】:
@Column(name="\"open\"")

这肯定会起作用,我在学习休眠时也遇到了同样的问题。

【讨论】:

【参考方案6】:

遇到了同样的问题,但使用了名为 Transaction 的表名。如果你设置

hibernate.globally_quoted_identifiers=true

然后所有的数据库标识符都会被引用。

在这里找到我的答案 Special character in table name hibernate giving error

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

虽然找不到更好的文档。

在我的情况下,设置在我的 Spring 属性文件中。如 cmets 中所述,它也可以在其他与休眠相关的配置文件中。

【讨论】:

这不是默认设置吗? SQL 可能变得不可读,并且使用关键字作为名称是不应该鼓励的不好的做法。我想……? 好的。我宁愿整天使用转义的保留字作为名称,而不是不合适的名称。 是的,你可以说 Hibernate 提供的抽象只关心而不是它是如何在技术上实现的。但是,如果您还使用 Flyway 或 Liquibase 之类的工具,那么当您需要考虑可能存在保留字时,它会增加复杂性。这是我迁移架构时的经验。 对于那些想知道需要在哪里设置的人,它可能在您的 persistence.xml 中用于 JBoss 项目。【参考方案7】:

手动转义保留关键字

如果你使用的是 JPA,你可以用双引号转义:

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

如果您使用的是 Hibernate 原生 API,那么您可以使用反引号对它们进行转义:

@Column(name = "`open`")

自动转义保留关键字

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

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

Yaml 格式

spring:
  jpa:
    properties:
      hibernate:
        globally_quoted_identifiers: true

【讨论】:

【参考方案8】:

还有另一种选择:hibernate.auto_quote_keyword

哪个

指定是否自动引用任何被视为关键字的名称。

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

Yaml

spring:
  jpa:
    properties:
      hibernate:
        auto_quote_keyword: true

【讨论】:

我发现这比 global_quoted_identifiers 更好,因为它只引用保留关键字而不是每个标识符。

以上是关于如何在 JPA 中映射名称为保留字的实体字段的主要内容,如果未能解决你的问题,请参考以下文章

如何在运行时检索 JPA 中实体的映射表名称?

如何使用 JPA 从多列构造模型实例

如何将计算字段映射到 JPA 实体?

如何在同一个数据库表上映射两个 JPA 或 Hibernate 实体

如何在 JPA 2 实体中映射 postgresql“带有时区的时间戳”

JPA,映射实体人,其中包含名称类型的类