113
@Column(name="open")

Using sqlserver dialect with hibernate.

[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'.

I would have expected hibernate to use quoted identifier when creating the table.

Any ideas on how to handle this... other than renaming the field?

Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
TJR
  • 3,617
  • 8
  • 38
  • 41

8 Answers8

157

With Hibernate as JPA 1.0 provider, you can escape a reserved keyword by enclosing it within backticks:

@Column(name="`open`")

This is the syntax inherited from Hibernate Core:

5.4. SQL quoted identifiers

You can force Hibernate to quote an identifier in the generated SQL by enclosing the table or column name in backticks in the mapping document. Hibernate will use the correct quotation style for the SQL Dialect. This is usually double quotes, but the SQL Server uses brackets and MySQL uses backticks.

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

In JPA 2.0, the syntax is standardized and becomes:

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

References

Related questions

Johan Kaving
  • 4,870
  • 1
  • 27
  • 21
Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124
  • And thanks from me. It solved a problem I had. btw - Ref is now at: http://docs.jboss.org/hibernate/stable/core/manual/en-US/html/mapping.html#mapping-quotedidentifiers – Steve Nov 12 '13 at 16:54
  • 7
    I don't understand why I have to do this, why Hibernate don't do this automatically instead of me??? – Daniel Hári May 04 '16 at 22:54
  • @DanielHári maybe you find my answer more "automatic"? – Rafiek Apr 25 '18 at 11:08
  • 1
    Using `@Column(name="[open]")` is much prettier :) – Waleed Abdalmajeed Jun 10 '18 at 10:36
  • If you use _@Column(name="\"open\"")_ on **Oracle**, note that quoted identifiers are case sensitive. Which means most likely you need to use **@Column(name="\"OPEN\"")** instead, otherwise you'll get an invalid identifier error. – Istvan Devai Dec 01 '19 at 11:39
70

Had the same problem, but with a tablename called Transaction. If you set

hibernate.globally_quoted_identifiers=true

Then all database identifiers will be quoted.

Found my answer here Special character in table name hibernate giving error

And found all available settings here https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/appendices/Configurations.html

Could not find better docs for this though.

In my case the setting was in my Spring properties file. As mentioned in the comments, it could also be in other, hibernate related, configuration files.

Rafiek
  • 1,434
  • 1
  • 16
  • 24
  • 12
    How is this not the default setting? – Josh M. Jun 28 '18 at 14:21
  • SQL might become unreadable and using keywords as names is a bad practice that should not be encouraged. I think...? – Rafiek Jun 29 '18 at 09:53
  • 3
    Okay. I'll prefer an escaped reserved word as a name all day long over a name that doesn't fit. – Josh M. Jun 29 '18 at 15:13
  • 1
    Yes, you could say that the abstraction provided by Hibernate is only of concern and not how it is technically implemented. But if you also use tooling like Flyway or Liquibase, then it adds to complexity when you need to consider that there might be reserved words. This has been my experience when migrating schema's. – Rafiek Jun 30 '18 at 06:56
  • 2
    For those wondering where this needs to be set, it's probably in your `persistence.xml` for JBoss projects. – Addison Feb 04 '19 at 06:10
  • Using Spring: `spring.jpa.properties.hibernate.globally_quoted_identifiers=true` – Patrick Brielmayer Feb 03 '22 at 09:06
29

Manually escaping the reserved keywords

If you are using JPA, you can escape with double quotes:

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

If you're using Hibernate native API, then you can escape them using backticks:

@Column(name = "`open`")

Automatically escaping reserved keywords

If you want to automatically escape reserved keywords, you can set to true the Hibernate-specific hibernate.globally_quoted_identifiers configuration property:

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

Yaml format

spring:
  jpa:
    properties:
      hibernate:
        globally_quoted_identifiers: true
Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
17

If you use as shown below it should work

@Column(name="[order]")
private int order;
abatishchev
  • 98,240
  • 88
  • 296
  • 433
Raman
  • 202
  • 2
  • 3
13
@Column(name="\"open\"")

This will work for sure, Same problem happened with me, when I was learning hibernate.

wmnitin
  • 3,387
  • 1
  • 13
  • 19
12

There is also another option: hibernate.auto_quote_keyword

which

Specifies whether to automatically quote any names that are deemed keywords.

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

Yaml

spring:
  jpa:
    properties:
      hibernate:
        auto_quote_keyword: true
Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
  • 2
    I found this better than globally_quoted_identifiers because this only quotes reserved keywords instead of every identifier. – Rafael Renan Pacheco Jan 04 '22 at 01:30
  • 1
    It's a shame this isn't set by default, I can see that not setting this makes it harder to switch to another JPA implementation that doesn't support automatic quoting. – Matthew Buckett Jun 28 '22 at 17:07
3

No - change the column name.

This is database-specific, and you just can't create such a column. After all hibernate finally sends DDL to the database. If you can't create a valid DDL with this column name, this means hibernate can't as well. I don't think quoting would solve the issue even if you are writing the DDL.

Even if you somehow succeed to escape the name - change it. It will work with this database, but won't work with another.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • That *may* work. See http://stackoverflow.com/questions/285775/how-to-deal-with-sql-column-names-that-look-like-sql-keywords. Let's wait for the OP confirmation. – ewernli Feb 08 '10 at 20:18
  • 1
    This is not database-specific! You escape it with a ` and hibernate translate it to correct quotation style for the SQL Dialect – Daniel Käfer Jun 26 '17 at 12:24
3

Some JPA implementations (e.g the one I use, DataNucleus) automatically quote the identifier for you, so you never get this.

Neil Stockton
  • 11,383
  • 3
  • 34
  • 29
  • Yes, surprised that Hibernate seemingly still does not offer such a basic feature given the number of times people get hit by it (and someone even downvoted you for daring to mention that this was possible elsewhere) –  Jul 09 '18 at 17:04