2015-06-14 79 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)。

[我对你的模型做了一些假设;所以我希望这个建议有意义。]