-->
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.  [ 11 posts ] 
Author Message
 Post subject: How to reassociate a dirty collection with a new session?
PostPosted: Fri Feb 11, 2005 1:01 pm 
Beginner
Beginner

Joined: Mon Aug 02, 2004 1:08 pm
Posts: 42
Hi.

Our application follows session-per-request-with-detached object pattern for application transactions and we have a problem with the re-association of the detached object.

That is, during the first request, the user adds a new element (BusinessHours) to the parent object (Hotline), which then becomes detached. After a new child element is added, a businessHoursSet collection whithin the hotline becomes dirty, therefore we have to use session.update(...) to reassociate the hotline with the new session in a second request.

However, during this update, elements of the businessHoursSet are not updated but saveOrUpdated. Consequently, all new elements of businessHoursSet are saved, which is not desired.

My question is: how do I correctly reassociate detached objects having dirty collections with a new session?

Why does update cascades to saveOrUpdate in child collections? I mean specifically the following code in SessionImpl:

Code:
   private void doUpdate(Object object, Serializable id, ClassPersister persister) throws HibernateException {

      if ( !persister.isMutable() ) {
         log.trace("immutable instance passed to doUpdate(), locking");
         reassociate(object, id, persister);
      }
      else {
         doUpdateMutable(object, id, persister);
      }

      cascading++;
      try {
         Cascades.cascade(this, persister, object, Cascades.ACTION_SAVE_UPDATE, Cascades.CASCADE_ON_UPDATE);  // do cascade
      }
      finally {
         cascading--;
      }

   }


May be I miss something, but should it not be something like Cascades.ACTION_UPDATE instead of SAVE_UPDATE?

Your help is greately appreciated.

Hotline might be assumed as an object with id (long, -1 means new object) and businessHoursSet (a set of BusinessHours objects).

BusinessHours imight be assumed to be a simple object with long id (-1 means new).

Mapping is something like:

Code:
  <class name="de.disy.vcc.bo.hotline.Hotline" table="hotlines">
    <!-- <cache usage="read-write"/> -->
    <id name="id" column="id" type="long" unsaved-value="-1">
      <generator class="sequence">
        <param name="sequence">hotline_ids</param>
      </generator>
    </id>

  ....

    <set name="businessHoursSet" table="hotline_business_hours_relations" cascade="all" lazy="true">
      <key column="hotline_id" />
      <many-to-many column="business_hours_id" class="de.disy.vcc.bo.hotline.BusinessHours"/>
    </set>

...
  </class>

  <class name="de.disy.vcc.bo.hotline.BusinessHours" table="business_hours">
    <id name="id" column="id" type="long" unsaved-value="-1">
      <generator class="sequence">
        <param name="sequence">business_hours_ids</param>
      </generator>
    </id>
    <property name="day">
      <column name="day" sql-type="smallint" not-null="true"/>
    </property>
    <property name="timeFrom">
      <column name="time_from" sql-type="varchar(10)" not-null="true"/>
    </property>
    <property name="timeTo">
      <column name="time_to" sql-type="varchar(10)" not-null="true"/>
    </property>
  </class>


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 17, 2005 9:26 am 
Beginner
Beginner

Joined: Mon Aug 02, 2004 1:08 pm
Posts: 42
Sorry for bumping this - any help would be greately appreciated.

I hope the question is fine formulated - otherwise please let me know were could I be more clear. This is a major issue for us since right now we have to give up lazy collections, which destorys the performance.

Thank you in advance.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 17, 2005 9:36 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Your problem makes no sense. Why would you *not* want new elements to be saved??


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 17, 2005 9:57 am 
Beginner
Beginner

Joined: Mon Aug 02, 2004 1:08 pm
Posts: 42
Because it is not the correct time from the application flow point of view. I have a long application transaction spanning several requests which may (but also may not) lead to saving the parent object (in this case - a hotline) into the database. Objects should be saved only when user desires to save them, not because of the reassociation of a detached object.

I want to use session.update(...) *only* to reassociate a detached object with a new Hibernate session (primary goal is that lazy collections or proxies could be accessed). Saving new elements in collections is an undesired side effect and I have no idea how could I avoid it.

A similar problem was discussed in another topic - however no good answer.

http://forum.hibernate.org/viewtopic.php?t=928481&start=0&postdays=0&postorder=asc

Thank you for your time.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 17, 2005 10:13 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
So don't flush the session at the end of that transaction.

This seems like a trivial problem??


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 17, 2005 10:17 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
Actually, let me qualify that slightly: either

(1) disable cascade on that association, and flush on that transaction OR
(2) disable flush and use a long session


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 17, 2005 10:22 am 
Beginner
Beginner

Joined: Mon Aug 02, 2004 1:08 pm
Posts: 42
gavin wrote:
So don't flush the session at the end of that transaction.

This seems like a trivial problem??


The problem is that session.update(hotline) cascades to session.saveOrUpdate(businessHours). And saveOrUpdate assigns a new identifier to the new businessHours object. And when the session is finally flushed, Hibernate issues an UPDATE statement for a *new* object, not the INSERT statement, since this new object is already assigned an id.

select-before-update="true" on BusinessHours object does not help either.

Do you think it is correct to save new objects when reassociating a detached structure? I think it's not.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 17, 2005 10:25 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
See my qualification.

Personally I use long sessions in this kind of scenario.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 17, 2005 10:46 am 
Beginner
Beginner

Joined: Mon Aug 02, 2004 1:08 pm
Posts: 42
gavin wrote:
See my qualification.

Personally I use long sessions in this kind of scenario.


Thank you.

Long sessions are, unfortunatelly, not an option: we may not block concurrent requests from the same user, we do not know exactly when application transactions start and end.

Disable cascade on association - well, this is an option, but it isn't nice. Actually, the association should be cascaded.

What happens during reassociation with session.update() is not 100% correct from my point of view. Ideal would be a session.reassociate(...) method, which would reassociate objects (including proxies) and persistent collections (including "lazy") with the current session.

It seems like at the moment I'll have to avoid detached objects with lazy properties - either make properties non-lazy or initialize required properties before detaching.

I will also try implementing reassociate(...) method. I hope I'll opnly need to replace the cascading operation of the doUpdate(...).


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 17, 2005 10:47 am 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
There is session.lock(obj, LockMode.NONE)


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 17, 2005 10:52 am 
Beginner
Beginner

Joined: Mon Aug 02, 2004 1:08 pm
Posts: 42
michael wrote:
There is session.lock(obj, LockMode.NONE)


... which is for unchanged objects only. If user adds new business hours to the hotline, session.lock(..) would produce "reassociating a dirty collection" exception.

Sorry.


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