최대 절전 모드 주석의 @UniqueConstraint 및 @Column (unique = true)


104

@UniqueConstraint@Column (unique = true)의 차이점은 무엇입니까 ?

예를 들면 :

@Table(
   name = "product_serial_group_mask", 
   uniqueConstraints = {@UniqueConstraint(columnNames = {"mask", "group"})}
)

@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private ProductSerialMask mask;

@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private Group group;

2
참고 : Hibernate 5.4에서는을 추가했을 때 unique=true스키마 자동 업데이트 프로그램에 의해 인덱스가 추가되지 않았습니다. @UniqueConstraint나타나게했다. 버그 일 수 있습니다.
Ondra Žižka

답변:


147

앞서 말했듯 이는 단일 필드 일 때 @Column(unique = true)의 지름길 UniqueConstraint입니다.

당신이 준 예에서, 둘 사이에는 큰 차이가 있습니다.

@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private ProductSerialMask mask;

@Column(unique = true)
@ManyToOne(optional = false, fetch = FetchType.EAGER)
private Group group;

이 코드는 mask및 둘 다 group고유해야하지만 별도로 있어야 함을 의미합니다 . 예를 들어, 당신이 가진 기록을 가지고있는 경우 것이 그 수단 mask.id = 1 과 다른 레코드 삽입하고 시도 mask.id = 1을 그 열이 고유 한 값을 가져야하기 때문에, 당신은 오류가 발생합니다. 그룹에도 동일하게 적용됩니다.

반면에

@Table(
   name = "product_serial_group_mask", 
   uniqueConstraints = {@UniqueConstraint(columnNames = {"mask", "group"})}
)

결합 된 마스크 + 그룹의 값이 고유해야 함을 의미합니다. 당신은 할 수있는 것을 의미한다, 예를 들어,와 기록 mask.id = 1group.id = 1 , 당신과 다른 레코드를 삽입하려고하면 = 1 mask.idgroup.id = 2 , 그것은 삽입됩니다 첫 번째 경우에는 그렇지 않습니다.

마스크와 그룹을 개별적으로 그리고 클래스 수준에서 고유하게하려면 다음과 같이 코드를 작성해야합니다.

@Table(
        name = "product_serial_group_mask",
        uniqueConstraints = {
                @UniqueConstraint(columnNames = "mask"),
                @UniqueConstraint(columnNames = "group")
        }
)

이것은 첫 번째 코드 블록과 동일한 효과가 있습니다.


고유 제약 조건이 생성되면 JPA 리포지토리에서 이름으로 제약 조건을 참조하여 쿼리 할 수 ​​있습니까?
jDub9

@ jDub9 인덱스를 쿼리 할 수 ​​없습니다. 하나의 쿼리로 마스크 및 그룹 열을 쿼리 할 수 ​​있으며 빠른 처리를 위해 해당 인덱스를 사용하지만 (운이 좋다면) 단순히 인덱스를 쿼리 할 수는 없습니다.
Dalibor Filus

columnNames는 데이터베이스의 실제 이름이어야합니다. 그것은해야 mask_id하고 group_id기본적 명명 전략을 사용하는 경우.
시험관

27

Java EE 문서에서 :

public abstract boolean unique

(선택 사항) 속성이 고유 키인지 여부. 이것은 테이블 수준에서 UniqueConstraint 주석에 대한 바로 가기이며 고유 키 제약 조건이 단일 필드 일 때 유용합니다. 이 제약 조건은 기본 키 매핑 및 테이블 수준에서 지정된 제약 조건에 추가로 적용됩니다.

문서 참조


그래서이 코드를 사용할 때 : @Column (unique = true) @ManyToOne (optional = false, fetch = FetchType.EAGER) private ProductSerialMask mask; @Column (unique = true) @ManyToOne (선택 사항 = false, fetch = FetchType.EAGER) 개인 그룹 그룹; 두 개의 인덱스가 있지만 다른 방법으로 사용할 때 두 개의 열이 결합 된 하나의 인덱스가 있습니까?
navid_gh 2013 년

22

보아스의 대답 외에도 ....

@UniqueConstraint제약 조건의 이름을 지정할 수 @Column(unique = true)있으며 임의의 이름 (예 :) 을 생성합니다 UK_3u5h7y36qqa13y3mauc5xxayq.

때로는 제약 조건이 어떤 테이블과 연관되어 있는지 아는 것이 도움이 될 수 있습니다. 예 :

@Table(
   name = "product_serial_group_mask", 
   uniqueConstraints = {
      @UniqueConstraint(
          columnNames = {"mask", "group"},
          name="uk_product_serial_group_mask"
      )
   }
)

5

@Boaz와 @ vegemite4me의 답변 외에도 ....

구현함으로써 ImplicitNamingStrategy제약 조건을 자동으로 명명하는 규칙을 만들 수 있습니다. metadataBuilderHibernate의 초기화 중에 이름 지정 전략을 추가합니다 .

metadataBuilder.applyImplicitNamingStrategy(new MyImplicitNamingStrategy());

항상 임의의 이름을 생성하는에서는 작동 @UniqueConstraint하지만에서는 작동 하지 않습니다 @Column(unique = true)(예 : UK_3u5h7y36qqa13y3mauc5xxayq).

이 문제를 해결하기위한 버그 보고서가 있으므로 가능하면 투표 하여이 문제를 구현하십시오. 여기 : https://hibernate.atlassian.net/browse/HHH-11586

감사.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.