aspose file tools*
The moose likes Object Relational Mapping and the fly likes Hibernate entity referencing itself by foreign key Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "Hibernate entity referencing itself by foreign key" Watch "Hibernate entity referencing itself by foreign key" New topic
Author

Hibernate entity referencing itself by foreign key

Kjeld Sigtermans
Ranch Hand

Joined: Aug 10, 2006
Posts: 125
Hi,

Let's say I have a table called Entity having a database managed identity column 'id'. It also has another column called 'parentId' having a foreign key constraint to 'its own' Entity.id. This way I'd like to create a parent/child relationship between Entity rows.

I have generated a class Entity that represents the Entity table. The FK reference is represented by Entity.setEntity(Entity p) where p is the parent.
When creating a new child entity Entity c = new Entity() I want to have c be its own parent so I set c.setEntity(c).

When trying to persist c, Hibernate complains: org.hibernate.PropertyValueException: not-null property references a null or transient value.
It is obvious the parent I try to set is not yet persisted (because it is c) and therefore it has no id, but I was hoping Hibernate would be able to deal with this in some smart way, maybe by temporarily turning off auto identity on the id column or nullability on the parentId column.

Of course I can remove the FK constraint which creates Entity.setParentId(int) instead of Entity.setEntity(Entity), or probably temporarily turn off the column properties myself. But is there a better way to achieve this goal?

Thanks,
Kjeld


Kjeld Sigtermans - SCJP 1.4 - SCWCD 1.4
Victor Dolirio
Ranch Hand

Joined: Aug 21, 2008
Posts: 57
You can do something like the following code snippet:



I hope to help.

[]s


If happen something bad in you life, don't ask God why it happened. Ask for what.
SCJP 5 (80%) - SCWCD 5 (91%) - SCBCD & SCJD coming soon...
Kjeld Sigtermans
Ranch Hand

Joined: Aug 10, 2006
Posts: 125
Thank you Victor but I already have (generated) Entity classes and mappings and I explicitly use native id generation. I don't see how GenerationType.AUTO will do the trick? The problem isn't so much how to set up the class, but I was hoping Hibernate was able to deal with not-yet-persisted entities that refer to themselves by property.
Meanwhile I have made the parentId column nullable. First I persist all entities with parent = null, then I assign the correct parent to each entity and I persist them again. (saveOrUpdate). It is a two phase process and I don't like the concession of making the column nullable, but this does the trick.

Cheers!
Victor Dolirio
Ranch Hand

Joined: Aug 21, 2008
Posts: 57
My apologies, I confess that I don't have undertood correctly your question, but now, with a better read I've got a better understand. IMO, isn't it is a paradoxical concept?? How could one element it self be your own parent? This is worst than "Which came first, the chicken or the egg?". But regardless of my humble opinion, I think that you can accomplish this in two steps: first, saving the entity without parent (to have the hibernate make the identity of the entity) and then update this entity supplying the parent entity to it self. I don't know if that is possible to do it in a single step.

For sake of curiosity, which is the reason that towards you to have a element being a parent to it self?

best regards.
John Bengler
Ranch Hand

Joined: Feb 12, 2009
Posts: 133
Hi Kjeld,

if you use a two step operation,why don't you first persist the "master Entity" and then the one which holds alink to the master entity?

But I understand your problem and think it should workin one persist operation...


John
John Bengler
Ranch Hand

Joined: Feb 12, 2009
Posts: 133
Hi again,

thinking a second time about your problemI think it is clear that you have to define the foreign key column nullable..

Beacause either you build a huge "ring" of Entity entries or you will have at least one entry without a parent...

Or is this the reason why you want to have one entry to be its own parent?

Sorry, I think I just recognized that your problem occurs when your using such a self-reference...


But I still think it should be possible for Hibernate to handle this correct...


John
Kjeld Sigtermans
Ranch Hand

Joined: Aug 10, 2006
Posts: 125
Victor, John, thanks for your thoughts about this.
The reason I want an entity to be able to refer to itself is basically because it is a business requirement, and I must say I've seen it before. For example, in an insurance context, think of a person A who is responsible for the payment behaviour of others, B and C. He (or she) would be his/her own 'parent', as well as the 'parent' the 'children' refer to. I.o.w. A being responsible for A, B and C. Maybe the word 'parent' is a little confusing in this context.
Yes, I have now made entity.parentId nullable, but I don't want this (BReq says everybody must have a 'parent' and now I have broken this req to be able to solve my problem). Plus I want to make sure technically that a 'parent' can never be omitted.
Also it should be feasible to store the entity in one go, not two-step, but I'm not sure if it's possible using Hibernate either.
Thanks!
Victor Dolirio
Ranch Hand

Joined: Aug 21, 2008
Posts: 57
Kjeld, IMO hibernate by itself ain't the problem. Think in your dbms side: is it possible to insert a new record this way without violate the FK constraint? Maybe is possible if your dbms use sequences, you can get the sequence before insertion and set up both field of you bean: id and 'parent' reference. Just map your bean to have indetity controled by you and you can write a interceptor to get next value from sequence and fill the fields. Its just a suggestion.

hope be helpfull...
Kjeld Sigtermans
Ranch Hand

Joined: Aug 10, 2006
Posts: 125
Yes you are right, Hibernate is not the problem, the problem is as fundamental as the data design. However, I was hoping Hibernate would provide a little trick to be able to deal with this. Maybe by quickly make the column nullable, insert the entity, update it with its parent, and change the column back to not-nullable. Oh well, maybe one can't expect Hibernate to do magical stuff on such an underlying design.
For now I have accepted the nullable column and two-phase persisting of Entity and I moved on.
John Bengler
Ranch Hand

Joined: Feb 12, 2009
Posts: 133
Victor Dolirio wrote: Maybe is possible if your dbms use sequences


I'm using an Oracle database and when you enable SQL Output you can see that for generated Ids Hibernate first selects the next value from the mapped sequence and performs the insertin a second step - so I don't see a problem why Hibernate should not be able to use this selected value for the primary key and for the foreign key..

But of course I don't know what kind of database Kjeld uses and how Hibernate handles the genertion of keys for this..
Kjeld Sigtermans
Ranch Hand

Joined: Aug 10, 2006
Posts: 125
Interesting. Well I use SQL Server 2005 and I chose 'native' generation of ids, so SQL Server generates the id.
Cheers K
Lalit Narayan Mishra
Greenhorn

Joined: May 14, 2007
Posts: 4
Found a nice book on Spring & Hibernate. Have a look at this blog...

http://amritendude.blogspot.in/2014/06/new-book-on-spring-4-and-hibernate-4.html
 
 
subject: Hibernate entity referencing itself by foreign key