2017-11-15 10 views
1

UNIQUE 제약 조건이있는 열이있는 테이블이 있습니다. 제약 조건 검사가 커밋 시간을 연기하도록하고 싶습니다. 예상대로Hibernate 주석을 사용하여 INITIALLY DEFERRED 제약 조건을 정의 할 수 있습니까?

CREATE TABLE instrument 
(
    id bigint NOT NULL, 
    name character varying(255) NOT NULL, 
    CONSTRAINT instrument_pkey PRIMARY KEY (id), 
    CONSTRAINT instrument_name_key UNIQUE (name) 
    DEFERRABLE INITIALLY DEFERRED 
) 

그리고 모든 작품 : 나는 (많은 열이 생략) 같은 포스트 그레스 SQL을 사용하여 만드는 경우

. 나는 이런 식으로 최대 절전 모드를 정의하는 경우

:

import java.io.Serializable; 
import javax.persistence.*; 
import org.hibernate.annotations.ForeignKey; 

@Entity 
@Table(name="instrument") 
public class Instrument implements Versionable, Serializable { 
    private static final long serialVersionUID = 1L; 

    public static final String NAME_PROPERTY = "name"; 

    @Version 
    private int version; 

    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_GEN") 
    private Long id; 

    @Column(name="name", unique=true, nullable=false) 
    private String name; 

    public Instrument() { 
     // null constructor to make Hibernate happy 
    } 

    public Instrument(String name) { 
     this.name = name; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public Long getId() { 
     return id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    @Override 
    public int hashCode() { 
     return Objects.hashCode(getName()); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (obj instanceof Instrument) { 
      Instrument other = (Instrument)obj; 
      return Objects.equal(getName(), other.getName()); 
     } 
     return false; 
    } 

    @Override 
    public String toString() { 
     return "Instrument [id=" + id + ", name=" + name + "]"; 
    } 
} 

을 그리고 테이블을 만들 hibernate.hbm2ddl create를 사용 INITIALLY DEFERRED 옵션은 내가 알고하지 않기 때문에 예상대로 (이름의 UNIQUE 제약 조건을 지정하지 그것을 묻는 것이다.)

내가 앱을 실행할 때 나쁜 일이 일어난다.

특히 사용자는 두 악기 사이에서 이름을 바꿀 수 있습니다. 그는 INST1 사이 INST2 이름을 교체하려고하면 그것은 예외가 발생합니다 :

org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "instrument_name_key" 
    Detail: Key (name)=(inst1) already exists. 

그래서 질문은 : 컬럼에 제약의 INITIALLY DEFERRED 속성을 지정하는 데 사용할 수있는 최대 절전 모드 주석이 있습니까?

추신 : 나는 해결 방법을 찾고 있지 않습니다. 제약 조건을 적용하는 설치/설정 프로세스에 추가 단계가 있습니다. 내가 바라는 건 그 여분의 단계를 없애는 방법이다.

답변

1

Hibernate는 지연된 제약 조건을 지원하지 않는다. https://hibernate.atlassian.net/browse/HHH-2248

당신의 당신이 이름 INST1INST2와 악기가 있다고 가정하자 entityManager.flush() 메소드를 가지고 노는 시도 할 수 :

또는
Instrument inst1 = entityManager.find(Instrument.class, 1); 
// change name of first Instrument to some random one 
inst1.setName("inst3"); 
entityManager.flush(); 
Instrument inst2 = entityManager.find(Instrument.class, 2); 
inst2.setName("inst1"); 
entityManager.flush(); 
inst1.setName("inst2"); 

당신은 DB에서 개체를 얻을 수, 삭제 DB로부터 그것들을 가져오고, 플러시를 수행하고 업데이트 된 엔티티를 지속시킵니다. 이렇게하면 세 번째 이름을 만들 필요가 없습니다.

이러한 솔루션의 성능 효과에 대해 확신하지 못하면 자신을 알아 내야합니다.