So ordnen Sie ein Entitätsfeld zu, dessen Name in JPA ein reserviertes Wort ist

90
@Column(name="open")

Verwenden des SQL Server-Dialekts im Ruhezustand.

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

Ich hätte erwartet, dass der Ruhezustand beim Erstellen der Tabelle einen Bezeichner in Anführungszeichen verwendet.

Irgendwelche Ideen, wie man damit umgeht ... außer das Feld umzubenennen?

TJR
quelle
Siehe zB hibernate.onjira.com/browse/HHH-1272
Ondra Žižka

Antworten:

54

Hatte das gleiche Problem, aber mit einem Tabellennamen namens Transaction. Wenn Sie einstellen

hibernate.globally_quoted_identifiers=true

Dann werden alle Datenbankkennungen in Anführungszeichen gesetzt.

Ich habe meine Antwort hier gefunden. Sonderzeichen im Tabellennamen Ruhezustand mit Fehler

Alle verfügbaren Einstellungen finden Sie hier https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/appendices/Configurations.html

Es konnten jedoch keine besseren Dokumente dafür gefunden werden.

In meinem Fall befand sich die Einstellung in meiner Spring-Eigenschaftendatei. Wie in den Kommentaren erwähnt, kann es sich auch um andere Konfigurationsdateien handeln, die sich auf den Ruhezustand beziehen.

Rafiek
quelle
8
Wie ist dies nicht die Standardeinstellung?
Josh M.
SQL kann unlesbar werden und die Verwendung von Schlüsselwörtern als Namen ist eine schlechte Praxis, die nicht empfohlen werden sollte. Meiner Ansicht nach...?
Rafiek
1
In Ordnung. Ich bevorzuge den ganzen Tag ein entkommenes reserviertes Wort als Namen gegenüber einem Namen, der nicht passt.
Josh M.
Ja, man könnte sagen, dass die von Hibernate bereitgestellte Abstraktion nur von Belang ist und nicht, wie sie technisch implementiert wird. Wenn Sie jedoch auch Werkzeuge wie Flyway oder Liquibase verwenden, erhöht sich die Komplexität, wenn Sie berücksichtigen müssen, dass möglicherweise reservierte Wörter vorhanden sind. Dies war meine Erfahrung bei der Migration von Schemas.
Rafiek
2
Für diejenigen, die sich fragen, wo dies eingestellt werden muss, ist es wahrscheinlich in Ihren persistence.xmlfür JBoss-Projekten.
Addison
135

Mit Hibernate als JPA 1.0-Anbieter können Sie ein reserviertes Schlüsselwort umgehen, indem Sie es in Backticks einschließen:

@Column(name="`open`")

Dies ist die von Hiberate Core geerbte Syntax:

5.4. Bezeichner mit SQL-Anführungszeichen

Sie können Hibernate zwingen, einen Bezeichner in der generierten SQL anzugeben, indem Sie den Tabellen- oder Spaltennamen in Backticks im Zuordnungsdokument einfügen. Der Ruhezustand verwendet den richtigen Anführungszeichenstil für den SQL-Dialekt. Dies sind normalerweise doppelte Anführungszeichen, aber der SQL Server verwendet Klammern und MySQL 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 ist die Syntax standardisiert und lautet:

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

Verweise

Verwandte Fragen

Pascal Thivent
quelle
Und danke von mir. Es löste ein Problem, das ich hatte. Übrigens - Ref ist jetzt unter: docs.jboss.org/hibernate/stable/core/manual/en-US/html/…
Steve
5
Ich verstehe nicht, warum ich das tun muss, warum Hibernate das nicht automatisch anstelle von mir macht ???
Daniel Hári
@ DanielHári vielleicht findest du meine Antwort eher "automatisch"?
Rafiek
1
@ Rafiek: Oh ja, das ist die perfekte Lösung, positiv bewertet (y).
Daniel Hári
1
Verwenden @Column(name="[open]")ist viel schöner :)
Waleed Abdalmajeed
15

Wenn Sie wie unten gezeigt verwenden, sollte es funktionieren

@Column(name="[order]")
private int order;
Raman
quelle
Du machst das nur auf dem privaten Feld, nicht auf dem Getter?
Jake Gaston
4
Dies ist SQL Server-spezifisch.
Alfredo M
12

Manuelles Entkommen der reservierten Schlüsselwörter

Wenn Sie JPA verwenden, können Sie mit doppelten Anführungszeichen davonkommen:

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

Wenn Sie die native Hibernate-API verwenden, können Sie diese mithilfe von Backticks umgehen:

@Column(name = "`open`")

Reservierte Schlüsselwörter werden automatisch ausgeblendet

Wenn Sie reservierte Schlüsselwörter automatisch umgehen möchten, können Sie die Eigenschaft trueHibernate-spezifische hibernate.globally_quoted_identifiersKonfiguration festlegen :

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

Yaml-Format

spring:
  jpa:
    properties:
      hibernate:
        globally_quoted_identifiers: true

Weitere Informationen finden Sie in diesem Artikel .

Vlad Mihalcea
quelle
11
@Column(name="\"open\"")

Dies wird sicher funktionieren. Das gleiche Problem trat bei mir auf, als ich den Winterschlaf lernte.

wmnitin
quelle
4

Nein - Ändern Sie den Spaltennamen.

Dies ist datenbankspezifisch und Sie können eine solche Spalte einfach nicht erstellen. Schließlich sendet der Ruhezustand schließlich DDL an die Datenbank. Wenn Sie mit diesem Spaltennamen keine gültige DDL erstellen können, bedeutet dies, dass der Ruhezustand ebenfalls nicht möglich ist. Ich glaube nicht, dass Zitate das Problem lösen würden, selbst wenn Sie die DDL schreiben.

Auch wenn es Ihnen irgendwie gelingt, dem Namen zu entkommen - ändern Sie ihn. Es funktioniert mit dieser Datenbank, aber nicht mit einer anderen.

Bozho
quelle
Das kann funktionieren. Siehe stackoverflow.com/questions/285775/… . Warten wir auf die OP-Bestätigung.
Ewernli
1
Dies ist nicht datenbankspezifisch! Sie entkommen ihm mit einem `und übersetzen ihn im Ruhezustand in den korrekten Anführungszeichenstil für den SQL-Dialekt
Daniel Käfer
2

Einige JPA-Implementierungen (z. B. die von mir verwendete, DataNucleus) zitieren automatisch die Kennung für Sie, sodass Sie diese nie erhalten.

Neil Stockton
quelle
Ja, überrascht, dass Hibernate anscheinend immer noch keine so grundlegende Funktion bietet, wenn man bedenkt, wie oft Menschen davon betroffen sind (und jemand hat Sie sogar dafür herabgestuft, dass Sie es gewagt haben, zu erwähnen, dass dies anderswo möglich war)