-->
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.  [ 5 posts ] 
Author Message
 Post subject: Why should it care?
PostPosted: Fri Jul 09, 2004 3:19 pm 
Newbie

Joined: Fri Jul 09, 2004 3:01 pm
Posts: 7
We've been using Hibernate for about 5 months now, and we've found what I think are a pair of bugs.

I have an object A which has a many-to-one mapping to object B, which has a many-to-one mapping to object C. The many-to-one mappings are "cascade=none".

Problem #1:
In some circumstances, when I go to persist object A, it will also persist object C. I've debugged through hibernate, and for reasons I'll dicsuss below, it thinks C is "dirtY" and so its doing an update. But given the cascade=none, why does it CARE if it's dirty?

Problem #2:
Object C has a number components (DayRange), each of which have two components (Day) each of which contains a java.util.Date. It's possible for an empty DayRange to exist, which will be store to the database as NULL, NULL, for the two columns it is ultimately mapped to. The problem is that on the second pass through "flush()", Hibernate seems to think it's dirty because we have a DayRange object which is not == null, but contains two nulls. This doesn't seem correct to me.

Comments?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 09, 2004 11:55 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Quote:
But given the cascade=none, why does it CARE if it's dirty

Because cascades only pertain to "relation management". Once an entity is loaded (as your C instance must be), the Hibernate Session tracks the entity for any changes made to it that need to get flushed.

Quote:
Problem #2:
Object C has a number components (DayRange), each of which have two components (Day) each of which contains a java.util.Date. It's possible for an empty DayRange to exist, which will be store to the database as NULL, NULL, for the two columns it is ultimately mapped to. The problem is that on the second pass through "flush()", Hibernate seems to think it's dirty because we have a DayRange object which is not == null, but contains two nulls. This doesn't seem correct to me.

During load, when Hibernate encounters a component for which all the columns spanned are null it considers that component in its entirety as being null and assigns the mapped property the value of null. At some point, I am guessing your code sets the reference to be a new DayRange instance (with both properties null or whatever, doesn't matter). During flush, Hibernate no longer finds the same value in the property that it placed there during load, thus it considers it dirty. This is totally expected and correct.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 10, 2004 7:08 am 
Newbie

Joined: Fri Jul 09, 2004 3:01 pm
Posts: 7
steve wrote:
Quote:
But given the cascade=none, why does it CARE if it's dirty

Because cascades only pertain to "relation management". Once an entity is loaded (as your C instance must be), the Hibernate Session tracks the entity for any changes made to it that need to get flushed.


Is there no way to control this (short of breaking the A-B relatinoship)? A is a frequently changing object that needs to be persisted a lot. B is the start of an object tree that contains many objects that are not changing. We'd like to optimze the amount of work hibernate is doing when A is persisted.

steve wrote:
Quote:
Problem #2:
Object C has a number components (DayRange), each of which have two components (Day) each of which contains a java.util.Date. It's possible for an empty DayRange to exist, which will be store to the database as NULL, NULL, for the two columns it is ultimately mapped to. The problem is that on the second pass through "flush()", Hibernate seems to think it's dirty because we have a DayRange object which is not == null, but contains two nulls. This doesn't seem correct to me.

During load, when Hibernate encounters a component for which all the columns spanned are null it considers that component in its entirety as being null and assigns the mapped property the value of null. At some point, I am guessing your code sets the reference to be a new DayRange instance (with both properties null or whatever, doesn't matter). During flush, Hibernate no longer finds the same value in the property that it placed there during load, thus it considers it dirty. This is totally expected and correct.


We've managed to work around this, but it makes our code overly complex. Wouldn't it be reasonable to have HIbernate always create components and if they contain NULL in their fields, so what, rather than equating several "equalting all nulls in a component is the same as a null component"? At least as a component option?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 14, 2004 1:35 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 3:00 pm
Posts: 1816
Location: Austin, TX
Quote:
Is there no way to control this (short of breaking the A-B relatinoship)? A is a frequently changing object that needs to be persisted a lot. B is the start of an object tree that contains many objects that are not changing. We'd like to optimze the amount of work hibernate is doing when A is persisted.

Not sure what your asking here. Control what? Control whether Hibernate performs dirty checking on loaded entities? That doesn't make much sense. I mean at that point it wouldn't even know that A changed!


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 14, 2004 6:21 am 
Newbie

Joined: Fri Jul 09, 2004 3:01 pm
Posts: 7
steve wrote:
Quote:
Is there no way to control this (short of breaking the A-B relatinoship)? A is a frequently changing object that needs to be persisted a lot. B is the start of an object tree that contains many objects that are not changing. We'd like to optimze the amount of work hibernate is doing when A is persisted.

Not sure what your asking here. Control what? Control whether Hibernate performs dirty checking on loaded entities? That doesn't make much sense. I mean at that point it wouldn't even know that A changed!


What I meant was to control how far down the object tree hibernate looks when objects are being saved.

Maybe we're just using Hibernate incorrectly. We've mapped all of our objects to the database in a what I think is a a fairly straight forward manner. There are a few places where we do NOT map the actual object relationship for a <many-to-one> relationship but instead map the ID. We do this, because we find it "very handy" that if I load object J, it loads all the things it needs (K, L, M, N ). And, in some cases, if I store a J object I would expect it save K, L, M and N. But in others I might store P, and know that no other objects (Q, R) should be persisted. Saving P means saving P, not everything P is tied to. While I understand that Hibernate will look at the objects and decided they haven't changed and NOT save them, I'm concerned about the time it takes to do this, and the amount of RAM used to cache objects for this purpose.

Do I have such a radically different view of what a persistence layer should do?


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