วิธีแมปฟิลด์เอนทิตีที่มีชื่อเป็นคำสงวนใน JPA


92
@Column(name="open")

การใช้ภาษา sqlserver กับ 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'.

ฉันคาดว่าไฮเบอร์เนตจะใช้ตัวระบุที่ยกมาเมื่อสร้างตาราง

มีแนวคิดเกี่ยวกับวิธีจัดการสิ่งนี้ ... นอกเหนือจากการเปลี่ยนชื่อสนามหรือไม่


คำตอบ:


55

มีปัญหาเดียวกัน แต่มีการเรียกชื่อTransactionตาราง หากคุณตั้งค่า

hibernate.globally_quoted_identifiers=true

จากนั้นตัวระบุฐานข้อมูลทั้งหมดจะถูกยกมา

พบคำตอบของฉันที่นี่ อักขระพิเศษในชื่อตารางไฮเบอร์เนตให้ข้อผิดพลาด

และพบการตั้งค่าทั้งหมดที่นี่ https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/appendices/Configurations.html

ไม่พบเอกสารที่ดีกว่าสำหรับสิ่งนี้แม้ว่า

ในกรณีของฉันการตั้งค่าอยู่ในไฟล์คุณสมบัติ Spring ของฉัน ตามที่กล่าวไว้ในความคิดเห็นมันอาจอยู่ในไฟล์การกำหนดค่าอื่น ๆ ที่เกี่ยวข้องกับการจำศีล


9
นี่ไม่ใช่ค่าเริ่มต้นอย่างไร
Josh M.

SQL อาจไม่สามารถอ่านได้และการใช้คีย์เวิร์ดเป็นชื่อถือเป็นแนวทางปฏิบัติที่ไม่ดีที่ไม่ควรสนับสนุน ฉันคิด...?
Rafiek

1
ตกลง. ฉันจะเลือกใช้คำสงวนที่ไม่ใช้ Escape เป็นชื่อตลอดทั้งวันมากกว่าชื่อที่ไม่เหมาะสม
Josh M.

ใช่คุณสามารถพูดได้ว่าสิ่งที่เป็นนามธรรมจาก Hibernate เป็นเพียงความกังวลเท่านั้นและไม่ใช่วิธีการนำไปใช้ในทางเทคนิค แต่ถ้าคุณใช้เครื่องมือเช่น Flyway หรือ Liquibase ก็จะเพิ่มความซับซ้อนเมื่อคุณต้องพิจารณาว่าอาจมีคำสงวนไว้ นี่เป็นประสบการณ์ของฉันเมื่อย้ายสคีมา
Rafiek

2
สำหรับผู้ที่สงสัยว่าต้องตั้งค่าตรงไหนอาจอยู่ในpersistence.xmlโครงการ JBoss ของคุณ
แอดดิสัน

138

ด้วย Hibernate ในฐานะผู้ให้บริการ JPA 1.0 คุณสามารถหลีกเลี่ยงคำหลักที่สงวนไว้ได้โดยใส่ไว้ใน backticks

@Column(name="`open`")

นี่คือไวยากรณ์ที่สืบทอดมาจาก Hiberate Core:

5.4. ตัวระบุที่ยกมาของ SQL

คุณสามารถบังคับให้ Hibernate อ้างตัวระบุใน SQL ที่สร้างขึ้นโดยการใส่ชื่อตารางหรือคอลัมน์ใน backticks ในเอกสารการแม็ป ไฮเบอร์เนตจะใช้รูปแบบใบเสนอราคาที่ถูกต้องสำหรับภาษาถิ่นของ SQL โดยปกติจะเป็นเครื่องหมายคำพูดคู่ แต่ SQL Server ใช้วงเล็บและ MySQL ใช้ backticks

<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\"")

อ้างอิง

คำถามที่เกี่ยวข้อง


และขอบคุณจากฉัน มันช่วยแก้ปัญหาที่ฉันมี btw - Ref อยู่ที่: docs.jboss.org/hibernate/stable/core/manual/en-US/html/…
Steve

5
ฉันไม่เข้าใจว่าทำไมฉันต้องทำแบบนี้ทำไม Hibernate ไม่ทำสิ่งนี้โดยอัตโนมัติแทนฉัน ???
Daniel Hári

@ DanielHáriบางทีคุณอาจพบคำตอบของฉันมากขึ้น "อัตโนมัติ"?
Rafiek

1
@Rafiek: โอ้ใช่นั่นเป็นทางออกที่สมบูรณ์แบบโดยโหวตขึ้น (y)
Daniel Hári

1
การใช้@Column(name="[open]")นั้นสวยกว่ามาก :)
Waleed Abdalmajeed

16

หนีคำหลักที่สงวนไว้ด้วยตนเอง

หากคุณใช้ JPA คุณสามารถหลีกเลี่ยงด้วยเครื่องหมายคำพูดคู่:

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

หากคุณใช้ Hibernate native API คุณสามารถหลีกเลี่ยงได้โดยใช้ backticks:

@Column(name = "`open`")

หลีกเลี่ยงคำหลักที่สงวนไว้โดยอัตโนมัติ

หากคุณต้องการหลีกเลี่ยงคำหลักที่สงวนไว้โดยอัตโนมัติคุณสามารถตั้งค่าเป็นคุณสมบัติการกำหนดค่าtrueเฉพาะไฮเบอร์เนตhibernate.globally_quoted_identifiers:

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

รูปแบบ Yaml

spring:
  jpa:
    properties:
      hibernate:
        globally_quoted_identifiers: true

สำหรับรายละเอียดเพิ่มเติมโปรดดูบทความนี้


15

หากคุณใช้ตามที่แสดงด้านล่างควรใช้งานได้

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

คุณกำลังทำสิ่งนี้ในสนามส่วนตัวไม่ใช่ในการเริ่มต้น?
Jake Gaston

5
นี่คือ sqlserver เฉพาะ
Alfredo M

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

สิ่งนี้จะได้ผลอย่างแน่นอนปัญหาเดียวกันนี้เกิดขึ้นกับฉันเมื่อฉันเรียนรู้โหมดไฮเบอร์เนต


4

ไม่ - เปลี่ยนชื่อคอลัมน์

นี่เป็นข้อมูลเฉพาะฐานข้อมูลและคุณไม่สามารถสร้างคอลัมน์ดังกล่าวได้ หลังจากที่จำศีลทั้งหมดส่ง DDL ไปยังฐานข้อมูลในที่สุด หากคุณไม่สามารถสร้าง DDL ที่ถูกต้องด้วยชื่อคอลัมน์นี้ได้นั่นหมายความว่าไม่สามารถไฮเบอร์เนตได้เช่นกัน ฉันไม่คิดว่าการอ้างถึงจะช่วยแก้ปัญหาได้แม้ว่าคุณจะเขียน DDL ก็ตาม

แม้ว่าคุณจะประสบความสำเร็จในการหลบหนีชื่อ - เปลี่ยนชื่อ มันจะทำงานกับฐานข้อมูลนี้ แต่จะใช้กับฐานข้อมูลอื่นไม่ได้


ที่อาจได้ผล ดูstackoverflow.com/questions/285775/... รอการยืนยัน OP
ewernli

1
นี่ไม่ใช่ฐานข้อมูลเฉพาะ! คุณหลีกเลี่ยงมันด้วย `และจำศีลแปลเพื่อแก้ไขรูปแบบใบเสนอราคาสำหรับภาษา SQL
Daniel Käfer

2

การใช้งาน JPA บางอย่าง (เช่นที่ฉันใช้ DataNucleus) จะอ้างตัวระบุให้คุณโดยอัตโนมัติดังนั้นคุณจะไม่ได้รับสิ่งนี้


ใช่แปลกใจที่ดูเหมือนว่า Hibernate จะยังไม่มีฟีเจอร์พื้นฐานเช่นนี้เนื่องจากจำนวนครั้งที่ผู้คนโดนโจมตี (และบางคนก็โหวตให้คุณไม่กล้าพูดถึงว่าเป็นไปได้ที่อื่น)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.