Hibernate:如果x.equals(y)重用相同的外键

时间:2013-07-08 16:18:52

标签: java hibernate

让我们举例说明这两个实体:

城市:

<class name="City" table="city">
    <id name="id" column="id"/>
    <property name="city_name" column="city_name"/>
    <property name="country_name" column="country_name"/>
</class>

人:

<class name="Person" table="person">
    <id name="id" column="id"/>
    <property name="name" column="name"/>    
    <many-to-one cascade="save-update" name="city" column="city_id" class="City"/>
</class>
如果City.equals()true相同,

city_name实施将返回coutry_name

如果我在一次会话中保存了两个Person

Person person1 = new Person("Peter");
Person person2 = new Person("John");

City city1 = new City("Paris", "France");
City city2 = new City("Paris", "France");

person1.setCity(city1);    
person2.setCity(city2);

session.save(person1);
session.save(person2);

Hibernate会产生以下记录:

city:

| id |  name  | city_id |
-------------------------
| 1  |  Peter |    1    |
| 2  |  John  |    2    |

person:

| id |  city_name | country_name |
----------------------------------
| 1  |    Paris   |    France    |
| 2  |    Paris   |    France    |

但我可以告诉Hibernate在city_id时在person中重复使用相同的cityX.equals(cityY)吗?

编辑:

我应该澄清city1city2不能是同一个实例。为了简洁起见,我无法描述我所面临的全部问题。在实际情况下,表可以包含重复元素,我只是想通过分组一些特定元素来节省一些空间。谢谢!

5 个答案:

答案 0 :(得分:0)

创建单个City对象并将同一对象分配给两个实体。您将首先保留此City对象,以便与现有对象建立关联。

这里有一个问题。

由于您为两个Person实例分配了相同的值,因此不应该实际执行级联,但如果在删除{{City之后它将成为孤儿,则应删除Person 1}}。

在您的特定情况下,由于您正在与城市打交道,现有的包含多个城市的表格可能是一个很好的选择,允许您将预先存在的城市分配给新人,以防您想要创建第三个{删除 Peter John 之后{1}} {1}}。

答案 1 :(得分:0)

试试这个:

Person person1 = new Person("Peter");
Person person2 = new Person("John");

City city1 = new City("Paris", "France");

person1.setCity(city1);    
session.save(person1);
person2.setCity(city1);
session.save(person2);

答案 2 :(得分:0)

也许你有一些不同的想法,但这就是我将如何处理这个问题:

  1. 首先,我会在city表(city_name,country_name)的以下字段中放置一个唯一索引
  2. 当然我会让Hibernate知道这个独特的索引
  3. 而不是City city1 = new City("Paris", "France")我会

    //use session.createQuery or createCriteria here  
    City city = findByNameAndCountry("Paris", "France")   
    if (city == null){  
        city = new City("Paris", "France");  
        session.save(city)  
    }  
    

答案 3 :(得分:0)

最好将city_name和country_name作为主键。因此,在这种情况下,您无法向数据库插入相同的值。 像..

City city1 = new City("Paris", "France");
City city2 = new City("Paris", "France");

因此,您必须拥有一个具有相同值的城市对象。然后它不会重复。

不要忘记根据equals()方法覆盖hashCode()。

答案 4 :(得分:0)

城市是一个实体,其平等取决于其身份。只要您将两个不同的城市与两个人联系起来,您就会得到两个人。

为了避免这种情况,你必须只创建一个城市对象(如果它不存在),否则使用已经存在的城市对象。

还有一个问题:如果同一个国家的两个城市碰巧有相同的名字,会发生什么?他们不会是同一个城市,但会有相同的身份。