-->
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.  [ 10 posts ] 
Author Message
 Post subject: Graph Cached After Save Inside Session
PostPosted: Fri Dec 02, 2005 11:23 am 
Newbie

Joined: Fri Nov 04, 2005 12:32 pm
Posts: 14
Location: Detroit, MI, USA
Hibernate version: 3.0.5

Mapping documents:

Code:
In Transaction:
        <many-to-one name="person" class="xxx.Person"
           cascade="refresh" outer-join="auto" lazy="true">
            ...
        </many-to-one>

  In Person:
        <set name="transactions" cascade="refresh" sort="unsorted"
           lazy="true">
           <cache usage="read-write" />
           <key>
                  ...
           </key>

           <one-to-many class="xxx.Transaction" />
        </set>


Code between sessionFactory.openSession() and session.close():

Code:
List num1 = transaction.getPerson().getTransactions();

session.saveOrUpdate(new Transaction());

List num2 = transaction.getPerson().getTransactions();



Full stack trace of any exception that occurs: N/A

Name and version of the database you are using:

The generated SQL (show_sql=true):

Debug level Hibernate log excerpt:



The problem I am having is that I am doing a saveOrUpdate and the changes are not reflected in graph. The code above List num1 and num2 should be different because of the saveOrUpdate.

I cannot close the session because of the lazy loading graph.

Does anyone have any suggestions or maybe I am just not configuring the mapping correctly?[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 02, 2005 11:55 am 
Regular
Regular

Joined: Tue Oct 28, 2003 8:25 am
Posts: 72
Location: Belgium
I see two differents things:

1) Since you mapped the relation as bidirectional, you must mark the set mapping of the Person class with inverse=true.

2) Nowhere in your java code you linked the new Transaction object to the Person object so I cannot see any reason why it should magically appear in the Person's collection. Due to your call to saveOrUpdate(), Hibernate should insert a new row in Transaction's table with the foreign key to Person set to null.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 02, 2005 12:56 pm 
Newbie

Joined: Fri Nov 04, 2005 12:32 pm
Posts: 14
Location: Detroit, MI, USA
Sorry that was just a bad example. Lets say the primary key has been set correclty so that the second call to "transaction.getPerson().getTransactions()" should return the new transaction.

I tried setting inverse="true", but I get the same result. I know the code is correct because closing the session before the second call returns the new transaction.

I also tried setting cascade="all", that did nothing.


Do you have any other ideas?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 02, 2005 1:17 pm 
Regular
Regular

Joined: Tue Oct 28, 2003 8:25 am
Posts: 72
Location: Belgium
Quote:
Sorry that was just a bad example. Lets say the primary key has been set correclty so that the second call to "transaction.getPerson().getTransactions()" should return the new transaction.

You meant the foreign key has been set correctly, right ?

How did you set it ? I suspect you're doing something wrong but I'm not sure because I'm lacking visibility on your problem.

Anyway, if you want both sides of the association to always be in sync, you have to manually set them, ie: manually add the transaction to the person's set and manually set the person in the transaction. Failing to do so could result in consistent DB state but incorrect memory state just like what you're seeing.

Carefully read the bidirectional one-to-many example in the doc:
http://www.hibernate.org/hib_docs/v3/re ... te-filters


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 02, 2005 3:14 pm 
Newbie

Joined: Fri Nov 04, 2005 12:32 pm
Posts: 14
Location: Detroit, MI, USA
Sorry, I just provided an example and cannot include the actual source. The foreign keys are working in my application because w/o lazy loading enabled I do not have the caching problem.

Also, I have second level cache disabled with (also query cache):

Code:
hibernate.cache.use_second_level_cache=false
hibernate.cache.use_query_cache=false


So basically, instead of saving the transaction, I want to add the transaction to the set that belongs to the person and save the person and have the save cascaded.

There is no mechanism to automatically do this?

Take a look at http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#objectstate-transitive. So refresh looks like a good idea for cascade, but the Javadoc says "It is inadvisable to use this to implement long-running sessions that span many business tasks".


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 02, 2005 3:41 pm 
Regular
Regular

Joined: Tue Oct 28, 2003 8:25 am
Posts: 72
Location: Belgium
Try removing the cascade parameter from the many-to-one side and change it to cascade="all" on the one-to-many side. This way when you add a new object to the set it will automatically be persisted.

I would advise you to re-read very carefully chapter 11.11. It cleary explains what you wanted to know. Why have you choosen refresh cascading style ?


Finally I do not understand this sentence:
Quote:
The foreign keys are working in my application because w/o lazy loading enabled I do not have the caching problem

I think you should enable lazy loading on the set.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 02, 2005 4:09 pm 
Newbie

Joined: Fri Nov 04, 2005 12:32 pm
Posts: 14
Location: Detroit, MI, USA
I changed the code example to something like this, and it worked:

Code:
List num1 = transaction.getPerson().getTransactions();

Transaction trans2 = new Transaction();
transaction.setPerson(trans2.getPersion())

session.saveOrUpdate(trans2);

Transaction obj =  Transaction)this.getHibernateTemplate().get(Transaction.class, trans2.getTransactionId());
           
this.getHibernateTemplate().flush();
this.getHibernateTemplate().evict(obj);

List num2 = transaction.getPerson().getTransactions();



I have tried cascade="all", but no luck with that either. I have a temporary solution, but will continue to look into this. Thanks for your help lorban.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 02, 2005 4:40 pm 
Newbie

Joined: Fri Nov 04, 2005 12:32 pm
Posts: 14
Location: Detroit, MI, USA
This also requires setting cascade="evict" (or all if you want).

I guess what I don't understand is why a save does not automatically evict the cache, I was assuming it did, but that appears to be wrong.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 02, 2005 5:37 pm 
Newbie

Joined: Wed Nov 30, 2005 9:06 pm
Posts: 1
lorban wrote:
I see two differents things:

1) Since you mapped the relation as bidirectional, you must mark the set mapping of the Person class with inverse=true.

2) Nowhere in your java code you linked the new Transaction object to the Person object so I cannot see any reason why it should magically appear in the Person's collection. Due to your call to saveOrUpdate(), Hibernate should insert a new row in Transaction's table with the foreign key to Person set to null.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 02, 2005 5:49 pm 
Newbie

Joined: Fri Nov 04, 2005 12:32 pm
Posts: 14
Location: Detroit, MI, USA
What was the point of that post?


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