2012-02-10 121 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,在第二列中插入最大ID。這可以通過一個簡單的檢查約束來實現。 – 2012-02-10 16:05:40

+0

你是指觸發器?解決方案聽起來不錯。我必須找出如何編寫該觸發器。 – BigJ 2012-02-10 17:11:20

+0

我不認爲它是有效的,因爲TagRelation實體已經設置了tag_1和tag_2引用。您建議的觸發器可能會在插入數據庫時​​將其轉向,導致TagRelation實體和數據庫之間不一致。但也許我可以做一個觸發器來檢查數據庫中是否存在唯一的關係。 – BigJ 2012-02-10 17:18:17

回答

0

關係類型在運行時是否動態?如果不是我想你會得到更好的直接在標籤放置的關係:

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

這會讓你的關係,更安全和更高性能。

+0

我實際上實施了JB Nizet的解決方案,工作正常。我不確定我是否瞭解您的解決方案。它必須有可能有多個相同類型的關係,但我猜你的解決方案中的標籤關係可以更改爲列表。但在這種情況下,JPA將創建3個連接表。然後,我自己創建一個tag_relation會更容易。 – BigJ 2012-11-20 15:50:07