-->
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: Version and Parent/Child relationship?
PostPosted: Fri Jan 02, 2004 2:14 pm 
Regular
Regular

Joined: Wed Dec 17, 2003 1:58 pm
Posts: 102
Hi I am working with some objects basically in the usual parent/child relationship. I am using version columns in both objects so I can manage concurrent updates among objects. I am baffled however on how versioning gets applied when the parent object is saved. A couple questions:

1) If parent is modified, children not modified, parent is saved, does it also update the version of the children?

Well I guess thats the main question :) I don't want versioning to be applied down the chain if only the parent object is modified..

Any help is greatly appreciated!
Thanks,
David


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 02, 2004 2:17 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
Have you tried it ?

What did it do ?

...
...
...

version is only updated if the core entity is modified - adding children to an entity does not change the core entity.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 02, 2004 2:26 pm 
Regular
Regular

Joined: Wed Dec 17, 2003 1:58 pm
Posts: 102
Ok I just tested it to confirm what happened earlier. When I update the parent object it increments its version obviously, but also increments the child objects version. Here are the mappings for the objects:

Code:
<hibernate-mapping>
    <class name="marketing.Prospect" table="marketingProspect">
      <id name="id" type="long" unsaved-value="null">
           <generator class="identity"/>
        </id>
       <version name="version" type="long" unsaved-value="null"/>
        <property name="assets"/>
        <property name="assignedRep"/>
        <property name="attentionPriority"/>
        <property name="customerId"/>
        <property name="federal"/>
        <property name="lastActivityDate"/>
        <many-to-one name="lastActivityType" cascade="none"/>
        <property name="members"/>
        <property name="name"/>
        <property name="ncuaId"/>
        <property name="nextActivityDate"/>
        <many-to-one name="nextActivityType" cascade="none"/>
        <property name="note">
           <column name="note" sql-type="mediumtext"/>           
        </property>
        <property name="phone"/>
        <property name="website"/>
        <many-to-one name="salesRegion" cascade="none"/>
        <set name="activities" cascade="all-delete-orphan" inverse="true" lazy="true" order-by="date asc">
         <key column="prospect_id"/>
         <one-to-many class="marketing.Activity"/>
      </set>
      <set name="contacts" cascade="all-delete-orphan" inverse="true" lazy="true" order-by="isPrimary desc">
         <key column="prospect_id"/>
         <one-to-many class="marketing.Contact"/>
      </set>       
      <set name="locations" cascade="all-delete-orphan" inverse="true" lazy="true" order-by="isPrimary desc">
         <key column="prospect_id"/>
         <one-to-many class="marketing.Location"/>
      </set>       
      </class>
</hibernate-mapping>

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
    <class name="marketing.Activity" table="marketingActivity">
        <id name="id" type="long">
            <generator class="identity"/>
        </id>
       <version name="version" type="long" unsaved-value="null"/>
        <property name="date">
           <column name="date" sql-type="datetime"/>   
        </property>
        <property name="description">
           <column name="description" sql-type="mediumtext"/>
        </property>
        <many-to-one name="activityType" cascade="none">
           <column name="activityType_id"/>
        </many-to-one>
      <many-to-one name="prospect" column="prospect_id" not-null="true"/>
    </class>

</hibernate-mapping>


Here is the code in my struts action that is doing the updating on the object:

Code:
    Session session;

    try {
      session = HibernateFilter.getSession();
      Transaction tx = session.beginTransaction();
     
      SalesRegion region = (SalesRegion)session.get(SalesRegion.class, theform.getSalesRegionId());
      prospect.setSalesRegion(region);
      if (theform.getNewActivityTypeId() != null && (theform.getNewActivityTypeId().longValue() > 0)) {
        ActivityType activityType = (ActivityType)session.get(ActivityType.class, theform.getNewActivityTypeId());
        Activity activity = theform.getNewActivity();
        activity.setDate(new Date(System.currentTimeMillis()));
        activity.setActivityType(activityType);
        activity.setProspect(prospect);
        prospect.getActivities().add(activity);
        session.flush();
      }
      session.saveOrUpdate(prospect);
      tx.commit();
      forward = mapping.findForward("success");
      //HibernateUtil.closeSession();
    } catch (StaleObjectStateException o1) {
      errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.prospect.outofdate"));   
    } catch (HibernateException e1) {
     
      logger.error("Error saving prospect with id: " + prospect.getId(), e1);
      forward = mapping.findForward("failure");
    }


I have traced through the code in that action and if I know for sure the code with the new activity is not getting executed unless I add a new activity. But if I change something in my prospect object my activities versions all get incremented as well.

Is there any way to stop this?
Thanks,
David


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 02, 2004 2:33 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 6:10 am
Posts: 8615
Location: Neuchatel, Switzerland (Danish)
quick guess - hibernate thinks the children has changed because their parent object has changed ....or you have an incorrect value of unsaved-value.

_________________
Max
Don't forget to rate


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 02, 2004 2:39 pm 
Regular
Regular

Joined: Wed Dec 17, 2003 1:58 pm
Posts: 102
Using the above code even if I do not change ANYTHING in the object it will execute the following sql code:
Code:
Hibernate: update marketingProspect set version=?, assets=?, assignedRep=?, attentionPriority=?, customerId=?, federal=?, lastActivityDate=?, lastActivityType=?, members=?, name=?, ncuaId=?, nextActivityDate=?, nextActivityType=?, note=?, phone=?, website=?, salesRegion=? where id=? and version=?
Hibernate: update marketingActivity set version=?, date=?, description=?, activityType_id=?, prospect_id=? where id=? and version=?
Hibernate: update marketingActivity set version=?, date=?, description=?, activityType_id=?, prospect_id=? where id=? and version=?
Hibernate: update marketingActivity set version=?, date=?, description=?, activityType_id=?, prospect_id=? where id=? and version=?


Am I calling something incorrectly in my code that is forcing it to update even if nothing has changed?

I guess the underlying problem is this: I load my object from a session, then the session gets closed, the object gets passed through an html form and either modified or left alone, then I open a new session and have no way to tell if that object has been changed or not, so I call saveOrUpdate() on it. And it is currently disassociated with any session, but it still contains its ID value so Hibernate knows that it has been previously saved, but I think it is forcing an update on the DB even if it hasnt been modifed. Is there someway to re-associate it with the persistance layer without hibernate loading values into the object? I just don't want my changes to be overwritten before they get persisted to the db. Did that make any sense? :)
Thanks,
David


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 02, 2004 2:48 pm 
Hibernate Team
Hibernate Team

Joined: Tue Sep 09, 2003 2:10 pm
Posts: 3246
Location: Passau, Germany
You can reassociate your object with the session using session.lock(object, LockMode.NONE). I am not sure this solves your problem however, as you need to update the object If i get you right.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 02, 2004 2:51 pm 
Regular
Regular

Joined: Wed Dec 17, 2003 1:58 pm
Posts: 102
Ya in more clear terms the problem is I don't want to update an object and its version needlessly. I seem to have no way of knowing if the user actually modified the object or not. Is there someway to re-associate an object with hibernate, have hibernate check if its been modified, and ONLY if it has been modified issue an update command?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 02, 2004 3:08 pm 
Regular
Regular

Joined: Wed Dec 17, 2003 1:58 pm
Posts: 102
I modifed my code a little bit, at the beginning of my update action I tried calling session.lock(prospect, LockMode.NONE); and I also removed any call to session.saveOrUpdate(prospect);

The results:
1) If I modify any of the normal data fields of the object while it is transient then after I lock it, it will not update the object to the persistance layer.
2) If I modify any of the sets or other class objects associated with the prospect object, it will update them, and also update the parent object AND its version.

So my question now is WHY is #1 not being updated? If I load the object in session 1, then close that session, modify the object, start a new session, re associate the object with the new session, shouldn't it detect the changes that have been made? Or is there a way to make it detect them?

Thanks,
David


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 02, 2004 3:24 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
From the reference guide
Code:
//just reassociate:
sess.lock(fritz, LockMode.NONE);
//do a version check, then reassociate:
sess.lock(izi, LockMode.READ);
//do a version check, using SELECT ... FOR UPDATE, then reassociate:
sess.lock(pk, LockMode.UPGRADE);


This means that LockMode.NONE suppose you object hasn't be updated, so why update it ?

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 02, 2004 3:30 pm 
Regular
Regular

Joined: Wed Dec 17, 2003 1:58 pm
Posts: 102
Ok I think I understand the lock better now, that is not what I need to do. What I have modified is putting select-before-update="true" in my class mapping, then just calling saveOrUpdate();

However one last problem remains. Is it possible to setup cascading to only update the children if they have changed? I put select-before-update="true" into my child class mapping but it didn't do it, my cascade is listed as all-delete-orphan to the children.

Thanks in advance,
David


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.