【问题标题】:How to map an entity field whose name is a reserved word in JPA如何在 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 在创建表时使用带引号的标识符。

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

【问题讨论】:

标签: java sql-server hibernate orm jpa


【解决方案1】:

否 - 更改列名。

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

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

【讨论】:

  • 可能有效。见stackoverflow.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\"")

参考文献

相关问题

【讨论】:

  • 感谢我。它解决了我遇到的一个问题。顺便说一句 - 参考现在在: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 更好,因为它只引用保留关键字而不是每个标识符。
      猜你喜欢
      • 2021-07-23
      • 1970-01-01
      • 1970-01-01
      • 2019-11-04
      • 1970-01-01
      • 2013-11-22
      • 2011-01-21
      相关资源
      最近更新 更多