2011-05-15 62 views
1

我面臨着以下問題 problem冬眠唯一約束

,P:我們來看看在上面的鏈接

在commnets :)雖然解決它,我現在有一個關於如何的問題唯一的約束是在hibernate中實現的,我開始相信它激發了一個選擇查詢(我對此不確定),然後「一些如何」執行驗證。

我不是很不服氣,與解釋

回答

4

休眠創建該列有「獨特」的指標,它是那麼強制執行uniquness數據庫。

舉例來說,如果你有一個類:

@Entity 
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) 
public class UserEmailAddressEntity { 
    @Id 
    @Basic(optional = false) 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    @Basic(optional = false) 
    private boolean primaryEmail; 

    @ManyToOne(optional = false) 
    private UserEntity user; 

    @NaturalId // this means the email column must be unique 
    @Basic(optional = false) 
    private String email; 

    @Basic(optional = false) 
    private String token; 

    @Basic(optional = false) 
    private boolean verified; 
} 

休眠創建一個表像這樣:(PostgreSQL的,但這個想法是一樣的幾乎所有RDBMS)

CREATE TABLE useremailaddressentity 
(
    id bigint NOT NULL, 
    email character varying(255) NOT NULL, 
    primaryemail boolean NOT NULL, 
    token character varying(255) NOT NULL, 
    verified boolean NOT NULL, 
    user_id bigint NOT NULL, 
    CONSTRAINT useremailaddressentity_pkey PRIMARY KEY (id), 
    CONSTRAINT fk279a5e06c843ec30 FOREIGN KEY (user_id) 
     REFERENCES userentity (id) MATCH SIMPLE 
     ON UPDATE NO ACTION ON DELETE NO ACTION, 

    -- note the `UNIQUE` here: 
    CONSTRAINT useremailaddressentity_email_key UNIQUE (email) 
) 
+0

我認爲一樣多,但是如果你看給定鏈路上的評論,你會看到,當我有得天獨厚的約束..休眠被射擊session.save查詢(實體),當我刪除約束時,它不會觸發,對此有什麼想法? – Sudarshan 2011-05-15 13:51:24

+0

我試圖在本地重新創建該行爲,但我沒有任何運氣,對不起:(即使有一個獨特的約束,它會直接插入(對於新實體)或更新(當...更新時) – wmacura 2011-05-15 23:37:44

0

我試圖複製這種行爲,我使用使用grails 1.3.7,並發現它是可重複的

class Child { 
String name 
static constraints = { name(unique:true) } 

}

table created 
CREATE TABLE `child` (
    `id` BIGINT(20) NOT NULL AUTO_INCREMENT, 
    `name` VARCHAR(255) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `name` (`name`) 
) 

查詢上 child.save()發射

Hibernate: select this_.id as id0_0_, this_.version as version0_0_, this_.created_by as created3_0_0_, this_.date_created as date4_0_0_, this_.last_updated as last5_0_0_, this_.name as name0_0_, this_.updated_by as updated7_0_0_ from child this_ where this_.name=? 
Hibernate: insert into child (version, created_by, date_created, last_updated, name, updated_by) values (?, ?, ?, ?, ?, ?) 

究其原因,我想我休眠觸發以上查詢是檢查唯一約束,而如果你試圖執行更新那麼這個查詢將導致另一個在內存中具有相同標識符的對象,這可能導致非唯一性觀察。

我以爲這是hibernate而不是grails,沒有在java/hibernate中雙重檢查過這個。

感謝

+0

Can任何人都可以確認這種行爲是否特定於grails,在使用@UniqueConstraints時我沒有看到類似的行爲 – Sudarshan 2011-06-29 15:06:29

+2

這是Grails特有的,也是非常可疑的(唯一性可能會在SQL檢查和tx提交之間同時發生變化) – Vincent 2013-10-01 15:53:57