【问题标题】:The concept for one-to-one mapping. Explain the mapping一对一映射的概念。解释映射
【发布时间】:2013-06-19 12:20:57
【问题描述】:

如何定义两个类之间的One-to-One 关系?从概念上讲,我认为我在某个地方出错了。我不知道是什么,但确实如此。

假设有两个类名为CountryPM

Country
  int c_id
  String name_c

PM
 int c_id
 String name_pm

现在对于一个国家,只能有一位 PM,并且 PM 只能属于一个国家。如何在我的映射文件中执行此操作?

我正在尝试这个:

<class name="pojo.Country" table="country">
      <id name="c_id">
          <generator class="increment" />
      </id>
      <property name="name_c" />
      <one-to-one class="pojo.PM" name="name_pm" />
  </class>

  <class name="pojo.PM" table="pm">
      <id name="c_id">
          <generator class="increment" />
      </id>
      <property name="name_pm"  />
  </class>

但是这个有效的映射除了在运行时产生异常之外什么也没做。它说在Country 类中找不到属性name_pm!但它是否在 Country 类中搜索。它应该在 PM 类中搜索。

还帮助我完成我的one-to-one 两个类之间的映射。我已经尝试了一段时间。

Java 代码:

国家

    public class Country {
    private int c_id;
    private String name_c;

    public int getC_id() {
        return c_id;
    }

    public void setC_id(int c_id) {
        this.c_id = c_id;
    }

    public String getName_c() {
        return name_c;
    }

    public void setName_c(String name_c) {
        this.name_c = name_c;
    }

}

下午

    public class PM {
    private int c_id;
    private String name_pm;

    public int getC_id() {
        return c_id;
    }

    public void setC_id(int c_id) {
        this.c_id = c_id;
    }

    public String getName_pm() {
        return name_pm;
    }

    public void setName_pm(String name_pm) {
        this.name_pm = name_pm;
    }

}

【问题讨论】:

  • 这不是一个有效的例子,因为一个国家不一定有总理。在一对一映射中,一个集合的每个元素都与另一个集合的唯一元素相关联。

标签: java hibernate jakarta-ee hibernate-mapping


【解决方案1】:

如果您的问题的一部分也是“......我认为我在某个地方出错了,概念上......”,我想提供一些解释。

首先,One-to-One 表示引用在对象(实例)之间。换句话说,必须有从一个对象到另一个对象的引用。不仅是常见的简单类型(即String name_pmString name_c

两个对象应该相互引用:

public class PM {
    private Country country;  // reference to an instance of the PM
    ...
}

public class Country {
    private PM pm; // reference to an instance of the Country
    ...
}

DB 级别上,它有点棘手。因为引用是基于 ID 列的,我们向我们保证,这两个 Country-PM 将始终属于一起,我们必须重用 ID 值。

所以,一个对象将扮演主人的角色,例如。 Country 和 second 将根据它分配其 ID。如果我们不遵循这种模式,我们无法确定迟早会出现一些many-to-onemany-to-many 关系。

这就是为什么映射通常看起来像这样

<class name="pojo.Country" table="country">
    <id name="c_id">
        <generator class="increment" />
    </id>
    <property name="name_c" />
    <one-to-one class="pojo.PM" name="pm" cascade="save-update" />
</class>

<class name="pojo.PM" table="pm">
    <id name="pmid" type="java.lang.Integer">
        <column name="c_id" />
        <generator class="foreign">
           <param name="property">country</param>
        </generator>
    </id>
    <one-to-one name="country" class="pojo.Country" constrained="true" />
</class>

但是一对一的映射真的很特别。我想在 PM 端映射多对上(在 DB 中带有国家 ID 参考)可能更合适。这是完全不同的方法,但是...

请尝试看看这篇好文章:

【讨论】:

  • 我们可以在这里讨论吗@chat.stackoverflow.com/rooms/32215/…
  • +1:我相信可以实现单向一对一,但通常双向更好,这是一个很好的解释。
  • @DonRoby 非常感谢。我开始写下来,当你的回答要求更多信息时......我花了一点时间;)也给你+1!
  • 当我尝试您在答案中提供的映射时,我遇到了一个异常org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property: country。这是什么原因?
  • 必须指定两个方向。 IE。 country.pm = pm; pm.country = country;。在创作过程中,这是必须的。这将解决该异常
【解决方案2】:

问题在于您的 xml 映射和 Java 代码之间的关系。

如果你指定

  <one-to-one class="pojo.PM" name="name_pm" />

您的Country POJO 中需要有一个名为“name_pm”的字段。

你没有这样的字段。

如果您的 Country 类有一个对应 PM 对象的字段,则应在此处使用该字段的名称。

如果两个类都没有对另一个类的引用,则需要添加一个。

我可能会对您的代码执行的操作是向国家/地区添加一个字段并在映射中使用其名称。

public class Country {
    private int c_id;
    private String name_c;
    private PM c_pm;

    public int getC_id() {
        return c_id;
    }

    public void setC_id(int c_id) {
        this.c_id = c_id;
    }

    public String getName_c() {
        return name_c;
    }

    public void setName_c(String name_c) {
        this.name_c = name_c;
    }

    public PM getC_pm() {
        return c_pm;
    }

    public void setC_pm(PM c_PM) {
        this.c_pm = c_pm;
    }

}

映射:

<class name="pojo.Country" table="country">
      <id name="c_id">
          <generator class="increment" />
      </id>
      <property name="name_c" />
      <one-to-one class="pojo.PM" name="c_pm" />
</class>

免责声明:

我还没有测试过这些,我不确定应该如何使用共享主键来完成映射。如果其他人想提供一个经过测试的版本,我会很高兴地支持另一个答案,或者让这个答案变成“社区 wiki”。

【讨论】:

  • 我不明白,除了我需要name_pm 来消除异常。能否请您解释一下,one-to-one 映射是如何完成的
  • 这可能是一个愚蠢的问题..但实际上,我如何测试/知道它是否是 one-to-one 映射?
猜你喜欢
  • 2017-11-26
  • 2020-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-20
  • 2022-08-10
  • 1970-01-01
  • 2011-08-31
相关资源
最近更新 更多