-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: error: "foreign key contraint fails" when saving
PostPosted: Tue Jan 17, 2006 5:41 pm 
Newbie

Joined: Tue Jan 17, 2006 5:18 pm
Posts: 4
Hi,

I'm learning Hibernate and I keep getting the same error messages when saving a object. I've searched the forum and read the manual, but can't figure this one out. Please help.

I've got 2 Tables: Parent and Child:

Code:
CREATE TABLE `parent` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(20) default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

CREATE TABLE `child` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(30) default NULL,
  `parent_id` int(11) NOT NULL default '0',
  PRIMARY KEY  (`id`),
  KEY `parent_id` (`parent_id`),
  CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;



Here are my Mapping Files for:
Parent:
Code:
<hibernate-mapping>

   <class name="entities.Parent" table="parent" >
      
       <id name="id" column="id" unsaved-value="-1" type="long">
           <generator class="native"/>
       </id>
      
       <property name="name" />
   
        <set name="children" inverse="true" cascade="all">
          <key column="parent_id" not-null="true" />
          <one-to-many class="entities.Child"  />
        </set>
   
   </class>

</hibernate-mapping>


and Child:
Code:
<hibernate-mapping>

   <class name="entities.Child" table="child">
    
       <id name="id" column="id" unsaved-value="-1" type="long">
           <generator class="native"/>
       </id>
      
       <property name="name" /> 
      
       <property name="parent_id" not-null="true" />
   
   </class>

</hibernate-mapping>


When I load a Parent all works fine, and hibernate populates all the Child Objects associated with the Parent, and adds them to the HashSet.

But when I try to create a new Parent and add new Children to the Parent, I get the following error:

Code:
org.hibernate.exception.ConstraintViolationException: could not insert: [entities.Child]

and...

Caused by: java.sql.SQLException: Cannot add or update a child row: a foreign key constraint fails


Here's my Java Code for the parent and child classes:
Code:
package entities;

public class Child {
   private String name = null;
   private long id = -1;
   private long parent_id= -1;

   public long getParent_id() {
      return parent_id;
   }
   public void setParent_id(long parent_id) {
      this.parent_id = parent_id;
   }
   public long getId() {
      return id;
   }
   public void setId(long id) {
      this.id = id;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
}

package entities;

import java.util.Set;

public class Parent {

   private String name = null;
   private long id = -1;
   private Set children = null;
   

   public Set getChildren() {
      return children;
   }

   public void setChildren(Set children) {
      this.children = children;
   }

   public long getId() {
      return id;
   }

   public void setId(long id) {
      this.id = id;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

}




this is what I do when I try to create and save a new Parent with new Children:
Code:
      Session session = SessionManager.getSessionFactory().getCurrentSession();
      session.beginTransaction();

      Parent p= new Parent();
      p.setName("mom");
      
      Child c = new Child();
      c.setName("kid1");
      
      p.setChildren(new HashSet());
      p.getChildren().add(c);

      session.save(p);
      session.getTransaction().commit();


Apparently to me, Hibernate doesn't know the Parents id at the time of saving and therefore cant set the foreign key of the Parent_id in the Child table. But how to I tell Hibernate that it should update this foreign key?
This problem has been haunting me for days now, and I cant solve it on my own. Maybe someones got some helpful hints on how to solve this problem.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 18, 2006 5:15 am 
Regular
Regular

Joined: Tue Jan 03, 2006 9:52 am
Posts: 52
Location: Zurich
I noticed two problems:

1) You do not have to deal with the parent_id as a field in your child class. The relationship is handled by hibernate. Remove the parent_id and related getter/setter from your Child.java and also from your xml definition for the Child: <property name="parent_id" ...

2) remove inverse=true from the set definition for Parent
<set name="children" cascade="all" >

Have also a look at:
http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#assoc-unidirectional-12m
where you can find one-to-many association example(s).

Hope this helps ..
Urs


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 18, 2006 2:31 pm 
Newbie

Joined: Tue Jan 17, 2006 5:18 pm
Posts: 4
thanks for the fast reply.

I took the steps you suggested and removed the inverse=true in the set mapping in the parent.hbm.xml and removed tho parent_id (FK) mapping in the child.hbm.xml. I also deleted the the parent_id from the list of properties in Child.java.

However I still get the same error.

What am I doing wrong? (or not doing right?)

--- carco


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 18, 2006 6:55 pm 
Regular
Regular

Joined: Tue Jan 03, 2006 9:52 am
Posts: 52
Location: Zurich
I just tried your example with MySQL which created the following tables:
Code:
create table child (id bigint not null auto_increment, name varchar(255), parent_id bigint not null, primary key (id))
create table parent (id bigint not null auto_increment, name varchar(255), primary key (id))
alter table child add index FK5A3F51CB021726D (parent_id), add constraint FK5A3F51CB021726D foreign key (parent_id) references parent (id)

and the data gets inserted correctly:
Code:
Hibernate: insert into parent (name) values (?)
Hibernate: insert into child (name, parent_id) values (?, ?)
Hibernate: update child set parent_id=? where id=?

with the following insertion code:
Code:
      Session session = HibernateUtil.getSessionFactory().openSession();
      
      Transaction tx = session.beginTransaction();
      Parent p= new Parent();
      p.setName("mom2");
      
      Child c = new Child();
      c.setName("kid2");
      
      p.setChildren(new HashSet());
      p.getChildren().add(c);
      
      session.save(p);
      tx.commit();
      session.close();


I only did the changes as mentioned in my previous post.
Do you want to have a go with MySQL?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 19, 2006 2:43 pm 
Newbie

Joined: Tue Jan 17, 2006 5:18 pm
Posts: 4
I tried your sql create code, but I noticed that you didn't use the InnoDB Storage engine. Using your code all my inserts i.e. parent and child etc are inserted without any exceptions from hibernate or MySQL, but the foreign key in child table doesn't get updated.

I'm also missing the last Hibernate update line that you posted:
Code:
Hibernate: update child set parent_id=? where id=?


all I get is:
Code:
Hibernate: insert into parent (name, id) values (?, null)
Hibernate: insert into child (name, id) values (?, null)


What version of MySQL did you use? and what did you use to generate your SQL create code?


Top
 Profile  
 
 Post subject: Cannot add or update a child row: a foreign key constraint f
PostPosted: Wed Nov 29, 2006 6:30 pm 
Newbie

Joined: Wed Nov 29, 2006 6:21 pm
Posts: 1
Location: eden prairie
well the Mapping file of yours is as below for the primary key autoincrement

<id name="id" column="id" unsaved-value="-1" type="long">
<generator class="native"/>
</id>

and your code is

Parent p= new Parent();
p.setName("mom");

Child c = new Child();
c.setName("kid1");

p.setChildren(new HashSet());
p.getChildren().add(c);
>>

Now with generator == native cause the database to generate the key for you.
So following modification will make it work
>> modification >>
Parent p= new Parent();
p.setName("mom");

session.save(p);
session.flush();
session.refresh(p);

Child c = new Child();
c.setName("kid1");

p.setChildren(new HashSet());
p.getChildren().add(c);


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.