19

フィールドの一種のエキゾチックなマッピングがあります。

@ElementCollection
@CollectionTable(name = "studentGradeLevel", joinColumns = @JoinColumn(name = "studentId"))
@MapKeyJoinColumn(name = "schoolYearId")
@Column(name = "gradeLevel", nullable = false)
@ForeignKey(name = "fkStudentGrade2Student")
private Map<SchoolYear, GradeLevel> gradeLevels;

SchoolYear はエンティティで、GradeLevel は列挙型です。

Hibernate ツールを使用してスキーマの DDL を生成しています。これが生成するスキーマは次のとおりです。

create table studentGradeLevel (
    studentId numeric(19,0) not null,
    gradeLevel int not null,
    schoolYearId int not null,
    primary key (studentId, schoolYearId)
);

alter table studentGradeLevel 
    add constraint FK1BCA4A883A97C498 
    foreign key (schoolYearId) 
    references schoolYear;

alter table studentGradeLevel 
    add constraint fkStudentGrade2Student 
    foreign key (studentId) 
    references student;

問題は、コレクション テーブルとマップ キーとして使用されるエンティティのテーブルの間で、外部キーの制約名を変更できないように見えることです。

@ForeignKey を使用して、@OneToMany、@ManyToMany、およびその他の @ElementCollections の制約名を問題なく指定しました。@ForiegnKey の「inverseName」属性を試しましたが、無視されているようです。@MapKeyJoinColumn には、これに影響するプロパティがないようです。

これを行う方法があるかどうか誰かが知っていますか?

4

2 に答える 2

6

Hibernateが私のために作成したものは実際には役に立たなかったため、異なる外部キー名を作成するためにHibernateにパッチを適用する必要がありました。

Hibernateソースを取得し、クラスのソースをorg.hibernate.mapping.Tableソースフォルダーに配置しました。これは、クラスパスの開始点です(プロジェクトの結果のjarは、hibernate.jarよりも小さい文字で始まるため、これはWebアプリケーションでも機能します。 )。

関数uniqueColumnStringを次のコード(関数の上部にある元のコード)に置き換えました。

    public String uniqueColumnString(Iterator iterator, String referencedEntityName) {
//        int result = 0;
//        if ( referencedEntityName != null ) {
//            result += referencedEntityName.hashCode();
//        }
//        while ( iterator.hasNext() ) {
//            result += iterator.next().hashCode();
//        }
//        return ( Integer.toHexString( name.hashCode() ) + Integer.toHexString( result ) ).toUpperCase();
          StringBuilder retVal = new StringBuilder();
          retVal.append("_").append(referencedEntityName);
          while( iterator.hasNext() ) {
              Column c = (Column)iterator.next();
              retVal.append("_");
              retVal.append(c.getName());
          }
          return retVal.toString();
    }

これにより、「_ Entity_attributeName_id」のような適切な文字列が自動的に返され、「fk_Entity_attributeName_id」のような外部キーを作成するために使用されます。もう一度私の名前を手で指定する必要はありません:)))

于 2011-03-07T17:48:15.683 に答える
0

私は同じ問題を抱えていましたが、それを行う方法が見つからなかったため、データベース自体にクエリを実行してその情報を取得することになりました。

このクエリを SQL SERVER で実行する

select kcu.TABLE_NAME, kcu.CONSTRAINT_NAME, tc.CONSTRAINT_TYPE, kcu.COLUMN_NAME
from INFORMATION_SCHEMA.TABLE_CONSTRAINTS as tc
join INFORMATION_SCHEMA.KEY_COLUMN_USAGE as kcu
on kcu.CONSTRAINT_SCHEMA = tc.CONSTRAINT_SCHEMA
and kcu.CONSTRAINT_NAME  = tc.CONSTRAINT_NAME
and kcu.TABLE_SCHEMA    = tc.TABLE_SCHEMA
and kcu.TABLE_NAME = tc.TABLE_NAME

テーブル名、制約名 (FK1BCA4A883A97C498 など)、タイプ (UNIQUE 制約など)、および列名を取得します。これは、意味のあるエラー メッセージを返すのに十分なはずです。

データベースの移植性を失っているため、あまり良くないことはわかっていますが、現時点で求めていることを実行する方法はないようです...

于 2011-03-06T02:05:07.490 に答える