views:

188

answers:

2

I have two classes, ServiceType and ServiceRequest. Every ServiceRequest must specify what kind of ServiceType it is. All ServiceType's are predefined in the database, and ServiceRequest is created at runtime by the client.

Here are my .hbm files:

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

and

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

When I run this, I get

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

I think my problem is that when I create a new ServiceRequest object, ServiceType is one of its properties, and therefore when I'm saving ServiceRequest to the database, Hibernate attempts to insert the ServiceType object once again, and finds that it is already exists. If this is the case, how do I make it so that Hibernate points to the exists ServiceType instead of trying to insert it again?

The code throwing the error:

/* 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";
A: 

in the absence of the code that causes the exception, i'd say your problem is likely that you're trying to create a new ServiceType for each ServiceRequest whereas what you need to do is retrieve the existing ServiceType by id rather than adding a new one every time.

if this doesn't sound plausible, show your java code and i'll try and help further :)


further help : do your DAOs use the same hibernate session? entities loaded from one session and saved in another can cause problems unless you use merge instead of save.

oedo
I update my question to show the code. As you can see I'm requesting the ServiceType from the database, but then saving it again.
teehoo
and yes, I'm using the same session for each DAO.
teehoo
you could try merge() instead of save() anyway? or encapsulate the whole thing in a transaction? otherwise i'm out of ideas, sorry.
oedo
Nope, merge doesn't fix it :(. So Hibernate takes care of the situation where I'm saving an entity, that already exists in the database (ServiceRequest's property ServiceType in my case)?
teehoo
it SHOULDN'T do. actually one more thing to try, take out the cascade="all" on your many-to-one mapping, see if that helps?
oedo
A: 

Your SQL exception doesn't really seem to match the assumption that it's trying to create a ServiceType that already exists. Wouldn't you expect to see a unique constraint violation on the ServiceType table? First thing I would check on seeing this is, does the FK target in the database match the hibernate mapping? You can get things like this when your Entity for ServiceType is pointed to (BOB_DEV_SERVICE_TYPES) but the actual foreign key being enforced on the ServiceRequest goes to (TINA_TEST_SERVICE_TYPES)

Affe

related questions