JPA에서 이름이 예약어 인 엔티티 필드를 매핑하는 방법


92
@Column(name="open")

최대 절전 모드에서 sqlserver dialect 사용.

[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
괜찮아. 맞지 않는 이름보다 이스케이프 된 예약어를 하루 종일 이름으로 선호합니다.
Josh M.

예, Hibernate가 제공하는 추상화는 기술적으로 구현되는 방식이 아니라 단지 관심사라고 말할 수 있습니다. 그러나 Flyway 또는 Liquibase와 같은 도구를 사용하는 경우 예약어가있을 수 있다는 점을 고려해야 할 때 복잡성이 추가됩니다. 이것은 스키마를 마이그레이션 할 때의 경험이었습니다.
Rafiek

2
이것이 어디에 설정되어야하는지 궁금한 사람들을 persistence.xml위해 아마도 JBoss 프로젝트에 있을 것입니다 .
Addison

138

Hibernate를 JPA 1.0 공급자로 사용하면 예약 된 키워드를 백틱으로 묶어 이스케이프 할 수 있습니다.

@Column(name="`open`")

다음은 Hiberate Core에서 상속 된 구문입니다.

5.4. SQL 인용 식별자

매핑 문서에서 테이블 또는 열 이름을 백틱으로 묶어 Hibernate가 생성 된 SQL에서 식별자를 인용하도록 할 수 있습니다. Hibernate는 SQL Dialect에 대해 올바른 인용 스타일을 사용합니다. 일반적으로 큰 따옴표이지만 SQL Server는 대괄호를 사용하고 MySQL은 백틱을 사용합니다.

<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 심판은 지금 : docs.jboss.org/hibernate/stable/core/manual/en-US/html/...
스티브

5
왜 내가 이것을해야하는지, 왜 Hibernate가 나 대신에 이것을 자동으로하지 않는지 이해하지 못한다. ???
Daniel Hári

@ DanielHári 어쩌면 내 대답이 "자동"이라고 생각합니까?
Rafiek

1
@Rafiek : 오 예, 그것은 완벽한 솔루션입니다, upvoted (y).
Daniel Hári

1
사용하여 @Column(name="[open]")훨씬 예뻐은 :)입니다
왈 리드 Abdalmajeed

16

예약 된 키워드를 수동으로 이스케이프

JPA를 사용하는 경우 큰 따옴표로 이스케이프 할 수 있습니다.

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

Hibernate 네이티브 API를 사용하는 경우 백틱을 사용하여 이스케이프 할 수 있습니다.

@Column(name = "`open`")

예약 된 키워드 자동 이스케이프

예약 된 키워드를 자동으로 이스케이프 true하려면 Hibernate 관련 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 2010

1
이것은 데이터베이스에만 국한되지 않습니다! 당신은 SQL 방언에 대한 올바른 인용 스타일로 번역으로 탈출`와 최대 절전 모드
다니엘 Käfer

2

일부 JPA 구현 (예 : 내가 사용하는 DataNucleus)은 식별자를 자동으로 인용하므로 절대 얻을 수 없습니다.


예, Hibernate는 겉으로는 여전히 (심지어이 가능한 곳이라고 언급 감히 당신을을 downvoted 누군가) 사람들이 그것을에 치여 죽게 횟수 주어진 이러한 기본 기능을 제공하지 않습니다 놀라게
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.