-->
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: Unnecessary update on parent when map is updated
PostPosted: Mon Dec 11, 2006 3:52 pm 
Newbie

Joined: Mon Dec 11, 2006 3:17 pm
Posts: 3
Hi all.

Here's one weird bit I am trying to solve. Hibernate seems to generate one unnecessary UPDATE statement on my UserSession mapping. The mapping and the update statement are below. The only thing that changes during transaction are the context properties (name/value pairs) but not the user nor user session. Yet hibernate updates the version of UserSession.

Since the whole update is part of a bigger transaction it took a bit to find where the extra update was coming from. Finally I replaced the contextProperties map in UserSession with a static map in a similar class to emulate the storage. Extra update was gone and that's how I figured it was this map causing it.

The schema looks like this:
USER(user_id,name,version)
(0,n)->
USER_SESSION(user_session_id,user_id,version)
(0,n)->
USER_CONTEXT_PROPERTIES(user_session_id,name,value)

User and UserSession are mapped into pojo-s, context properties are mapped through UserSession as a map.

Any help is appreciated. Thanks.
Dan


Hibernate version:
3.1

Mapping documents:
<hibernate-mapping package="com.....">
<class name="UserSession" table="USER_SESSION">
<id name="userSessionId" type="java.lang.Long" unsaved-value="null">
<column name="USER_SESSION_ID" precision="10" scale="0"/>
<generator class="sequence">
<param name="sequence">USER_SESSION_ID_SEQ</param>
</generator>
</id>

<version name="version" type="long" column="VERSION" />

<many-to-one name="user" class="User" fetch="join">
<column name="USER_ID" precision="10" scale="0" not-null="true" />
</many-to-one>

<map name="userContextProperties" table="USER_CONTEXT_PROPERTY" inverse="false" fetch="join">
<key column="USER_SESSION_ID"/>
<index column="NAME" type="string"/>
<element column="VALUE" type="string" not-null="true"/>
</map>

....

</class>
</hibernate-mapping>

Code between sessionFactory.openSession() and session.close():
The object is saved as part of a bigger transaction so I can't provide the whole trace.

Full stack trace of any exception that occurs:
No exception.

Name and version of the database you are using:
Oracle 9i

The generated SQL (show_sql=true):
Hibernate: update USER_SESSION set VERSION=?, USER_ID=? where USER_SESSION_ID=? and VERSION=?

Debug level Hibernate log excerpt:
-


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 11, 2006 4:00 pm 
Expert
Expert

Joined: Tue Jul 11, 2006 10:21 am
Posts: 457
Location: Columbus, Ohio
When you modify a collection in a one-to-many, the one side is (and should be) updated with a new version stamp. The version stamp will tell anyone that something has changed about this object (e.g. now it has 5 UserSessions instead of 4). I know it feels odd updating the parent in a parent-child association when the children change, but it does work for concurrency issues/optimistic locking.

Imagine two processes adding children and expecting N+1 children to be in the resulting collection.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 11, 2006 4:51 pm 
Newbie

Joined: Mon Dec 11, 2006 3:17 pm
Posts: 3
Thanks for the quick reply. I do agree with you there, especially in my case where children objects are just implied through the map, they don't even exist, so parent's version should be updated, period. Definitely. But.... my problem is a bit bigger than what I had explained.

At application runtime I am not catching any changes to context properties, except at the very beginning. I should have pointed that out clearly. My mistake. Context properties change only once at the login and then they don't. The transaction during which UserSession's version will get updated is initiated at another place... two relationships away... through UserSession -(o,n)-> UserStates <-(0,m)- UserGame. It is the UserGame that gets saved and starts the transaction.

So, I save the UserGame which will cascade the saves... obviously all the way down to UserContextProperties as the UserSession's version gets updated on that.... but context properties have not changed this time. And yet I get the update on UserSession. Again, if I emulate UserContextProperties through a static map no update on UserSession is issued.

I know I am explaining this in two posts, when I should have made maybe only one.... less misleading. Sorry about that.

Thanks.
Dan


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 11, 2006 5:19 pm 
Expert
Expert

Joined: Tue Jul 11, 2006 10:21 am
Posts: 457
Location: Columbus, Ohio
Too late in the day for me to wrap my head around the problem, I'll give it another go in the morning. Much love to Mondays. :P


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 11, 2006 5:45 pm 
Newbie

Joined: Mon Dec 11, 2006 3:17 pm
Posts: 3
Yeah I know, gotta "love" Mondays... especially after a weekend spent over in Quebec :)

Here's one more thing I just did that may help. I replaced the map of UserContextProperties with the set of real UserContextProperty(name, value) POJO-s in UserSession. Basically, this time I have UserContextProperty.hbm.xml mapping and UserContextProperty.java POJO class and the set of them in UserSession.
<set name="userContextProperties" ....>
</set>

You know, the more common situation where both sides are mapped and pojo-ed, your school book parent-children example. And guess what, that extra update is gone now. I mean, mapping them as a set of POJO(name,value) objects is awkward and it is not a preferred solution. Original <map.../> was a natural solution to this. But why do I get the extra update with the <map.../> and not with the <set.../> that requires you to code more (hbm, class) I don't know.

It almost looks like Hibernate is being "paranoid" about the map of context properties ... and updates the UserSession... well just because... to be on the safe side, I don't know. Seriously though, I can't explain it.

Thanks.
Dan


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.