Hibernate映射到已存在的对象

时间:2010-05-02 23:36:20

标签: hibernate mapping foreign-keys

我有两个类,ServiceType和ServiceRequest。每个ServiceRequest都必须指定它是什么类型的ServiceType。所有ServiceType都在数据库中预定义,ServiceRequest由客户端在运行时创建。

这是我的.hbm文件:

<hibernate-mapping>
  <class dynamic-insert="false" dynamic-update="false" mutable="true" name="xxx.model.entity.ServiceRequest" optimistic-lock="version" polymorphism="implicit" select-before-update="false">
    <id column="USER_ID" name="id">
      <generator class="native"/>
    </id>
    <property name="quantity">
        <column name="quantity" not-null="true"/>
    </property>
    <many-to-one cascade="all" class="xxx.model.entity.ServiceType" column="service_type" name="serviceType" not-null="false" unique="false"/>
  </class>
</hibernate-mapping>

<hibernate-mapping>
  <class dynamic-insert="false" dynamic-update="false" mutable="true" name="xxx.model.entity.ServiceType" optimistic-lock="version" polymorphism="implicit" select-before-update="false">
    <id column="USER_ID" name="id">
      <generator class="native"/>
    </id>
    <property name="description">
        <column name="description" not-null="false"/>
    </property>
    <property name="cost">
        <column name="cost" not-null="true"/>
    </property>
    <property name="enabled">
        <column name="enabled" not-null="true"/>
    </property>
  </class>
</hibernate-mapping>

当我运行时,我得到了

com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails

我认为我的问题是,当我创建一个新的ServiceRequest对象时,ServiceType是它的一个属性,因此当我将ServiceRequest保存到数据库时,Hibernate会再次尝试插入ServiceType对象,并发现它已经存在。如果是这种情况,我该怎么做才能让Hibernate指向存在的ServiceType而不是试图再次插入它?

抛出错误的代码:

/* Get existing Service Type from database */
ServiceType st = DAOFactory.getDAOFactory().getServiceTypeDAO().getServiceType(newServiceTypeName);

/* Set the ServiceType of the new Service Request*/
newServiceRequest.setServiceType(st);

/* Error occurs inside this function which simply calls
    session.beginTransaction();
    session.save(sr);
    session.getTransaction().commit();  */
DAOFactory.getDAOFactory().getServiceRequestDAO().saveData(newServiceRequest);
return "newRequestDone";

2 个答案:

答案 0 :(得分:0)

如果没有导致异常的代码,我会说你的问题很可能就是你要为每个ServiceType创建一个新的ServiceRequest,而你需要做的是通过id检索现有的ServiceType,而不是每次都添加一个新的。{/ p>

如果这看起来不合理,请显示您的java代码,我会尝试进一步提供帮助:)


进一步的帮助:你的DAO使用相同的hibernate会话吗?除非您使用merge而不是save,否则从一个会话加载并保存在另一个会话中的实体可能会导致问题。

答案 1 :(得分:0)

您的SQL异常似乎与它尝试创建已存在的ServiceType的假设不匹配。您不期望在ServiceType表上看到唯一的约束违规吗?我要检查的第一件事是,数据库中的FK目标是否与hibernate映射匹配?当指向您的Entity for ServiceType(BOB_DEV_SERVICE_TYPES)但在ServiceRequest上强制执行的实际外键进入(TINA_TEST_SERVICE_TYPES)时,您可以得到类似的内容