【问题标题】:JPA: many-to-many relationship with @JoinTable having the same column for each side of relationshipJPA:与@JoinTable 的多对多关系在关系的每一侧都具有相同的列
【发布时间】:2015-06-14 15:13:19
【问题描述】:

我想在 2 个实体之间有一个 JoinTable,这两个实体派生自同一个所有者实体。因此,当使用@ManyToMany 关系加入这些实体时,我得到了@JoinTable(如下面的 DDL):

 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 的提供者的工作场所提供。所以最好在每个 ForeignKey 之间共享这个 @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 的冗余列

【问题讨论】:

    标签: hibernate jpa many-to-many entities jointable


    【解决方案1】:

    在某些方面,以这种方式映射您的模型并没有多大意义。您的多对多关系中没有任何内容可以保证关系中的Services 和Locations 必须具有相同的Provider。我会更改您的对象模型以明确该要求。在Provider 和一个新对象ServiceProvidedOn 之间添加一对多关系(不是最伟大的名字;也许类似于ServiceOccurrence?)。所以Provider 会有一个集合属性serviceProvidedOns;并且新类ServiceProvidedOn 将具有三个属性providerserviceworkStation(适当映射)。 ServiceProvidedOn 的主键将派生自其他三个对象(ProviderServiceWorkStation)。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-24
      • 2016-05-02
      • 2014-05-16
      • 1970-01-01
      • 1970-01-01
      • 2012-06-14
      • 1970-01-01
      相关资源
      最近更新 更多