Hibernate Books

All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: Foreign key constraint fails
PostPosted: Thu Apr 19, 2012 9:04 am 
Newbie

Joined: Mon Feb 13, 2012 4:59 am
Posts: 8
Hello Community,

I'm in trouble with my hibernate mapping.
The situation is, I have the Class "SimpleUser" and another Class "MapItemHib".
Every object of MapItemHib contains an object of SimpleUser (the owner of the Item), but a user can have many items.
So I have a many-to-one-relation, haven't I?

My mapping files look like this (snippets):

MapItemHib.hbm.xml
Code:
<many-to-one name="owner" class="test.SimpleUser"
        cascade="save-update" column="OWNER" />


and

SimpleUser.hbm.xml
Code:
<hibernate-mapping>
    <class name="test.SimpleUser" table="SIMPLEUSER">
        <id name="id" type="java.lang.Long">
            <column name="ID" />
            <generator class="native" />
        </id>
   ... weitere properties...

    </class>
</hibernate-mapping>


Now I want to create a new SimpleUser.
But I get this error:

Code:
ERROR: Cannot add or update a child row: a foreign key constraint fails (`test`.`simpleuser`, CONSTRAINT `FKC7A4E07D72CFDE7B` FOREIGN KEY (`ID`) REFERENCES `mapitemhib` (`ITEMID`))


This means, I cant create the user because there is no reference to an MapItemHib of this user.
How can I fix it? I want, that there can be users without any Items. Do you understand my problem?
(Sorry for the bad english, its not my first language).


Thanks for help!


Top
 Profile  
 
 Post subject: Re: Foreign key constraint fails
PostPosted: Fri Apr 20, 2012 11:55 am 
Newbie

Joined: Fri Apr 20, 2012 10:08 am
Posts: 2
Did you ever find an answer? I came to this forum to ask a very similar, perhaps identical question. Maybe somebody can help us both.

I think I have an error somewhere in either my code or my annotations. I am trying to persist a complex, compound object into a database. It is more complicated than this, but the essential part of my question is about an object with at least two levels of OneToMany relationships:

* an Advisory has zero or more Positions
* a Position has zero or more SeaContours

So basically

* object A has OneToMany with object B
* object B has OneToMany with object C

I have all this set up with bi-directional JPA annotations:

Code:
public class Advisory { ...
   @OneToMany(cascade = CascadeType.ALL, mappedBy = "advisory")
   public Collection<Position> getPositions() {
      return positions;
   }
}

public class Position { ...
   @ManyToOne(cascade = CascadeType.ALL)
   @JoinColumn(name = "advisory_id")
   public Advisory getAdvisory() {
      return advisory;
   }
   @OneToMany(cascade = CascadeType.ALL, mappedBy = "position")
   public Collection<SeaContour> getSeaContours() {
      return seaContours;
   }
}

public class SeaContour { ...
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="position_id")
   public Position getPosition() {
      return position;
   }
}


I make sure to set up the bi-directional relationship correctly. Each parent/child object relationship is set on both ends.

Finally, the MySQL database has three tables (advisory, position, sea_contour) and both 'position' and 'sea_contour' have foreign keys back to their parent tables, with not-null on that foreign key column, and a foreign key constraint.

When I try to call Hibernate to persist the object I get an error:

Code:
      EntityManager entityManager = getEntityManagerSingleton();
      EntityTransaction entityTransaction = entityManager.getTransaction();

      try {
         entityTransaction.begin();
         entityManager.merge(advisory);
         entityTransaction.commit();
      } catch (HibernateException e) { ...



Quote:
"Cannot add or update a child row: a foreign key constraint fails (`tropicalsystems_dev`.`position`, CONSTRAINT `fk_position_advisory1` FOREIGN KEY (`advisory_id`) REFERENCES `advisory` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION)"


Now, finally, if I (first set the foreign key to not null, and then) remove that fk_position_advisory1 constraint, suddenly the entire compound object is saved no problem. This is unexpected, because as far as I can tell, my A <-> B relationship is set up exactly the same as my B <-> C relationship, but I don't get the same error from my B <-> C relationship. The sea_contour table has a similar constraint for its foreign key to the position table. If both child tables have the same constraint to their parent tables, then I would expect to receive the same error for the other fk constraint.

I assume that I have done *something* different in my A-B and B-C relationships, but I can't figure out what it is. I am a bit of a Hibernate n00b. The other possibility is that a bug in Hibernate is causing it to write compound objects in the wrong way.

In my search for an answer I have:

* absolutely verified that my object sets up the bidirectional relationship correctly
* verified that all my object id types are Long, and my database id types are INT
* made sure all my relationships are Cascade=ALL in both directions

Many thanks!


Top
 Profile  
 
 Post subject: Re: Foreign key constraint fails
PostPosted: Fri Apr 20, 2012 12:44 pm 
Newbie

Joined: Fri Apr 20, 2012 10:08 am
Posts: 2
Success! I figured out my problem. I have been searching the tubes for more than a day looking for tips on what could be the problem, and I never found this tip, so I hope my explanation will help somebody out there.

My problem, it appears, is that my Advisory table was (mistakenly, unknowingly) set to type MyISAM instead of InnoDB. Based on my novice understanding, MyISAM does not support row-level locking and does not support transactions.

Therefore my guess is that Hibernate was forced to insert my compound object one bit at a time, instead of in one big transaction:

* first insert the Advisory
* then insert the Position in a separate transaction
* then go back and update the Position with the Advisory id. I saw this mentioned somewhere -- that Hibernate will do an insert-then-update when it could possibly do a single insert. I don't know why it does this, but I think it does.
* That first insert fails on the foreign key constraint because Hibernate doesn't set the advisory_id in that initial insert.

I changed my Advisory table to InnoDB and Hibernate correctly persisted my entire object. I sincerely hope this tip helps somebody someday.


Top
 Profile  
 
 Post subject: Re: Foreign key constraint fails
PostPosted: Tue Apr 24, 2012 6:37 am 
Newbie

Joined: Mon Feb 13, 2012 4:59 am
Posts: 8
shbrn8 wrote:
Success! I figured out my problem. I have been searching the tubes for more than a day looking for tips on what could be the problem, and I never found this tip, so I hope my explanation will help somebody out there.

My problem, it appears, is that my Advisory table was (mistakenly, unknowingly) set to type MyISAM instead of InnoDB. Based on my novice understanding, MyISAM does not support row-level locking and does not support transactions.

I changed my Advisory table to InnoDB and Hibernate correctly persisted my entire object. I sincerely hope this tip helps somebody someday.


All my tables are set to InnoDB, but it does not work :( And I dont want to save some complicated objects, just an instance of "SimpleUser".

The properties of SimpleUser are:

Code:
   private Long id;
   private String email;
   private String nick;
   private String name;
   private String forename;
   private String password;
   private UserUtil.UserRole role;


UserUtil is an enum.
My mapping file is this (snippet):
Code:
    <class name="test.SimpleUser" table="SIMPLEUSER">
        <id name="id" type="java.lang.Long">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="email" type="java.lang.String">
            <column name="EMAIL" />
        </property>
        <property name="nickname" type="java.lang.String" column="NICKNAME" />

        <property name="name" type="java.lang.String" column="NAME" />

        <property name="forename" type="java.lang.String" column="VORNAME"/>

        <property name="password" type="java.lang.String" column="PASSWORT" />
           
        <property name="role" column="ROLE">
            <type name="org.hibernate.type.EnumType">
                <param name="type">12</param>
                <param name="enumClass">test.UserUtil$UserRole</param>
            </type>
        </property>
    </class>



Is it right, that hibernate generates the ID of the object? In my save-method i create the object without an id, just like this:
Code:
SimpleUser newUser = new SimpleUser(email,
                  nickname, name, vorname, passwd, UserRole.USER);


I dont understand, why this object cannot be saved... :( The main problem is, hibernate has a problem, when an instance of SimpleUser doe not reference to a MipItemHib...


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 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.