Cách ánh xạ một trường thực thể có tên là một từ dành riêng trong JPA


92
@Column(name="open")

Sử dụng phương ngữ sqlserver với chế độ ngủ đông.

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

Tôi đã mong đợi chế độ ngủ đông để sử dụng số nhận dạng được trích dẫn khi tạo bảng.

Bất kỳ ý tưởng về cách xử lý điều này ... ngoài việc đổi tên trường?


Câu trả lời:


55

Gặp vấn đề tương tự, nhưng với một tên bảng được gọi Transaction. Nếu bạn đặt

hibernate.globally_quoted_identifiers=true

Sau đó, tất cả các định danh cơ sở dữ liệu sẽ được trích dẫn.

Tìm thấy câu trả lời của tôi ở đây Ký tự đặc biệt trong tên bảng ở chế độ ngủ đông gây ra lỗi

Và tìm thấy tất cả các cài đặt có sẵn tại đây https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/appendices/Configurations.html

Không thể tìm thấy tài liệu tốt hơn cho việc này.

Trong trường hợp của tôi, cài đặt nằm trong tệp thuộc tính Spring của tôi. Như đã đề cập trong các nhận xét, nó cũng có thể nằm trong các tệp cấu hình khác, có liên quan đến chế độ ngủ đông.


9
Làm thế nào đây không phải là cài đặt mặc định?
Josh M.

SQL có thể trở nên khó đọc và việc sử dụng các từ khóa làm tên là một phương pháp không tốt không nên được khuyến khích. Tôi nghĩ...?
Rafiek

1
Được chứ. Tôi sẽ thích một từ dành riêng thoát tục như một cái tên suốt ngày hơn một cái tên không phù hợp.
Josh M.

Có, bạn có thể nói rằng sự trừu tượng được cung cấp bởi Hibernate chỉ là mối quan tâm chứ không phải cách nó được thực hiện về mặt kỹ thuật. Nhưng nếu bạn cũng sử dụng công cụ như Flyway hoặc Liquibase, thì nó sẽ tăng thêm sự phức tạp khi bạn cần xem xét rằng có thể có các từ dành riêng. Đây là kinh nghiệm của tôi khi di chuyển lược đồ.
Rafiek

2
Đối với những người tự hỏi điều này cần được thiết lập ở đâu, có thể nó nằm trong các persistence.xmldự án dành cho JBoss của bạn .
Addison

138

Với Hibernate as JPA 1.0 nhà cung cấp, bạn có thể thoát khỏi một từ khóa dành riêng bằng cách đặt nó trong backticks:

@Column(name="`open`")

Đây là cú pháp được kế thừa từ Hiberate Core:

5.4. Mã định danh được trích dẫn trong SQL

Bạn có thể buộc Hibernate trích dẫn một số nhận dạng trong SQL được tạo bằng cách đặt tên bảng hoặc cột trong dấu gạch ngược trong tài liệu ánh xạ. Hibernate sẽ sử dụng kiểu trích dẫn chính xác cho Phương ngữ SQL. Đây thường là dấu ngoặc kép, nhưng SQL Server sử dụng dấu ngoặc và MySQL sử dụng dấu ngoặc kép.

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

Trong JPA 2.0, cú pháp được chuẩn hóa và trở thành:

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

Người giới thiệu

Câu hỏi liên quan


Và cảm ơn từ tôi. Nó đã giải quyết một vấn đề mà tôi gặp phải. btw - Tham khảo hiện có tại: docs.jboss.org/hibernate/stable/core/manual/en-US/html/…
Steve

5
Tôi không hiểu tại sao tôi phải làm điều này, tại sao Hibernate không làm điều này tự động thay vì tôi ???
Daniel Hári

@ DanielHári có lẽ bạn thấy câu trả lời của tôi "tự động" hơn?
Rafiek

1
@Rafiek: Ồ vâng, đó là giải pháp hoàn hảo, được ủng hộ (y).
Daniel Hári

1
Sử dụng @Column(name="[open]")nhiều đẹp hơn :)
Waleed Abdalmajeed

16

Thoát khỏi các từ khóa dành riêng theo cách thủ công

Nếu bạn đang sử dụng JPA, bạn có thể thoát bằng dấu ngoặc kép:

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

Nếu bạn đang sử dụng API gốc Hibernate, thì bạn có thể thoát khỏi chúng bằng cách sử dụng backticks:

@Column(name = "`open`")

Tự động thoát các từ khóa dành riêng

Nếu bạn muốn tự động thoát khỏi các từ khóa dành riêng, bạn có thể đặt thành truethuộc tính hibernate.globally_quoted_identifierscấu hình Hibernate cụ thể :

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

Định dạng Yaml

spring:
  jpa:
    properties:
      hibernate:
        globally_quoted_identifiers: true

Để biết thêm chi tiết, hãy xem bài viết này .


15

Nếu bạn sử dụng như hình dưới đây, nó sẽ hoạt động

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

Bạn chỉ làm điều này trên lĩnh vực riêng tư không phải trên getter?
Jake Gaston

5
đây là sqlserver cụ thể.
Alfredo M

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

Điều này chắc chắn sẽ hiệu quả, Vấn đề tương tự đã xảy ra với tôi, khi tôi học ngủ đông.


4

Không - thay đổi tên cột.

Đây là cơ sở dữ liệu cụ thể và bạn không thể tạo một cột như vậy. Sau tất cả hibernate cuối cùng gửi DDL đến cơ sở dữ liệu. Nếu bạn không thể tạo DDL hợp lệ với tên cột này, điều này có nghĩa là chế độ ngủ đông cũng không thể. Tôi không nghĩ rằng trích dẫn sẽ giải quyết được vấn đề ngay cả khi bạn đang viết DDL.

Ngay cả khi bạn thành công bằng cách nào đó thoát khỏi cái tên - hãy thay đổi nó. Nó sẽ hoạt động với cơ sở dữ liệu này, nhưng sẽ không hoạt động với cơ sở dữ liệu khác.


Điều đó có thể hoạt động. Xem stackoverflow.com/questions/285775/… . Chúng ta hãy chờ xác nhận OP.
ewernli

1
Đây không phải là cơ sở dữ liệu cụ thể! Bạn thoát khỏi nó với một `và hibernate dịch nó để phong cách báo giá chính xác cho các thổ ngữ SQL
Daniel Käfer

2

Một số triển khai JPA (ví dụ: cái tôi sử dụng, DataNucleus) tự động trích dẫn số nhận dạng cho bạn, vì vậy bạn sẽ không bao giờ nhận được điều này.


Vâng, ngạc nhiên rằng Hibernate dường như vẫn không cung cấp một tính năng cơ bản như cho số lần người bị ảnh hưởng bởi nó (và ai đó thậm chí downvoted bạn vì dám đề cập đến rằng đây là có thể ở nơi khác)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.