Hi, I've run into a problem with hibernate relationships. It only appears to occur when using a 1-to-many, bi-directional relationship with *cascade*. Tried posting this question to the hibernate forum, but was bitterly disappointed by their attitude (admittedly they have a right to it, as they're not being payed). Would any of you veteran hibernate users happen to find the time to try it out ? If so, i'd be forever in your debt... ----------------------------------------- Problem in short: when using 1:M, bi-directional relationship with "cascade", hibernate saves the parent but fails to save children. I shall demonstrate for relationship "Department has several Employees". ----------------------------------------- The classes: ------------------------
----------------------------------------- The mapping (bi-di relashionship, with "inverse=true" and "cascade="all": ------------------------
------------------------ The problem: ------------------------ Department is saved to the DB, but child employees are not. According to the log, hibernate issues an sql "update" instead of "insert". Interesting notes: 1) Problem only occurs with "cascade". When removing the cascade, you need to explicitly save each employee, but at least it works. 2) Behaviour differs if you save the new department before adding employees, namely: session.save(dept); dept.addEmployee(emp); session.save(emp); Again, any help would be greatly appreciated.
Lasse Koskela
author
Sheriff
Joined: Jan 23, 2002
Posts: 11962
5
posted
0
Hi Sol, I noticed your display name features an initial for a last name, which goes against our naming policy. Would you mind expanding it into a full last name? You can do that via My Profile. Thanks.
If you are seeing updates instead of inserts it sounds like there might be a problem with the id of the object (i.e. Hibernate has a reference to an existing object, rather than a new one). You should be able to see what values Hibernate thinks its got with debug turned on. Check these. I suggest this because I notice you are overriding equals and hashCode - something I'm not strictly sure you need to do - what's your reasoning here?
Thanx for having a look. 1)The equals/hash are not necessary, I get the same behaviour when removing them. 2)Unsurprisingly, the log says "saveOrUpdate() previously saved instance with id: e1" , which is why it chooses to run an "update" rather than "insert" on those employees. 3)The fact those employees are marked as "already saved" appears to be somethow related to the fact it's been added to department (even though department itself was not saved yet). If you don't add them to department they get saved fine: dept = new Department("d1"); emp=new Employee("e1", 9000); // dept.addEmployee(emp); // If you rem this out, emp gets saved. session.save(dept); session.save(emp); Thanx again.
Sol Mayer-Orn
Ranch Hand
Joined: Nov 13, 2002
Posts: 310
posted
0
Thanx - your tip on the log & id's enabled me to send more focused info to the hibernate forum. Their reply indicates that the problem is with the "assigned" id. If I understand correctly (i could be wrong), they seem to assume that if an object has an id (different from 'null' or from the 'unsaved-value'), then it's an existing DB record. Which means if you manually assign the id before inserting, then hibernate would get confused. They suggested to add a "version" mapping, and it helped. Still, seems like an odd feature to me. I would have expected hibernate to rely on some flag, separate from the id value...
Thanx again
karl koch
Ranch Hand
Joined: May 25, 2001
Posts: 388
posted
0
hi
is there a reason you want to assign the ids by yourself ? if no, just let hibernate take care of them:
Thanx for relying. Assinged IDs are required since we're using a legacy system which relies on natural keys (e.g. people stored by social security number, equipment items stored by manufacturer-issued id's, etc).
Brendan Richards
Greenhorn
Joined: Jun 01, 2005
Posts: 3
posted
0
I've found an FAQ entry that has some good info on this topic: