-->
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.  [ 8 posts ] 
Author Message
 Post subject: Hibernate and database constraints
PostPosted: Wed Apr 07, 2004 10:59 am 
Beginner
Beginner

Joined: Wed Sep 03, 2003 9:31 am
Posts: 26
Hi.

I'm pretty sure I'm doing something wrong here but I couldn't figure it out until this point. I'm using Hibernate 2.1.2 on PostgreSQL 7.4.1.

I have something like a tree structure in the following table:

create table entity (
id integer not null,
name varchar(40) not null,
parent_id integer,
primary key id
);
alter table entity add constraint entity_entity_fk foreign key (parent_id) references entity;


This will restrict deletion on "entities" that have children, right?

In the mapping file, I have the following declarations:

<many-to-one name="parent" class="eg.Entity" column="parent_id"
insert="false" update="false" outer-join="false"/>
<set name="children" lazy="true" table="entity">
<key column="parent_id"/>
<one-to-many class="eg.Entity"/>
</set>


The class is fine, mapping is fine, table is fine. It works fine except for a small problem:
when I try to delete an entity that have children, I was waiting a JDBCException, because of
the constraint I created in database, but it doesn't occurs
.

Instead, Hibernate sets all children's parent_id to null and deletes the parent, so there's
no referential integrity violation. That's my problem, because I can't delete an entity that have
children in my application.

I know I can check in my code if an entity has children before trying to delete it, but I want to
use database referential integrity in order to avoid unecessary calls to the database.

What am I doing wrong here? Any alternatives?

iran


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 07, 2004 11:26 am 
Regular
Regular

Joined: Mon Sep 29, 2003 9:39 am
Posts: 67
try inverse="true" cascade="all-delete-orphan"
in your collection

not responsible for missing data!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 07, 2004 3:40 pm 
Beginner
Beginner

Joined: Wed Sep 03, 2003 9:31 am
Posts: 26
Thanks for the quick reply.

Unfortunately it didn't work.

Hibernate still keep setting all child's parent_id fields to null before delete the parent.

I'm looking for a way to avoid this behaviour, if such way does exists, of course.

Any other sugestions?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Apr 07, 2004 5:20 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
cascade="none" say to not touch this association during cascades, so that will do what you specify here.

cascade="all-delete-orphan" should work, by actually deleting the children instead of updating their FKs to null. Do you have both sides of the association mapped?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 08, 2004 8:05 am 
Beginner
Beginner

Joined: Wed Sep 03, 2003 9:31 am
Posts: 26
Yes, I have both sides mapped, since they are the same class.

Here is my complete mapping:

Code:
<hibernate-mapping>
   <class name="eg.Entity" table="entity">
      <id name="id" column="id" length="30" type="string">
         <generator class="assigned"/>
      </id>
      <property name="name" column="name" type="string" length="40" not-null="true"/>
      <property name="parentId" column="parent_id" type="string" length="30"/>
      <many-to-one name="parent" class="eg.Entity" column="parent_id" insert="false" update="false"/>
      <set name="children" lazy="true" order-by="name" table="entity">
         <key column="parent_id"/>
         <one-to-many class="eg.Entity"/>
      </set>
   </class>
</hibernate-mapping>


Is this kind of mapping nonsense?

My "entity" can have a "parent entity" (or no parent) of type eg.Entity. In addition it can have a set of "child entities" that are of type eg.Entity too. Kind of a circular reference.

As I wrote before, I have a constraint in my database that prevents deletion on entities that have children, better saying, prevents deletion on entities whose ids are used by other entities in parent_id.

It works fine, but Hibernate is setting entity.parent_id to null on entities that have parent_id equals to the entity's id I want to delete, and it is done before perform deletion. Thats the behaviour I would like to avoid, because I wanna catch the JDBCException generated from the database by my constraint.

Is that possible?

Thanx.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 08, 2004 8:25 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Quote:
Is this kind of mapping nonsense?


Nope, I use the same exact pattern in some of my apps. Its called the "Composite Pattern". Check out http://hibernate.org/86.html for details on implementing this in Hibernate mappings. Pay specific attention to the "inverse" and "cascade" values...


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 08, 2004 8:53 am 
Beginner
Beginner

Joined: Wed Sep 03, 2003 9:31 am
Posts: 26
Yeah!!! It worked Steve.

Thanks a lot.

However I didn't understand the effect of inverse="true" yet. But I will reread the documentation more carefully.

Thanks again.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Apr 08, 2004 12:50 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Check out http://hibernate.org/155.html. Pretty thorough dicussion of the implications of inverse values in various scenarios.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 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.