Cara memetakan bidang entitas yang namanya adalah kata yang dipesan di JPA

92
@Column(name="open")

Menggunakan dialek sqlserver dengan 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'.

Saya mengharapkan hibernate untuk menggunakan pengenal yang dikutip saat membuat tabel.

Ada ide tentang cara menangani ini ... selain mengganti nama bidang?

TJR
sumber
Lihat misalnya hibernate.onjira.com/browse/HHH-1272
Ondra Žižka

Jawaban:

55

Punya masalah yang sama, tetapi dengan nama tablen disebut Transaction. Jika Anda mengatur

hibernate.globally_quoted_identifiers=true

Kemudian semua pengidentifikasi database akan dikutip.

Menemukan jawaban saya di sini Karakter khusus dalam nama tabel hibernate memberikan kesalahan

Dan temukan semua pengaturan yang tersedia di sini https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/appendices/Configurations.html

Tidak dapat menemukan dokumen yang lebih baik untuk ini.

Dalam kasus saya, pengaturannya ada di file properti Spring saya. Seperti yang disebutkan di komentar, bisa juga di file konfigurasi lain yang terkait dengan hibernasi.

Rafiek
sumber
9
Bagaimana ini bukan pengaturan default?
Josh M.
SQL mungkin menjadi tidak dapat dibaca dan menggunakan kata kunci sebagai nama adalah praktik buruk yang seharusnya tidak didorong. Kupikir...?
Rafiek
1
Baik. Saya lebih suka kata yang dipisahkan dengan escape sebagai nama sepanjang hari daripada nama yang tidak pas.
Josh M.
Ya, Anda dapat mengatakan bahwa abstraksi yang disediakan oleh Hibernate hanya menjadi perhatian dan bukan bagaimana penerapannya secara teknis. Tetapi jika Anda juga menggunakan perkakas seperti Flyway atau Liquibase, itu menambah kompleksitas saat Anda perlu mempertimbangkan bahwa mungkin ada kata-kata yang dipesan. Ini adalah pengalaman saya saat memigrasi skema.
Rafiek
2
Bagi mereka yang bertanya-tanya di mana ini perlu ditetapkan, mungkin ini dalam persistence.xmlproyek JBoss Anda.
Addison
138

Dengan Hibernate sebagai penyedia JPA 1.0, Anda dapat keluar dari kata kunci yang dipesan dengan menyertakannya di dalam backticks:

@Column(name="`open`")

Ini adalah sintaks yang diwarisi dari Hiberate Core:

5.4. Pengenal kutipan SQL

Anda dapat memaksa Hibernate untuk mengutip pengenal dalam SQL yang dihasilkan dengan menyertakan nama tabel atau kolom di backticks dalam dokumen pemetaan. Hibernate akan menggunakan gaya kutipan yang benar untuk Dialek SQL. Ini biasanya tanda kutip ganda, tetapi SQL Server menggunakan tanda kurung dan MySQL menggunakan tanda kutip.

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

Di JPA 2.0, sintaksnya distandarisasi dan menjadi:

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

Referensi

Pertanyaan-pertanyaan Terkait

Pascal Thivent
sumber
Dan terima kasih dari saya. Itu memecahkan masalah yang saya miliki. btw - Ref sekarang ada di: docs.jboss.org/hibernate/stable/core/manual/en-US/html/…
Steve
5
Saya tidak mengerti mengapa saya harus melakukan ini, mengapa Hibernate tidak melakukan ini secara otomatis, bukan saya ???
Daniel Hári
@ DanielHári mungkin Anda menemukan jawaban saya lebih "otomatis"?
Rafiek
1
@ Rafiek: Oh ya, itu solusi yang tepat, suara positif (y).
Daniel Hári
1
Menggunakan @Column(name="[open]")jauh lebih cantik :)
Waleed Abdalmajeed
16

Keluar secara manual dari kata kunci yang dipesan

Jika Anda menggunakan JPA, Anda dapat keluar dengan tanda kutip ganda:

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

Jika Anda menggunakan Hibernate native API, Anda dapat menghindarinya menggunakan backticks:

@Column(name = "`open`")

Secara otomatis keluar dari kata kunci yang dipesan

Jika Anda ingin keluar dari kata kunci yang dicadangkan secara otomatis, Anda dapat mengatur ke properti konfigurasi truekhusus Hibernasi hibernate.globally_quoted_identifiers:

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

Format Yaml

spring:
  jpa:
    properties:
      hibernate:
        globally_quoted_identifiers: true

Untuk lebih jelasnya, lihat artikel ini .

Vlad Mihalcea
sumber
15

Jika Anda menggunakan seperti yang ditunjukkan di bawah ini seharusnya berfungsi

@Column(name="[order]")
private int order;
Raman
sumber
Anda hanya melakukan ini di lapangan pribadi bukan di pengambil?
Jake Gaston
5
ini khusus untuk sqlserver.
Alfredo M
11
@Column(name="\"open\"")

Ini pasti berhasil, Masalah yang sama terjadi dengan saya, ketika saya belajar hibernasi.

wmnitin.dll
sumber
4

Tidak - ubah nama kolom.

Ini khusus database, dan Anda tidak bisa membuat kolom seperti itu. Setelah semua hibernate akhirnya mengirimkan DDL ke database. Jika Anda tidak dapat membuat DDL yang valid dengan nama kolom ini, artinya hibernasi juga tidak bisa. Saya rasa mengutip tidak akan menyelesaikan masalah bahkan jika Anda menulis DDL.

Bahkan jika Anda entah bagaimana berhasil melarikan diri dari nama itu - ubahlah. Ini akan bekerja dengan database ini, tetapi tidak akan bekerja dengan yang lain.

Bozho
sumber
Itu mungkin berhasil. Lihat stackoverflow.com/questions/285775/… . Kita tunggu konfirmasi OPnya.
ewernli
1
Ini bukan khusus database! Anda menghindarinya dengan "dan hibernasi menerjemahkannya ke gaya kutipan yang benar untuk Dialek SQL
Daniel Käfer
2

Beberapa implementasi JPA (misalnya yang saya gunakan, DataNucleus) secara otomatis mengutip pengenal untuk Anda, jadi Anda tidak akan pernah mendapatkan ini.

Neil Stockton
sumber
Ya, terkejut bahwa Hibernate tampaknya masih tidak menawarkan fitur dasar seperti itu mengingat berapa kali orang terpukul olehnya (dan seseorang bahkan menurunkan suara Anda karena berani menyebutkan bahwa ini mungkin terjadi di tempat lain)