一对一映射的概念。解释映射

时间:2013-06-22 12:57:55

标签: java hibernate java-ee hibernate-mapping

如何定义2个类之间的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>

但是这个有效的映射除了在运行时产生异常之外什么也没做。它说在name_pm类中找不到属性Country!但它是否在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;
    }

}

PM

    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;
    }

}

2 个答案:

答案 0 :(得分: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>

声明:

我还没有测试任何这个,我不确定应该如何使用共享主键完成映射。如果其他人感觉提供了经过测试的版本,我很乐意提出另一个答案,或者让这个回答“社区维基”。

答案 1 :(得分:2)

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

首先,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值。

因此,一个对象将扮演主人的角色,例如国家和第二个将根据它分配其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引用)可能更合适。这是完全不同的方法,但是......

请尝试看看这篇好文章: