1

name属性は@UniqueConstraint効果がないようです。

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

}

を使用SQL Server 2008JPA 2.0ていHibernate 3.6ます。

UQ__TAG__6EF57B66DB 側では、代わりにインデックスが作成されますUQ_TAG_USER

私は何が欠けていますか?Java側から指定された名前を強制する方法はありませんか? スキーマファイルの編集に頼る必要がありますか? 私たちは DBA のいない小さなショップであり、休止状態スキーマ機能の助けを借りてできる限りのことをしようとしています。

4

1 に答える 1

3

この質問のタグにHibernateが含まれているため、Hibernateを使用していると思います。これはHibernateのバグ/欠落機能です:

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

方言がcreatetableと同じステートメントでの制約の作成をサポートしている場合は、一意の制約名を単に無視します。SqlServerとOracleの方言を確認しましたが、どちらもこの制約の作成方法をサポートしているため、発生しているバグが発生します。

このバグを回避するには、次の2つの方法があります。

1.簡単な方法:
方言を拡張し、メソッドに対してfalseを返すだけですsupportsUniqueConstraintInCreateAlterTable()

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

そして、このクラスをhibernate.dialect永続性ユニット構成のプロパティの方言として設定します(persistence.xml)。

2.正しい方法:
休止状態のコードを修正して再コンパイルします
。バグは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)を使用した一意の制約の作成が含まれます。

于 2012-08-23T19:25:39.487 に答える