-->
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: Replicate not removing children
PostPosted: Mon Oct 10, 2005 9:13 pm 
Newbie

Joined: Mon Oct 10, 2005 8:33 pm
Posts: 2
I poked around a bit, but couldn't find an answer to the question I have.

I have an entity that involves a one-to-many relationship - an order is the parent, and an order can be served by multiple shipments. This entity is stored in two separate databases.

One database is the one that will receive updates from various sources. I'll call it sourceDB from here on. The other database gets a subset of the entries in the primary database, ones that, for whatever reason, I'm interested in tracking / doing more work on without mucking with the sourceDB. We'll call this one workDB.

I have java code to select out the entities I want to move across from sourceDB to workDB, and actually perform the replication. That code looks something like this:

Code:
/* The collection of orders comes from a method that loads from sourceDB, and forces the lazy loading so that all children for a parent should be available for replication */
static public void replicateEntries( SessionFactory toSession,
      Collection<Order> orders )
{
   Session session = null ;   
   Transaction tx = null;
   
   try {
      session = toSession.openSession() ;
      
      // copy orders over.
      for( Order order : orders )
      {
         try {
            tx = session.beginTransaction() ;
               
            session.replicate( order, ReplicationMode.OVERWRITE ) ;
            
            tx.commit();
            tx = null;
         } catch( HibernateException e) {
            System.err.println( "Order " + order.getId() + " with ref " + order.getOrderReferenceId() + " caused a replication error." );
            System.err.println( "The hibernate error was " + e );
            e.printStackTrace();
         } finally {
            if( tx != null )
               tx.rollback();
         }               
      }      
   } finally {
      if( session != null )
         session.close();
   }
   
}


The definition of Order includes the following:
Code:
<set
  name="Shipments"
  inverse=true
  cascade="all, delete_orphan"
  lazy="true"
  fetch="select">
  <key column="ORDER_ID"/>
  <one-to-many class="Shipment">
</set>


Now, if you've read this far, I'm sure you're curious about the problem. Replicate is working great when an order first appears at the source and moves across for the first time - the associated shipments get moved fine. If I add a shipment to an open order, or order information changes, this gets updated in workDB without a problem. The problem is when a shipment is removed from an order in the sourceDB - replication does not remove the shipment in the workDB.

I currently have a workaround involving an explicit (cascading) delete on the entity in workDB, followed by the replication call as presented. That works fine, but is needlessly slow. I'm sure I could also workaround by poking through the Shipments in WorkDB, comparing them to the children of the loaded Order, and explicitly replicating/deleting those. However, it seems to me that replicate on the parent entity, with the cascade set to all should take care of this chore of updating/creating/removing children as necessary.

Please let me know if I'm doing something obviously wrong, have poor expectation/understanding of what replicate() does, or you can't decide because I've forgotten to include some important piece of code/schema.

Thanks for reading, and thanks in advance for your answers.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Oct 13, 2005 5:00 pm 
Newbie

Joined: Sun May 22, 2005 6:09 am
Posts: 10
I'm also having this problem, anyone else have seen this?

Right now I had to put in explicit deletes with extra transactions and it has killed my performance - its taking 2x as long as it used to just by using session.replicate() alone!

Thanks!
-ryan


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 17, 2005 5:03 pm 
Newbie

Joined: Mon Oct 10, 2005 8:33 pm
Posts: 2
One last bump hoping for an answer.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Oct 17, 2005 5:06 pm 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
This is correct behavior.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Oct 19, 2005 2:49 am 
Newbie

Joined: Sun May 22, 2005 6:09 am
Posts: 10
gavin wrote:
This is correct behavior.


I would assert this is incorrect behaviour - the SOURCE of the data has changed, to drop one of the children, and now your replicated database has more data now. If we consider versioning the object graph, this means hibernate replicate cannot be used to do negative changes on object graphs during replicate - only positive changes.

I seem to be unclear why this is correct? Is not the point of replicate to provide a manner to help make one database look the same as another?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Dec 07, 2005 2:33 pm 
Newbie

Joined: Mon Dec 05, 2005 2:53 pm
Posts: 1
I am experiencing an identical problem. I have a 1:M relationship with dependent objects that should be deleted when the parent is deleted (all-delete-orphan cascade). When I replace the parent object with added or modified child objects, the changes are replicated. However, when I replicate the parent object which has had children removed, the delete is not replicated to my other session.

Mapping:
Code:
<bag name="skins" lazy="true" order-by="sweepstake_skin_id asc" inverse="true" cascade="all-delete-orphan">
  <key column="SWEEPSTAKE_ID" not-null="true"/>
  <one-to-many class="SweepstakeSkin" />
</bag>


Code:
Code:

Session s = SessionFactoryUtils.getSession(getSessionFactory(), true);
Session s2 = s.getSession(EntityMode.DOM4J);
Criteria sc = s2.createCriteria(clazz);
sc.add(Expression.eq("id", object.getId()));
Element entityE = (Element) sc.uniqueResult();
s2.evict(entityE);
Session ss = SessionFactoryUtils.getSession(getProductionSessionFactory(), true);
Session ss2 = ss.getSession(EntityMode.DOM4J);   
ss2.replicate(clazz.getName(), entityE, ReplicationMode.OVERWRITE);


I am also confused as to how this is the correct behavior. Is manually deleting the child objects the only way to "replicate" the change?


Top
 Profile  
 
 Post subject:
PostPosted: Sat Apr 29, 2006 12:44 pm 
Beginner
Beginner

Joined: Wed Feb 25, 2004 6:23 pm
Posts: 39
Since we are considering using replicate ourselves, I too wonder why this is considered correct behavior? I believe most people would expect replicate to replicate negative operations (against a collection or object graph) to the destination DB. If we were to stack all the use cases where people need replicate to replicate both additive and negative operations to the destination on the left side of a scale, and stack all the use cases where people need replicate to only ADD information to the destination from the source (so that the destination will NEVER reflect deletes or removals made to the source database) on the right side of that scale, I think you would see the scale fall over so hard to the left that it would bust all over the place.
I should note that I have not tested this myself, and am relying on comments made in this thread. For my sake, this is good. If I tested this out myself and found the same behavior, I would be most frustrated, which would not be good for my blood pressure (my blood pressure works a lot like hibernate, I guess - it only replicates additive stress).

- Anodos


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 09, 2006 8:37 pm 
Newbie

Joined: Mon Apr 03, 2006 1:38 am
Posts: 11
I suppose your database referential integrity should take care of this. However, it would be nice if there was an option to handle it in hibernate for those DBMS's who don't enforce referential integrity (the last time I used MySQL it didn't). I don't understand why this is the correct solution myself. Can anyone elaborate?


Top
 Profile  
 
 Post subject: By design or faulty?
PostPosted: Thu Dec 04, 2008 8:38 am 
Newbie

Joined: Thu Dec 04, 2008 8:34 am
Posts: 1
Location: Thessaloniki, Greece
I experience the same problems as original submitter writes. So is this behaviour by design?

(note: RDBMS referential integrity is of no help for this issue: the parent id is the same after replication and all children continue to reference the same row)

I think that replication should work both for additions and for deletions


Top
 Profile  
 
 Post subject: Re: Replicate not removing children
PostPosted: Fri Apr 04, 2014 11:20 am 
Newbie

Joined: Fri Apr 04, 2014 11:18 am
Posts: 1
Do we have a solution to this issue? If not do we have a bug id corresponding to this?


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.