Current filter:
                                You should refresh the page.
                                0
                                  • The PurgeDeletedObjects() method seems not to work in some cases.

                                    In my database there are many objects marked as deleted (GCRecord != null), but PurgeDeletedObjects() is not able to remove them from the database. When I'm removing the records by hand, it works (bottom up on derived objects table).
                                    There are 3 tables involved:
                                    BaseObject -> ValueObject -> RealObject

                                    Is there a way to findout why PurgeDeleteObjects is failing?

                                Show all comments
                                • I am afraid that we cannot give you any suggestions, because the source of the problem is unclear. Would you please provide a sample project or database backup with business classes for us to research?

                                • Severin Meyer 06.26.2012

                                  I was hoping there were a possibility to call the PurgeDeletedObjects() on a single object. So I would then be able to Log the XPO and SQL calls especially for this process.
                                  Unfortunately the project is complex and I haven't the time for creating a sample. But is there a description of the PurgeDeletedObjects(), so I can see which logic is used on a record which has GCRecord != null. In which order it should be called on descendant tables and so on?

                                • Severin Meyer 06.26.2012

                                  I have now investigated the SQL-statements processed from PurgeDeleteObjects(). Some of them are returning a record, but there is no delete statement. I was thinking, that PurgeDeleteObjects will collect all objects which can be purged, and will then call delete on every found record.

                                • Thank you for the additional information. I am forwarding your ticket to our developers. We will let you know if we have any ideas regarding the cause of the problem.

                                • Our developers suppose that the issue is in objects that reference objects that cannot be deleted. You can find these objects via the following code:

                                      public static class GCRootsFindHelper {
                                          public static IEnumerable FindRoots(IXPSimpleObject theObject) {
                                              return FindRoots(theObject.Session, theObject);
                                          }
                                          public static IEnumerable FindRoots(Session session, params object[] objects) {
                                              return FindRoots(session, (IEnumerable)objects);
                                          }
                                          public static IEnumerable FindRoots(Session session, IEnumerable notPurgedObjects) {
                                              ArrayList rv = new ArrayList();
                                              ArrayList toProcess = new ArrayList(notPurgedObjects.Cast<object>().ToArray());
                                              ObjectSet processed = new ObjectSet();
                                              while(toProcess.Count > 0) {
                                                  object o = toProcess[toProcess.Count - 1];
                                                  toProcess.RemoveAt(toProcess.Count - 1);
                                                  if(processed.Contains(o))
                                                      continue;
                                                  processed.Add(o);
                                                  if(session.IsObjectMarkedDeleted(o)) {
                                                      foreach(object r in session.CollectReferencingObjects(o, PersistentCriteriaEvaluationBehavior.InTransaction, true)) {
                                                          if(!processed.Contains(r))
                                                              toProcess.Add(r);
                                                      }
                                                  } else {
                                                      rv.Add(o);
                                                  }
                                              }
                                              return rv;
                                          }
                                      }
                                  
                                  Hope this helps.

                                • Severin Meyer 06.27.2012

                                  This function was really helpful. You should consider to add it directly on the session object.
                                  I could find out, that an older object instance is not deleted when overwritten:

                                          private LocalizedString localizedInformation;
                                          [Aggregated]
                                          public LocalizedString LocalizedInformation
                                          {
                                              get { return localizedInformation; }
                                              set
                                              {
                                                  if (localizedInformation != null && localizedInformation != value)
                                                  {
                                                      // Delete old string.
                                                      localizedInformation.Delete();
                                                  }
                                                  SetPropertyValue<LocalizedString>("LocalizedInformation", ref localizedInformation, value);
                                              }
                                          }

                                  If I don't add the Delete() method, the old value when setting the property will not be deleted.
                                  Is this by design?

                                • Thank you for your idea. I will pass it to our developers.
                                  Aggregated references are not deleted by default when the property value is changed. If one requires this logic, he/she needs to take care of this, as you did in your code snippet.

                                • Severin Meyer 06.28.2012

                                  But this is what I have asked DevExpress longtime ago, and the answer was, if the property is attributed with [Aggregated], the objects will be deleted. And I was using this approach with simpler objects, and they were deleted.
                                  Is [Aggregated] obsolete now?

                                • I think there was some kind of misunderstanding about this attribute. The Aggregated deletes related objects only when the master object is deleted. In spite of the fact that, most probably, this functionality worked in a previous version as you described, it was not designed to operate in such a manner. The [Aggregated] attribute is not obsolete, it still works just as described in our documentation. Should you have any additional questions in this regard, do not hesitate to contact me.

                                  I have also posted an Answer, so that you can close this ticket.

                                You must  log in  or  register  to leave comments

                                1 Solution

                                1

                                You can determine what objects prevent record deletion via the following code:

                                	
                                [C#]
                                public static class GCRootsFindHelper { public static IEnumerable FindRoots(IXPSimpleObject theObject) { return FindRoots(theObject.Session, theObject); } public static IEnumerable FindRoots(Session session, params object[] objects) { return FindRoots(session, (IEnumerable)objects); } public static IEnumerable FindRoots(Session session, IEnumerable notPurgedObjects) { ArrayList rv = new ArrayList(); ArrayList toProcess = new ArrayList(notPurgedObjects.Cast<object>().ToArray()); ObjectSet processed = new ObjectSet(); while(toProcess.Count > 0) { object o = toProcess[toProcess.Count - 1]; toProcess.RemoveAt(toProcess.Count - 1); if(processed.Contains(o)) continue; processed.Add(o); if(session.IsObjectMarkedDeleted(o)) { foreach(object r in session.CollectReferencingObjects(o, PersistentCriteriaEvaluationBehavior.InTransaction, true)) { if(!processed.Contains(r)) toProcess.Add(r); } } else { rv.Add(o); } } return rv; } }

                                You must  log in  or  register  to leave comments
                                You must  log in  or  register  to leave an answer

                                Is your intention to post an answer to your own question?

                                • If so, then proceed.
                                • If you simply wanted to post additional information, ask for further clarification, or to just say "Thanks!", please click Leave a Comment.
                                • If you wish to edit your original question, please use the Edit button in the Toolbox at the top right corner of that entry.