2012-02-10 16 views
2

"タグ"エンティティとの関係を作りたい。関係は双方向であり、私の実体「TagRelation」に格納されています。JPA - ユニークな双方向エンティティの関係

enter image description here

関係の方向は意味を持たないため、各タグの関係は唯一、tag_relationsテーブル内の1つのエントリを持つ必要があります。私は挿入した場合例:

"森"(タグ1)< - > "ツリー"(タグ2)

私は関係に周りに他の方法を挿入することが可能であるべきではない:

」ツリー」(タグ1)< - > "森"(タグ2)

これは、テーブルtag_relationのSQLコードです:

CREATE TABLE IF NOT EXISTS `tag_relation` (
    id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT , 
    `tag_id_1` INT(10) UNSIGNED NOT NULL , 
    `tag_id_2` INT(10) UNSIGNED NOT NULL , 
    `type` ENUM('related_subject','synonymous','alternative_writing') NOT NULL , 
    PRIMARY KEY (`id`) , 
    INDEX `fk_tag_1` (`tag_id_1` ASC) , 
    INDEX `fk_tag_2` (`tag_id_2` ASC) , 
    UNIQUE INDEX `ux_relation_1_2` (`tag_id_1` ASC, `tag_id_2` ASC) , 
    UNIQUE INDEX `ux_relation_2_1` (`tag_id_2` ASC, `tag_id_1` ASC) , 
    CONSTRAINT `fk_tag_1` 
     FOREIGN KEY (`tag_id_1`) 
     REFERENCES `mm`.`tag` (`id`) 
     ON DELETE NO ACTION 
     ON UPDATE NO ACTION, 
    CONSTRAINT `fk_tag_2` 
     FOREIGN KEY (`tag_id_2`) 
     REFERENCES `mm`.`tag` (`id`) 
     ON DELETE NO ACTION 
     ON UPDATE NO ACTION) 
ENGINE = InnoDB 
AUTO_INCREMENT = 1 

彼らのように一意索引今私が望む一意の関係を強制することはありません。私はこれを私のデータベースにどのように強制することができますか?

+1

私は専門家ではないので、より良い解決策があるかもしれません。しかし、[tag1、tag2]が[tag2、tag1]と等しいと考えると、カップルは常に最初の列に最も低いIDで挿入され、2番目の列では最大のIDで挿入されるというルールを適用することができます。これは、単純なチェック制約によって制限することができます。 –

+0

トリガーを意味するのですか?解決策は良いと思う。そのトリガーを書く方法を見つけなければなりません。 – BigJ

+0

TagRelationエンティティが既にtag_1とtag_2の参照を設定していたため、動作しないと思います。あなたが提案したトリガーは、DBに挿入されたときにそれらを回す可能性があり、TagRelationエンティティとデータベースの間に矛盾が生じます。しかし、おそらく私は、すでにデータベース内にユニークな関係があるかどうかをチェックするトリガーを作ることができます。 – BigJ

答えて

0

実行時にリレーションタイプが動的かどうかを確認します。いない場合、私はあなたがタグに直接の関係を置く方が良いだろうと思う:

public class Tag{ 
    @OneToOne private Tag related_subject; 
    @OneToOne private Tag synonymous; 
    @OneToOne private Tag alternative_writing; 
    //setters and getters 
} 

これはあなたの関係は、より安全で、よりパフォーマンスになります。

+0

JB Nizetのソリューションを実際に実装しました。これはうまく動作します。私はあなたの解決策を理解しているかどうかはわかりません。同じタイプの複数のリレーションを持つことは可能でなければなりませんが、ソリューションのタグリレーションをList に変更することができます。しかし、その場合、JPAは3つの接続テーブルを作成します。それで、自分でtag_relationを作成する方が簡単です。 – BigJ

関連する問題