2015-06-14 93 views
1

我想在兩個實體之間有一個JoinTable,這兩個實體是從同一個所有者實體派生的。因此,使用@ManyToMany關係我有@JoinTable(如在下面DDL)加入這個實體時:JPA:與@JoinTable的多對多關係每個關係都有相同的列

CREATE TABLE IF NOT EXISTS `local_services`.`service_provided_on` (
    `provider_id` INT UNSIGNED NOT NULL, 
    `service_id` INT UNSIGNED NOT NULL, 
    `service_point_no` INT UNSIGNED NOT NULL, 
    `work_station_no` INT UNSIGNED NOT NULL, 
    PRIMARY KEY (`provider_id`, `service_id`, `service_point_no`, `work_station_no`), 
    INDEX `fk_provider_service_has_work_station_work_station1_idx` (`service_point_no` ASC, `work_station_no` ASC, `provider_id` ASC), 
    INDEX `fk_provider_service_has_work_station_provider_service1_idx` (`provider_id` ASC, `service_id` ASC), 
    CONSTRAINT `fk_service_provided_on_provider_service` 
    FOREIGN KEY (`provider_id` , `service_id`) 
    REFERENCES `local_services`.`provider_service` (`provider_id` , `service_id`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE, 
    CONSTRAINT `fk_service_provided_work_station` 
    FOREIGN KEY (`service_point_no` , `work_station_no` , `provider_id`) 
    REFERENCES `local_services`.`work_station` (`service_point_no` , `work_station_no` , `provider_id`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE) 
ENGINE = InnoDB 

正如你可以看到有2個外鍵和他們每個人使用相同的PROVIDER_ID列。我想定義使用這個@JoinTable,給定提供者提供的服務屬於它的WorkPlace(WorkStation)。顯而易見的是,服務商提供的ID爲ex。 5只能在屬於id爲5的提供者的工作場所提供。所以最好的做法是在每個ForeignKeys之間共享這個@JoinColumn。並嘗試例如插入工作場所/服務與不匹配的提供商ID以引發一些異常!

我嘗試做這樣的事情:

@ManyToMany(fetch = FetchType.LAZY) 
    @JoinTable(name = "service_provided_on", 
      joinColumns = { 
        @JoinColumn(name = "provider_id", referencedColumnName = "provider_id", nullable = false, columnDefinition = "BIGINT UNSIGNED"), 
        @JoinColumn(name = "service_id", referencedColumnName = "service_id", nullable = false, columnDefinition = "INT UNSIGNED") 
      }, 
      inverseJoinColumns = { 
        @JoinColumn(name = "provider_id", referencedColumnName = "provider_id", insertable = false, updatable = false), 
        @JoinColumn(name = "service_point_no", referencedColumnName = "service_point_no", nullable = false, columnDefinition = "INT UNSIGNED"), 
        @JoinColumn(name = "work_station_no", referencedColumnName = "work_station_no", nullable = false, columnDefinition = "INT UNSIGNED") 
      } 
    ) 

但它顯然是行不通的,提高的例外是這樣的:

Caused by: org.hibernate.MappingException: Repeated column in mapping for collection: pl.salonea.entities.WorkStation.providedServices column: provider_id"}} 

我考慮重新命名爲一個外鍵此PROVIDER_ID前。 work_station_provider_id,但然後我會被允許插入不匹配的provider_ids,也許我可以定義一些CONSTRAINT來阻止這種行爲(如何在JPA中定義這個)?它可以工作,但我會有相同的提供冗餘列provider_id

回答

0

在某些方面,以這種方式映射模型並不合理。您的多對多關係中沒有任何內容保證關係中的ServiceLocation必須具有相同的Provider。我會改變你的對象模型來明確這個需求。在Provider和新對象ServiceProvidedOn(不是最大的名稱;可能類似ServiceOccurrence?)之間添加一對多關係。所以Provider將有一個集合屬性serviceProvidedOns;並且新類ServiceProvidedOn將具有三個屬性provider,serviceworkStation(適當映射)。 ServiceProvidedOn的主鍵可能來自其他三個對象(ProviderServiceWorkStation)。

[我對你的模型做了一些假設;所以我希望這個建議有意義。]