From: Richard B. <rb...@us...> - 2005-04-04 23:49:53
|
Update of /cvsroot/jcframework/dotnet In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13504 Modified Files: CCursor.vb CInjectedObject.vb CPersistenceBroker.vb CPersistentObject.vb Log Message: Fix when interfaced object has an association with a CPersistentObject. Fix for parent class association retrieval problem. Index: CPersistenceBroker.vb =================================================================== RCS file: /cvsroot/jcframework/dotnet/CPersistenceBroker.vb,v retrieving revision 1.104 retrieving revision 1.105 diff -u -d -r1.104 -r1.105 --- CPersistenceBroker.vb 4 Apr 2005 01:27:20 -0000 1.104 +++ CPersistenceBroker.vb 4 Apr 2005 23:49:43 -0000 1.105 @@ -417,7 +417,7 @@ End While obj.IsProxy = False 'Need to set non-proxy in case object is loaded via a retrieve criteria If Not obj.IsIPersistentObject Then - obj = LocateOrCacheInjObject(obj, False) + obj = LocateOrCacheInjObject(obj, False, True) End If m_cache.Add(obj) 'Add retrieved object to the cache Try @@ -451,7 +451,7 @@ End If If targetobj.Persistent Then If Not targetobj.IsIPersistentObject Then - targetobj = LocateOrCacheInjObject(targetobj, True) + targetobj = LocateOrCacheInjObject(targetobj, True, True) Else tmpObj = m_cache.Item(targetobj) End If @@ -491,7 +491,7 @@ targetobj = Me.createTargetObjectForMultipleInheritance(udamap.ToClass, obj.GetObjectType, obj.GetObjectType.Namespace, rs.ResultSet.Tables(0).Rows(i), joins, conn) If Not targetobj Is Nothing AndAlso targetobj.Persistent Then If Not targetobj.IsIPersistentObject Then - targetobj = LocateOrCacheInjObject(targetobj, True) + targetobj = LocateOrCacheInjObject(targetobj, True, True) Else tmpObj = m_cache.Item(targetobj) End If @@ -531,7 +531,7 @@ cm2.populateObject(cm2, targetobj, rs, mapName) If targetobj.Persistent Then If Not targetobj.IsIPersistentObject Then - targetobj = LocateOrCacheInjObject(targetobj, True) + targetobj = LocateOrCacheInjObject(targetobj, True, True) Else tmpObj = m_cache.Item(targetobj) End If @@ -601,7 +601,7 @@ classMapCount -= 1 'This is because we added one in the beginning of the for loop If Not targetobj Is Nothing AndAlso targetobj.Persistent Then If Not targetobj.IsIPersistentObject Then - targetobj = LocateOrCacheInjObject(targetobj, True) + targetobj = LocateOrCacheInjObject(targetobj, True, True) Else tmpObj = m_cache.Item(targetobj) End If @@ -661,7 +661,7 @@ 'For injected objects we want to work with just one version 'By not checking the persistent cache we can ensure this, and 'we will also be keeping the persistent cache updated - targetobj = LocateOrCacheInjObject(targetobj, True) + targetobj = LocateOrCacheInjObject(targetobj, True, True) tmpObj = Nothing Else tmpObj = m_cache.Item(targetobj) @@ -762,6 +762,7 @@ Dim Value As IPersistableObject Dim ValueObj As Object Dim ValueVar As String + Dim valuesSet As Boolean Dim tmpOIDValue As String Dim gotValue As Boolean Dim found As Boolean @@ -799,13 +800,20 @@ Value = udaMap.ToClass.CreateObjectInstance If Not Value Is Nothing Then 'Loop through fields in the association + valuesSet = False For j = 1 To udaMap.getSize ValueObj = obj.GetValueByAttribute(udaMap.getEntry(j).FromAttrMap.Name) If Not ValueObj Is Nothing Then Value.SetAttributeValue(udaMap.getEntry(j).ToAttrMap.Name, ValueObj) + valuesSet = True End If Next j + If valuesSet Then + If Not Value.IsIPersistentObject Then + anObjPers = LocateOrCacheInjObject(Value, True, True) + Else anObjPers = m_cache.Item(Value) + End If If anObjPers Is Nothing Then found = retrieveObject(Value, False, False) Else @@ -823,11 +831,17 @@ End If End If End If + End If ElseIf udaMap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_MANY Then + valuesSet = False For j = 1 To udaMap.getSize ValueVar = cm.getValueForRelationalDatabase(obj.GetValueByAttribute(udaMap.getEntry(j).FromAttrMap.Name)) + If Not ValueVar Is Nothing Then aCriteria.WhereCondition.addSelectEqualTo(udaMap.getEntry(j).ToAttrMap.Name, ValueVar) + valuesSet = True + End If Next j + If valuesSet Then aCriteria.ReturnFullObjects = Not udaMap.LazyLoad cursor = processCriteria(aCriteria, colCriteriaParameters, conn) col = obj.GetCollectionByAttribute(udaMap.FromClassTarget) @@ -852,10 +866,9 @@ anObjPers.OriginalCacheKey = New CCacheKey(anObjPers) col.Add(anObjPers.GetSourceObject) If Not anObjPers.IsIPersistentObject Then - anObjPers = LocateOrCacheInjObject(anObjPers, True) - Else + anObjPers = LocateOrCacheInjObject(anObjPers, True, True) + End If m_cache.Add(anObjPers) 'Add retrieved objects to the cache - End If Try PCCacheSize.RawValue = m_cache.Count Catch @@ -864,6 +877,7 @@ End While End If End If + End If Next i colCriteriaParameters = Nothing If Not cm.SuperClass Is Nothing Then @@ -891,7 +905,7 @@ ''' [rbanks] 16/12/2003 Created ''' </history> '''----------------------------------------------------------------------------- - Public Sub saveObject(ByRef obj As IPersistableObject) + Public Sub saveObject(ByVal obj As IPersistableObject) SyncLock GetType(CPersistenceBroker) Dim inTicks As Long, outTicks As Long inTicks = Now.Ticks @@ -964,7 +978,7 @@ ''' [rbanks] 16/12/2003 Created ''' </history> '''----------------------------------------------------------------------------- - Private Sub savePrivateObject(ByRef obj As IPersistableObject, ByVal conn As _CConnection) + Private Sub savePrivateObject(ByVal obj As IPersistableObject, ByVal conn As _CConnection) Dim j, i, k As Integer Dim clMap As CClassMap Dim m As Short @@ -2585,7 +2599,7 @@ Dim qObj As Object Dim col As IList 'Dim stack As New Stack - Dim queue As New queue + Dim q As New Queue Dim i, k As Integer Dim tmpObj As Object Dim injObj As IPersistableObject @@ -2596,7 +2610,7 @@ If obj.IsQueued Then 'if an object has already been added to the save queue, there is no need to add 'it again (could result in infinite recursion) - Return queue + Return q End If If includeBaseObject Then @@ -2611,23 +2625,23 @@ 'to this method while processing parent class maps will turn this off. 'Note that parent objects will not be dirty so in this case so we cannot 'do the normal IsDirty check. - If Not obj.IsDirty Then Return queue 'Do not save if nothing changed + If Not obj.IsDirty Then Return q 'Do not save if nothing changed End If - If obj.IsProxy Then Return queue 'Do not save if object is proxied + If obj.IsProxy Then Return q 'Do not save if object is proxied If GetType(IValidation).IsInstanceOfType(obj.GetSourceObject) Then - If Not CType(obj.GetSourceObject, IValidation).IsValid Then Return queue 'Do not save if object is not valid + If Not CType(obj.GetSourceObject, IValidation).IsValid Then Return q 'Do not save if object is not valid End If If obj.IsReadOnly Then - Return queue + Return q End If If (Not obj.Persistent) And obj.IsModifyOnly Then - Return queue + Return q End If If includeBaseObject Then - AddToQueue(obj, queue) + AddToQueue(obj, q) 'Do not return - since we saved this object we also need to check it's associations Else - Return queue + Return q End If Else 'Determine if the object needs saving @@ -2636,10 +2650,10 @@ (obj.IsDirty AndAlso Not obj.IsProxy AndAlso Not obj.IsReadOnly AndAlso Not obj.IsModifyOnly) Then If GetType(IValidation).IsInstanceOfType(obj.GetSourceObject) Then If CType(obj.GetSourceObject, IValidation).IsValid Then 'Do not save if object is not valid - AddToQueue(obj, queue) + AddToQueue(obj, q) End If Else - AddToQueue(obj, queue) + AddToQueue(obj, q) End If End If End If @@ -2660,7 +2674,7 @@ value = injObj End If For Each o In getObjectsToSave(value, True, checkAssociationsRecursivly) - queue.Enqueue(o) + q.Enqueue(o) Next End If ElseIf udamap.Cardinality = CUDAMap.CardinalityEnum.ONE_TO_MANY Then @@ -2674,7 +2688,7 @@ value = tmpObj End If For Each o In getObjectsToSave(value, True, checkAssociationsRecursivly) - queue.Enqueue(o) + q.Enqueue(o) Next Next k End If @@ -2685,7 +2699,7 @@ 'Delete the object qd = New CQueuedDelete qd.ObjectToDelete = value - queue.Enqueue(qd) + q.Enqueue(qd) Else For Each e As CUDAMapEntry In udamap.Entries 'Try to set to nothing first. If it fails set the value to NULL alias value @@ -2699,7 +2713,7 @@ End Try Next 'Now add object to list to be saved - queue.Enqueue(value) + q.Enqueue(value) End If Next ElseIf udamap.Cardinality = CUDAMap.CardinalityEnum.MANY_TO_MANY Then @@ -2725,7 +2739,7 @@ aObj = Nothing isNewManyToMany = state.ValidateObject(value) For Each qObj In getObjectsToSave(value, True, checkAssociationsRecursivly) - queue.Enqueue(qObj) + q.Enqueue(qObj) Next If isNewManyToMany Then 'We need to create an association object here for the class. @@ -2733,7 +2747,7 @@ aObj.ObjectA = obj aObj.ObjectB = value aObj.Association = udamap - queue.Enqueue(aObj) + q.Enqueue(aObj) End If Next k 'Remove old association records for items removed from the collection @@ -2745,7 +2759,7 @@ cm = cm.SuperClass End While - Return queue + Return q End Function ''' ----------------------------------------------------------------------------- @@ -2885,7 +2899,7 @@ Public Sub GetObject(ByRef obj As Object, ByVal useCache As Boolean) Dim injObj As CInjectedObject - injObj = LocateOrCacheInjObject(obj, False) + injObj = LocateOrCacheInjObject(obj, False, True) retrieveObject(injObj, False, useCache) obj = injObj.GetSourceObject End Sub @@ -2906,26 +2920,30 @@ End Sub Public Function getInjectedObject(ByVal obj As Object) As CInjectedObject - Return getInjectedObject(obj, False) + Return LocateOrCacheInjObject(obj, False, False) End Function Public Function getInjectedObject(ByVal obj As Object, ByVal createTemporary As Boolean) As CInjectedObject - Dim injObj As CInjectedObject - injObj = m_injectedObjects.Find(obj) - If injObj Is Nothing Then - injObj = New CInjectedObject(obj) - If createTemporary Then - 'When a single injected object has a reference to a set of objects that are - 'recursively referencing each other we need to add the objects to the cache - 'in order to prevent nested recursion. This temporary addition is only - 'used in getObjectsToSave - m_injectedObjects.AddTemp(injObj, False) - End If - End If - Return injObj + Return LocateOrCacheInjObject(obj, True, createTemporary) End Function - Public Function LocateOrCacheInjObject(ByVal obj As Object, ByVal replaceCachedValues As Boolean) As CInjectedObject + 'Public Function getInjectedObject(ByVal obj As Object, ByVal createTemporary As Boolean) As CInjectedObject + ' Dim injObj As CInjectedObject + ' injObj = m_injectedObjects.Find(obj) + ' If injObj Is Nothing Then + ' injObj = New CInjectedObject(obj) + ' If createTemporary Then + ' 'When a single injected object has a reference to a set of objects that are + ' 'recursively referencing each other we need to add the objects to the cache + ' 'in order to prevent nested recursion. This temporary addition is only + ' 'used in getObjectsToSave + ' m_injectedObjects.AddTemp(injObj, False) + ' End If + ' End If + ' Return injObj + 'End Function + + Public Function LocateOrCacheInjObject(ByVal obj As Object, ByVal replaceCachedValues As Boolean, ByVal addToCache As Boolean) As CInjectedObject Dim injObj As CInjectedObject injObj = m_injectedObjects.Find(obj) If injObj Is Nothing Then @@ -2934,7 +2952,9 @@ Else injObj = New CInjectedObject(obj) End If + If addToCache Then m_injectedObjects.Add(injObj) + End If Else If replaceCachedValues And Not injObj.IsLoading Then If TypeOf obj Is IPersistableObject Then @@ -3032,7 +3052,7 @@ Public Sub PersistChanges(ByVal obj As Object, ByVal checkAssociationsRecursively As Boolean) Dim value As IPersistableObject - Dim queue As queue + Dim q As Queue Dim qObject As Object Dim injObj, tmpObj As CInjectedObject Dim ckey As CCacheKey @@ -3048,7 +3068,7 @@ 'If for some reason the object isn't being tracked for changes yet, we will start 'tracking it now. - injObj = LocateOrCacheInjObject(obj, True) + injObj = LocateOrCacheInjObject(obj, True, True) If injObj.MarkedForDeletion Then deleteObject(injObj, injObj.WillDeleteParents) @@ -3059,12 +3079,12 @@ m_objectsToDelete.Clear() End If Else - queue = getObjectsToSave(injObj, True, checkAssociationsRecursively) + q = getObjectsToSave(injObj, True, checkAssociationsRecursively) 'All objects to be saved must be saved in a single transaction. - If queue.Count > 0 Then + If q.Count > 0 Then startTransaction() - Do While queue.Count > 0 - qObject = queue.Dequeue() + Do While q.Count > 0 + qObject = q.Dequeue() Try If GetType(CAssociationObject).IsInstanceOfType(qObject) Then saveAssociationObject(qObject) @@ -3377,10 +3397,10 @@ Return toColl End Function - Private Sub AddToQueue(ByVal obj As IPersistableObject, ByRef queue As Queue) - Call AddToQueue(obj, queue, True) + Private Sub AddToQueue(ByVal obj As IPersistableObject, ByRef q As Queue) + Call AddToQueue(obj, q, True) End Sub - Private Sub AddToQueue(ByVal obj As IPersistableObject, ByRef queue As Queue, ByVal includeObject As Boolean) + Private Sub AddToQueue(ByVal obj As IPersistableObject, ByRef q As Queue, ByVal includeObject As Boolean) 'Called recursively so that objects with superclasses are queued from the 'top most object down. Dim cm As CClassMap @@ -3389,13 +3409,13 @@ If Not cm.SuperClass Is Nothing Then tmpobj = obj.GetObjectByClassMap(cm.SuperClass) If cm.SharedTableField Is Nothing Then - AddToQueue(tmpobj, queue, True) + AddToQueue(tmpobj, q, True) Else - AddToQueue(tmpobj, queue, False) + AddToQueue(tmpobj, q, False) End If End If If includeObject Then - queue.Enqueue(obj) + q.Enqueue(obj) End If Return End Sub @@ -3420,7 +3440,7 @@ If TypeOf obj Is IPersistentObject Then Throw New RetrieveException("The RefreshObject method cannot be used for classes that inherit from CPersistentObject. Use obj.Refresh()") End If - injObj = LocateOrCacheInjObject(obj, False) + injObj = LocateOrCacheInjObject(obj, False, True) injObj.ResetToOriginal() If Not useCache Then retrieveObject(injObj, False, False) Index: CCursor.vb =================================================================== RCS file: /cvsroot/jcframework/dotnet/CCursor.vb,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- CCursor.vb 22 Mar 2005 06:09:03 -0000 1.16 +++ CCursor.vb 4 Apr 2005 23:49:42 -0000 1.17 @@ -270,12 +270,14 @@ Else obj.AssociationsLoaded = True End If - pbroker.InjectedObjects.Add(obj) + obj = pbroker.LocateOrCacheInjObject(obj, True, True) + 'pbroker.InjectedObjects.Add(obj) Else 'need to retrieve the proxy and then load the object clMap.populateProxy(obj, m_row, _alias) pbroker.retrieveObject(obj, False, True) - pbroker.InjectedObjects.Add(obj) + obj = pbroker.LocateOrCacheInjObject(obj, True, True) + 'pbroker.InjectedObjects.Add(obj) End If Exit Sub End If @@ -289,12 +291,14 @@ Else obj.AssociationsLoaded = True End If - pbroker.InjectedObjects.Add(obj) + obj = pbroker.LocateOrCacheInjObject(obj, True, True) + 'pbroker.InjectedObjects.Add(obj) Else 'need to retrieve the proxy and then load the object clMap.populateProxy(obj, m_row) pbroker.retrieveObject(obj, False, True) - pbroker.InjectedObjects.Add(obj) + obj = pbroker.LocateOrCacheInjObject(obj, True, True) + 'pbroker.InjectedObjects.Add(obj) End If End Sub Index: CInjectedObject.vb =================================================================== RCS file: /cvsroot/jcframework/dotnet/CInjectedObject.vb,v retrieving revision 1.22 retrieving revision 1.23 diff -u -d -r1.22 -r1.23 --- CInjectedObject.vb 4 Apr 2005 01:27:20 -0000 1.22 +++ CInjectedObject.vb 4 Apr 2005 23:49:42 -0000 1.23 @@ -418,8 +418,9 @@ obj = CallByName(o, propertyName, CallType.Get) End If If obj Is Nothing Then Return Nothing - If obj.GetType.IsSubclassOf(GetType(IPersistableObject)) Then - injobj = CType(obj, CInjectedObject) + 'If obj.GetType.IsSubclassOf(GetType(IPersistableObject)) Then + If TypeOf obj Is IPersistableObject Then + injobj = obj Else pbroker = getPersistenceBrokerInstance() injobj = pbroker.getInjectedObject(obj) Index: CPersistentObject.vb =================================================================== RCS file: /cvsroot/jcframework/dotnet/CPersistentObject.vb,v retrieving revision 1.62 retrieving revision 1.63 diff -u -d -r1.62 -r1.63 --- CPersistentObject.vb 4 Apr 2005 01:27:24 -0000 1.62 +++ CPersistentObject.vb 4 Apr 2005 23:49:43 -0000 1.63 @@ -596,9 +596,14 @@ <EditorBrowsable(EditorBrowsableState.Advanced)> _ Public Function getObjectByAttribute(ByVal pName As String) As IPersistableObject Implements IPersistableObject.getObjectByAttribute Dim dotPos As Integer + Dim obj As Object + Dim injobj As IPersistableObject + Dim pbroker As CPersistenceBroker + dotPos = pName.IndexOf(".") + Try If dotPos = -1 Then - Return CallByName(Me, pName, CallType.Get) + obj = CallByName(Me, pName, CallType.Get) Else Dim o As Object Dim objName As String @@ -606,8 +611,19 @@ objName = pName.Substring(0, dotPos) propertyName = pName.Substring(dotPos + 1) o = CallByName(Me, objName, CallType.Get) - Return CallByName(o, propertyName, CallType.Get) + obj = CallByName(o, propertyName, CallType.Get) End If + If obj Is Nothing Then Return Nothing + If TypeOf obj Is IPersistableObject Then + injobj = obj + Else + pbroker = getPersistenceBrokerInstance() + injobj = pbroker.getInjectedObject(obj) + End If + Catch ex As Exception + Throw New Exception("getObjectByAttribute failed for attribute " & pName & " in " & Me.GetType.FullName, ex) + End Try + Return injobj End Function '''----------------------------------------------------------------------------- |