Menu

Error in CopyOneToManyCollections()

2005-04-08
2013-03-07
  • victor Saquicela

    Hi.

    I have a problem with last CVS. My aplication is correct with atoms version 2.0, now I download of the CVS, my aplication have many problems with a function:

    <Browsable(False)> Public Property IsLoading() As Boolean Implements IPersistentObject.IsLoading
            Get
                Return m_isLoading
            End Get
            Set(ByVal Value As Boolean)
                If m_isLoading <> Value Then
                    If Value = True Then
                        RaiseEvent LoadStarted(Me, New EventArgs)
                    Else
                        RaiseEvent LoadFinished(Me, New EventArgs)
                        'Also need to copy collections for one-to-many associations so that we
                        'have a reference point when figuring out what changed.
                        CopyOneToManyCollections()
                    End If
                End If
                m_isLoading = Value
            End Set
        End Property

    I have the following structure:

    A -- OneToMany B, in the associate is retriveAutomatic="False". My idea is that retrive collection only when I use a.b()

    in the property to retrive B I have the following:

    Property Transacciones() As TransaccionC
                Get
                    If _transacciones.Count = 0 Then
                        _transacciones.Clear()
                        Dim t As New Transaccion
                        Dim rc As New CRetrieveCriteria
                        rc.ClassMap = t.getClassMap
                        rc.WhereCondition.addSelectEqualTo("CodigoCuenta", Me.CodigoCuenta)
                        Dim cc As CCursor = rc.perform()
                        While Not cc.EOF
                            t = New Transaccion
                            cc.loadObject(t)
                            _transacciones.Add(t)
                            cc.nextCursor()
                        End While
                        getPersistenceBrokerInstance.addToCache(Me)
                    End If

                    Return _transacciones
                End Get

    then, when I ejecute a.find(a) this code access to a.b(), this cause a object not instance, because the method CopyOneToManyCollections() access to my property. If I have retriveAtomatic="False" this method don't access to collection, because I don't need this collection in the moment.

     
    • victor Saquicela

      I don't know if this is the solutio, but I change your code in the CPersistenBroker:

      Friend Shared Function CopyCollection(ByVal fromObject As IPersistableObject, ByVal propertyName As String) As Object
              Dim t, iListType, iDicType As Type
              Dim fromColl, toColl, collItem As Object
              Dim il As IList
              Dim id As IDictionary
              Dim p As PropertyInfo
              Dim tmpObj As Object

              fromColl = fromObject.GetCollectionByAttribute(propertyName)
              If fromColl Is Nothing Then

                  Return Nothing
              End If

              p = fromObject.GetObjectType.GetProperty(propertyName, BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.Public)
              If p Is Nothing Then
                  Return Nothing
              End If
              iListType = p.PropertyType.GetInterface("IList", True)
              iDicType = p.PropertyType.GetInterface("IDictionary", True)
              If Not iListType Is Nothing OrElse Not iDicType Is Nothing Then
                  Dim ICloneType As Type = p.PropertyType.GetInterface("ICloneable", True)
                  If Not ICloneType Is Nothing Then
                      'Getting the ICloneable interface from the object.
                      tmpObj = p.GetValue(fromObject.GetSourceObject, Nothing)
                      If Not tmpObj Is Nothing Then
                          Dim IClone As ICloneable = CType(tmpObj, ICloneable)
                          toColl = IClone.Clone()
                      Else
                          toColl = Nothing
                      End If
                      Return toColl
                  Else
                      'If the field doesn't support the ICloneable interface then just set it.
                      'need to copy collection members one by one
                      t = p.PropertyType
                      toColl = Activator.CreateInstance(t)
                      Dim fColl, fieldsColl() As FieldInfo
                      If Not iListType Is Nothing Then
                          il = CType(toColl, IList)
                          For Each collItem In fromColl
                              il.Add(collItem)
                          Next
                      Else
                          id = CType(toColl, IDictionary)
                          For Each de As DictionaryEntry In fromColl
                              id.Add(de.Key, de.Value)
                          Next
                      End If
                  End If
              End If
              Return toColl
          End Function

      I add the following lines:

              If p Is Nothing Then
                  Return Nothing
              End If

      I think that the collection.count is 0, then don't have retrive by atribute, it not exist.

      I don't know if in the method
      Private Sub CopyOneToManyCollections() Implements IPersistableObject.CopyOneToManyCollections
              Dim cm As CClassMap
              Dim coll As Object
              cm = Me.getClassMap
              m_oneToManyCollections = New Collection
              Dim aMap As CUDAMap
              While Not cm Is Nothing
              For Each de As DictionaryEntry In cm.AssociationMaps
                  aMap = de.Value
                  If aMap.Cardinality = aMap.CardinalityEnum.ONE_TO_MANY Then
                      coll = CPersistenceBroker.CopyCollection(Me, aMap.FromClassTarget)
                      m_oneToManyCollections.Add(coll, aMap.FromClassTarget)
                  End If
              Next
                  cm = cm.SuperClass
              End While
          End Sub

      I change the next code:
      coll = CPersistenceBroker.CopyCollection(Me,
      aMap.FromClassTarget)
      if not coll is nothing then
                      m_oneToManyCollections.Add(coll, aMap.FromClassTarget)
      endif

      or not ?????????????

       
    • victor Saquicela

      the problem is when the collection is empty.

      Any sugestion

       
    • Richard Banks

      Richard Banks - 2005-04-11

      Hi Victor,

      I've changed the code as follows:

      1.  In CopyCollections I check the property exists before checking if the collection exists

      2.  In CopyOneToManyCollections I only copy collections that have both the retrieveAutomatic and saveAutomatic flag equal to "true".  Lazy load and non-retrieve associations are now ignored.

      3. In GetObjectsToSave I only look for collections with the retrieveautomatic="true" flag and the saveAutomatic="true".

      I've updated CVS in both the v2_1 branch and the Main branch.  The main branch contains all the changes to naming, so I suggest you get the code from the v2_1 branch for the moment.

      Let me know if this fixes it for you.

      - Richard.

       
    • Nobody/Anonymous

      Where  I get the code from the v2_1 branch. I view only version with naming

       
      • Richard Banks

        Richard Banks - 2005-04-12

        If you are using TortoiseCVS you have 2 options.

        1.  Checkout the dotnet module to a new directory.
        Start a checkout, in the Revision tab, select "Choose branch or tag" and enter v2_1
        In the options tab, you may want to specify a folder name to checkout to.

        2.  Switch the current directory to the v2_1 branch.
        Right click the directory and select CVS->Update Special.
        Select Get Tag/Branch/Revision and enter v2_1. Click OK.

        If you use WinCVS or the command line you'll have to check the documentation. I can't remember the branch syntax off the top of my head.

        - Richard

         
    • Nobody/Anonymous

      I have an error when I use Tortoise:

      cvs [server aborted]: "import" requires write access to the repository

       
      • Richard Banks

        Richard Banks - 2005-04-12

        Import is the wrong CVS function.  I'd say you clicked on  the "CVS->Make New Module..." menu item.

        You should be using checkout or update special.

        Right click on a directory in windows explorer and you will see some CVS shell extensions provided by Tortoise.  If the directory does not currently hold a CVS based project in it then there should be an option called "CVS Checkout...".

        If the directory does hold a project (ie it's the directory you currently have the framework in) then the commands will be something like "CVS Update", "CVS Edit", "CVS Commit", "CVS Add Contents..." and a CVS submenu.

        In the submenu is an option for "Update Special".

        Select one of these options and proceed as described earlier.  If you really get stuck I'll put together some pictures to describe it better.

         
    • Nobody/Anonymous

      If I execute CVS Checkout, I have a following error:

      In C:\: "C:\Archivos de programa\TortoiseCVS\cvs.exe" "-q" "checkout" "-P" "jcframework"
      CVSROOT=:pserver:anonymous@cvs.sourceforge.net:/cvsroot/jcframework

      cvs.exe checkout: Empty password used - try 'cvs login' with a real password

      cvs.exe checkout: in directory .:
      cvs.exe checkout: cannot open CVS/Entries for reading: No such file or directory

      Success, CVS operation completed

       
      • Richard Banks

        Richard Banks - 2005-04-13

        Could be a temporary CVS issue..  I just tried using public CVS and got the following:

        In C:\Projects\Sourceforge: "C:\Program Files\TortoiseCVS\cvs.exe" "-q" "checkout" "-d" "ttt" "-P" "dotnet"
        CVSROOT=:pserver:anonymous@cvs.sf.net:/cvsroot/jcframework

        cvs checkout: Empty password used - try 'cvs login' with a real password

        U ttt/AFCustomAttributes.vb
        U ttt/AFExceptions.vb
        U ttt/AToMSFramework.sln

        The only difference is I used cvs.sf.net instead of cvs.sourceforge.net.  I don't think that makes much difference though.

         
    • Nobody/Anonymous

      hi.

      Excuseme but it is bad

      In C:\jcframework: "C:\Archivos de programa\TortoiseCVS\cvs.exe" "-q" "checkout" "-P" "jcframework"
      CVSROOT=:pserver:anonymous@cvs.sf.net:/cvsroot/jcframework

      cvs.exe checkout: Empty password used - try 'cvs login' with a real password

      cvs.exe checkout: in directory .:
      cvs.exe checkout: cannot open CVS/Entries for reading: No such file or directory

      Success, CVS operation completed

       
    • Nobody/Anonymous

      OK.

      I use:

      In C:\: "C:\Archivos de programa\TortoiseCVS\cvs.exe" "-q" "checkout" "-P" "dotnet"
      CVSROOT=:pserver:anonymous@cvs.sf.net:/cvsroot/jcframework

      cvs.exe checkout: Empty password used - try 'cvs login' with a real password

      U dotnet/AFCustomAttributes.vb
      U dotnet/AFExceptions.vb
      U dotnet/AToMSFramework.sln
      U dotnet/AToMSFramework.vbproj
      U dotnet/AssemblyInfo.vb
      U dotnet/AtomsFramework.ndoc
      U dotnet/AtomsFramework.snk
      U dotnet/AtomsFramework.xml
      U dotnet/CAssociationKey.vb
      U dotnet/CAssociationObject.vb
      U dotnet/CAssociationState.vb
      U dotnet/CAssociationTa
      ....................

       
      • Richard Banks

        Richard Banks - 2005-04-13

        A-hah!!

        I see what your problem was the first time

        You command TortoiseCVS output was
        In C:\jcframework: "C:\Archivos de programa\TortoiseCVS\cvs.exe" "-q" "checkout"
        "-P" "jcframework"
        CVSROOT=:pserver:anonymous@cvs.sf.net:/cvsroot/jcframework

        In the CVS.exe line you can see the last parameter was "jcframework".  This indicates that the module name you were trying to checkout was set to jcframework - but there is no jcframework module in CVS so you get the error

        The one you did that worked you set the module name to "dotnet" which is a module that does exist and is why things worked.

        I don't know why I didn't see it before.  Probably due to being half asleep when I was looking at the message :-)

        I'm glad it's all working now.

        - Richard.

         

Log in to post a comment.