-->
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.  [ 9 posts ] 
Author Message
 Post subject: A bidirectional many-to-one association with read-only cache
PostPosted: Mon Nov 28, 2005 2:33 pm 
Newbie

Joined: Mon Nov 28, 2005 11:01 am
Posts: 11
Is it the case that a bidirectional many-to-one association (without a join table) cannot work with read-only cache???

We have the following mapping:

<class name="Solution">
<id name="id" column="ID">
<generator class="native"/>
</id>
<bag name="grades" table="GRADE" inverse="true" cascade="all-delete-orphan" lazy="false">
<key column="SOLUTION_ID"/>
<one-to-many class="Grade"/>
</bag>
</class>

<class name="Grade">
<id name="id" column="ID">
<generator class="native"/>
</id>
<many-to-one name="solution" class="Solution"
column="SOLUTION_ID"
not-null="true" lazy="false"/>
</class>

and every time we insert a new grade into solution, Hibernate generates the following SQL:

Hibernate: insert into GRADE (VALUE, SOLUTION_ID) values (?, ?)
Hibernate: update SOLUTION set STUDENT_ID=?, ASSIGNMENT_ID=?, where ID=?
Hibernate: update GRADE set VALUE=?, SOLUTION_ID=?, where ID=?
Hibernate: update GRADE set VALUE=?, SOLUTION_ID=?, where ID=?
Hibernate: update GRADE set VALUE=?, SOLUTION_ID=?, where ID=?
Hibernate: update GRADE set VALUE=?, SOLUTION_ID=?, where ID=?

Obviously this doesn't work with read-only cache since the old grades are updated by Hibernate every times new grade is created.

Should we use one-to-many with join table to allow read only caching?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 28, 2005 2:51 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
You should always finish initializing an object before calling save() or persist(), or you will see this kind of inefficient SQL.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Nov 28, 2005 2:57 pm 
Newbie

Joined: Mon Nov 28, 2005 11:01 am
Posts: 11
Can you elaborate, please?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 01, 2005 12:36 am 
Beginner
Beginner

Joined: Sat Oct 29, 2005 2:05 am
Posts: 21
Location: Kansas City, KS
>>You should always finish initializing an object before calling save() or persist(), or you will see this kind of inefficient SQL.

>Can you elaborate, please?

"I am thinking of a number between 1 and 10..." I think he is trying to say that you're continuing to change your objects somehow before you commit. One of the little surprises of Hibernate that I was working with today is that it likes to double-check your objects to see if they changed between the save and the commit. So if you:

1) Call save() on your objects.
2) Make some kind of change to your objects AFTER calling save() on them (any properties changing values).
3) Commit your transaction.

The commit causes a flush. The flush decides to go back through all your saved objects and check to see if they have become dirty. (Code stepping aside: If hibernate can't tell if your objects are dirty, it tries to find out if they're really dirty. If it can't tell if your objects are really dirty, it tries to find out if they're really, really dirty. Ok, I exaggerate, but only a little.) If any of these saved objects are dirty, hibernate will perform an update on them.

So perhaps you are somehow changing your objects between the save and the commit.

IMHO its unfortunate that hibernate does this extra check during flush as (1) it is counter-intuitive (wouldn't you expect the dbase to be consistent with the data when you saved it rather than with the data at commit time?), and (2) it hurts performance (if I didn't change my objects then its a waste of time, and its generally a bad idea to be changing them during a transaction), but it did cause me to catch a bug in my own code so c'est la guerre.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Dec 01, 2005 9:13 am 
Newbie

Joined: Mon Nov 28, 2005 11:01 am
Posts: 11
Thanks for a long reply. I doubt we change our objects in this case but I will check.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 03, 2005 10:19 am 
Newbie

Joined: Mon Nov 28, 2005 11:01 am
Posts: 11
All fields in Grade objects are initialized in its constructor and nothing gets changed in Grade object after it's been created.

The question still remains. Why do we see updates issued for the previously created Grade objects?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 03, 2005 10:28 am 
Hibernate Team
Hibernate Team

Joined: Mon Aug 25, 2003 9:11 pm
Posts: 4592
Location: Switzerland
Quote:
IMHO its unfortunate that hibernate does this extra check during flush as (1)


Blah. How else could an identifier be returned from save(), if not from an INSERT? Obviously you need an update if anything else was modified until flush.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 05, 2005 1:37 am 
Newbie

Joined: Mon Nov 28, 2005 11:01 am
Posts: 11
OK. I've finally found a problem. In order for "read-only" cache to work, mutable="false" has to be specified in the class mapping, which will give a hint to Hibernate not to update already created entities. Simple. Has nothing to do with "finish initializing".

Unfortuntaly none of the suggestions above pointed me in this direction.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 05, 2005 10:24 am 
Beginner
Beginner

Joined: Sat Oct 29, 2005 2:05 am
Posts: 21
Location: Kansas City, KS
>>IMHO its unfortunate that hibernate does this extra check during flush as (1)

>Blah. How else could an identifier be returned from save(), if not from an INSERT?

Phooie to you too. I'm using generator="assigned". Hibernate already has the identifier when save() is called.

>Obviously you need an update if anything else was modified until flush.

Given your design decision to make flush time the "snapshot of truth" rather than save time, obviously yes. I was commenting on your design decision, not the steps you have to take to fulfill it.


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