如何防止Hibernate在多对一映射中创建重复项

时间:2011-08-03 03:37:22

标签: java hibernate

我有两个简单的对象;人与城市。一个城市可能有多个人,但一个人只有一个城市。我希望能够保存一个人并让Hibernate自动保存城市 - 只有当它是一个新城市时 - 城市应该是独一无二的。通过我的映射,我发现每次保存Person时,都会在数据库中插入一个新的City,无论它是否已存在。我确信这是相当直接的,但我是Hibernate的新手并且正在努力解决它。请注意,如果我在一个会话中保存一个城市的两个人 - 一切正常。这是跨会话的问题。我还在City类中创建了equals和hashcode方法,如下所示。

Person.hbm.xml

  <id name="id" type="long" column="id" >
   <generator class="native"/>
  </id>

  <property name="firstName">
   <column name="firstname" />
  </property>

 <many-to-one name="city" class="com.project.City" cascade="save-update">
  <column name="cityId" not-null="true" />
 </many-to-one>


City.hbm.xml

   <id name="id" type="long" column="id" >
   <generator class="native"/>
  </id>

  <property name="description" unique="true">
   <column name="description" />
  </property>


public class City implements java.io.Serializable {
    private Long id;
    private String description;

      // getters and setters

    public boolean equals(Object other) {
        if (this==other) return true;
        if ( !(other instanceof City) ) return false;
        final City that = (City) other;
        return this.description.equals( that.getDescription() );
    }   

    public int hashCode() {
        return description.hashCode();
    }    
}




    try {
      Transaction tx = session.beginTransaction();

      Criteria criteria = session.createCriteria(City.class);
      criteria.add(Restrictions.eq("description", city.getDescription()));
      criteria.setMaxResults(1);

      // Possible to use:
      // List<City> cities = criteria.list();
      // However, this generates warnings about unsafe casting.  If you use this then
      // set @SuppressWarnings("unchecked")
      List<City> cities = HibernateUtil.castList(City.class, criteria.list());

      if (cities.isEmpty())  {
          session.save(city);
        }
      else  {
          city = (City) cities.get(0);
        }
          session.flush();
          tx.commit();
            }
        catch (Exception e) {
          return null;
            }
      }
return city;

1 个答案:

答案 0 :(得分:1)

    if ( !(other instanceof Ward) ) return false;
    final Ward that = (Ward) other;

这不应该是城市而不是沃德吗?