2012-08-15 31 views
1

命名多列約束@UniqueConstraintname屬性似乎不起作用。使用JPA

@Entity 
@Table(name = "TAG", uniqueConstraints = @UniqueConstraint(columnNames = { 
     "TAG_NAME", "USERS_ID" }, name="UQ_TAG_USER")) 
public class Tag extends BaseEntity { 

} 

我usning SQL Server 2008JPA 2.0Hibernate 3.6

在數據庫端創建索引UQ__TAG__6EF57B66而不是UQ_TAG_USER

我錯過了什麼?有沒有辦法強制從Java方面給定的名稱?並且必須要求編輯模式文件?我們是一家沒有DBA的小型商店,我儘可能地利用hibernate架構設施做好準備。

回答

3

我假設你正在使用hibernate,因爲你在這個問題的標籤中有它。這是一個錯誤/丟失功能處於休眠:

https://hibernate.onjira.com/browse/HB-1245

當方言支持創建作爲創建表的相同語句約束它會簡單地忽略唯一約束的名稱。 我檢查過SqlServer和Oracle方言,他們都支持這種創建約束的方式,這會導致你遇到的錯誤。

有兩種方法來解決此錯誤:

1.快捷方式:
只是延長方言和supportsUniqueConstraintInCreateAlterTable()方法返回false:

public static class SQLServerDialectImproved extends SQLServerDialect { 
    @Override 
    public boolean supportsUniqueConstraintInCreateAlterTable() { 
     return false; 
    } 
} 

並將此作爲類你的方言在hibernate.dialect持久性單元配置屬性(persistence.xml)。

2.正確方法:
修復Hibernate代碼並重新編譯:
bug是在org.hibernate.mapping.UniqueKey類,方法sqlConstraintString()將返回unique (TAG_NAME, USERS_ID)所有的方言,即使他們支持constraint UQ_TAG_USER unique (TAG_NAME, USERS_ID)
但是,這可能是一個較大的變化(需要支持各種方言等)

引擎蓋下:
如果使用原來的話,它會導致下面的SQL語句將被執行創建表(添加ID列):

create table TAG (
    id bigint not null, 
    TAG_NAME varchar(255), 
    USERS_ID varchar(255), 
    primary key (id), 
    unique (TAG_NAME, USERS_ID) 
) 

並應用修正後的第一選擇,因爲聲明如下SQL語句將被執行:

create table TAG (
    id numeric(19,0) not null, 
    TAG_NAME varchar(255), 
    USERS_ID varchar(255), 
    primary key (id) 
) 

create unique index UQ_TAG_USER on TAG (TAG_NAME, USERS_ID) 

其中包括在單獨的語句中使用所選名稱(UQ_TAG_USER)創建唯一約束。

+0

不幸的是,上面的快速解決方案似乎不起作用,至少使用Hibernate 4.1.7和PostgreSQL82Dialect。 create table語句的「unique」子句確實被抑制,但沒有生成「create unique index」語句。 – 2013-09-18 01:01:32