【问题标题】:How to map multiple composite keys in Hibernate?如何在 Hibernate 中映射多个复合键?
【发布时间】:2017-08-19 21:28:48
【问题描述】:

我有一个包含 3 个主键的表。他们是custom_idpatient_idpatientservice_provider_type_idservice_provider_type。我当前的映射如下所示

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="beans.ServiceProvider" table="service_provider" catalog="myglukose" optimistic-lock="version">
        <id name="customId" type="string">
            <column name="custom_id" not-null="true"/>
        </id>
        <many-to-one name="patient" class="beans.Patient" fetch="select">
            <column name="patient_idpatient" not-null="true"/>
        </many-to-one>
        <many-to-one name="serviceProviderType" class="beans.ServiceProviderType" fetch="select">
            <column name="service_provider_type_idservice_provider_type" not-null="true"/>
        </many-to-one>
        <property name="dateCreated" type="timestamp">
            <column name="date_created" length="19" />
        </property>
        <property name="lastUpdated" type="timestamp">
            <column name="last_updated" length="19" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

我的 SQL 代码

CREATE TABLE IF NOT EXISTS `xxx`.`service_provider` (
  `custom_id` VARCHAR(45) NOT NULL,
  `patient_idpatient` INT NOT NULL,
  `service_provider_type_idservice_provider_type` INT NOT NULL,
  `date_created` TIMESTAMP NULL,
  `last_updated` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  INDEX `fk_service_provider_patient1_idx` (`patient_idpatient` ASC),
  INDEX `fk_service_provider_service_provider_type1_idx` (`service_provider_type_idservice_provider_type` ASC),
  PRIMARY KEY (`custom_id`, `patient_idpatient`, `service_provider_type_idservice_provider_type`),
  CONSTRAINT `fk_service_provider_patient1`
    FOREIGN KEY (`patient_idpatient`)
    REFERENCES `xxx`.`patient` (`idpatient`)
    ON DELETE CASCADE
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_service_provider_service_provider_type1`
    FOREIGN KEY (`service_provider_type_idservice_provider_type`)
    REFERENCES `xxx`.`service_provider_type` (`idservice_provider_type`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

如何映射这 3 个复合键?

【问题讨论】:

  • 你真的是指多个主键吗?还是您的意思是复合主键?我认为不可能有多个 pkey....
  • patient_idpatientservice_provider_type_idservice_provider_type 不是 service_provider 的主键,它们是该表中的外键,因为它们是其他表的主键跨度>
  • @Ben:好的,所以我是通过mysql work bench 创建的。是的,我认为您是正确的,请检查更新。

标签: java mysql hibernate hibernate-mapping composite-primary-key


【解决方案1】:

您正在寻找一个复合键,而不是多个 PKey。

这在 Hibernate 中可能如下所示(通过 hbm.xml):

<composite-id name="compId">
   <key-property name="customId” column="custom_id" />
   <key-property name="patientIdpatient" column="patient_idpatient" />
   <key-property name="serviceProviderTypeIdserviceProviderType" column="service_provider_type_idservice_provider_type" />
</composite-id>

或带有注释之类的样式:

搜索@EmbeddedId

您可以阅读更多详细信息,例如此处(类似问题): How to map a composite key with Hibernate?

编辑
这是一个简单的代码示例,它(也许)可以帮助您显示正确的方向:

您的 hbm.xml 可能看起来像(未经测试,如果不进行更正,代码可能无法正常工作!):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="beans.ServiceProvider" table="service_provider" catalog="myglukose" optimistic-lock="version">

        <composite-id name="myId">
            <key-property name="customId” column="custom_id" />
            <key-property name="patientIdpatient" column="patient_idpatient" />
            <key-property name="serviceProviderTypeIdserviceProviderType" column="service_provider_type_idservice_provider_type" />
        </composite-id>

        <!-- not sure with this part...maybe not needed -->
        <many-to-one name="patient" class="beans.Patient" fetch="select">
            <column name="patient_idpatient" not-null="true"/>
        </many-to-one>

        <!-- not sure with this part...maybe not needed -->
        <many-to-one name="serviceProviderType" class="beans.ServiceProviderType" fetch="select">
            <column name="service_provider_type_idservice_provider_type" not-null="true"/>
        </many-to-one>

        <property name="dateCreated" type="timestamp">
            <column name="date_created" length="19" />
        </property>

        <property name="lastUpdated" type="timestamp">
            <column name="last_updated" length="19" not-null="true" />
        </property>

    </class>
</hibernate-mapping>

这可能是 Id-Class:(未测试!):

import java.io.Serializable;

public class MyId implements Serializable {
  private beans.ServiceProviderType spt;
  private int customId;
  private beans.Patient pat;

  // an easy initializing constructor
  public MyId(int customId, beans.Patient pat, beans.ServiceProviderType spt) {
    this.pat = pat;
    this.customId = customId;
    this.spt = spt;
  }

  public beans.Patient getPatient() {
    return pat;
  }

  public void setPatient(beans.Patient pat) {
     this.pat = pat;
  }

  public beans.ServiceProviderType getServiceProviderType() {
    return spt;
  }

  public void setServiceProviderType(beans.ServiceProviderType pat) {
     this.spt = spt;
  }

  public int getCustomId() {
     return customerId;
  }

  public void setCustomId(int customId) {
    this.customId = customId;
  }

  @Override
  public boolean equals(Object arg0) {
    //needs implementation
  }

  @Override
  public int hashCode() {
    //needs implementation
  }
}

【讨论】:

  • 谢谢。您可以通过将代码添加到我给定的映射代码中来编辑它吗?在添加您的代码之前,我找不到是否应该删除我已经完成的关系映射,是否应该删除我已经完成的主键映射等等。
  • @PeakGen 看到我的编辑。您只需尝试一下(并阅读文档),这很容易......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-12
  • 2011-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-18
  • 2023-04-03
相关资源
最近更新 更多