5 Replies Latest reply on Oct 11, 2006 10:08 AM by T._Ruggles

    Deleting items from FDS arraycollection

    RuiRosao Level 1
      Hi all,

      I have an ArrayCollection that has been filled by a DataService from a DB and displayed in a datagrid. I can create update and delete single items in the DB.
      When I try to delete multiple items (e.g. in a for loop), I will end up with only a few deleted items (about half of them) both in the DB and in the datagrid . I think this has to do with the asynchronous nature of FDS, but I cannot figure out how to solve this through a result-handler.

      Any suggestions are welcome.

      Rui
        • 1. Re: Deleting items from FDS arraycollection
          T._Ruggles Level 1
          Would you show your deletion code?
          • 2. Re: Deleting items from FDS arraycollection
            RuiRosao Level 1
            Hi Tom,

            This is the part of the code that concerns deletion (sorry: partly in dutch).
            Maybe I'm sending too much, plse let me know.
            FYI: prospects can have one or more acties.
            Thank you for (trying to) helping me out.

            Rui

            // Server-side
            // Just showing the minimum for understanding the problem

            // Class: Actie.java
            package nl.rosado;

            import java.sql.Date;

            public class Actie {

            private int actie_id;
            private int klant_id;
            private int vert_id;
            private String naam;
            private Date actie_invoerdatum;
            private Date actie_vervaldatum;
            private String actie_soort;
            private String omschrijving;
            private int prioriteit;
            private boolean afgehandeld;

            public Actie() {
            }
            public int getActie_id() {
            return actie_id;
            }
            public void setActie_id(int actie_id) {
            this.actie_id = actie_id;
            }
            // other getter and setters. They are OK

            .....

            // Class: ActieAssembler.java (package etc.OK)
            // Functions: getItem(),fill(),createItem(),updateItem() work OK
            //
            public void deleteItem(Object prevVersion) {
            ActieDAO dao = new ActieDAO();
            try {
            dao.delete((Actie)prevVersion);
            }
            catch (ConcurrencyException e) {
            int actieId = ((Actie)prevVersion).getActie_id();
            System.err.println("*** DataSyncException trying to delete actie_id=" + actieId);
            throw new DataSyncException(dao.getActie(actieId), null);
            }
            }

            .....

            // Class ActieDAO.java (package,etc. OK)
            // Other functions here (they are OK)
            //
            public void delete(Actie actie) throws DAOException, ConcurrencyException {
            Connection c = null;
            PreparedStatement ps = null;
            try {
            c = ConnectionHelper.getConnection("nl/test","db/test","test");
            ps = c.prepareStatement(
            "DELETE FROM test.actions"+
            " WHERE actie_id=? AND klant_id=? AND vert_id=? AND naam=?"+
            " AND actie_invoerdatum=? AND actie_vervaldatum=? AND actie_soort=?"+
            " AND omschrijving=? AND prioriteit=? AND afgehandeld=?"
            );
            ps.setInt(1, actie.getActie_id());
            ps.setInt(2, actie.getKlant_id());
            ps.setInt(3, actie.getVert_id());
            ps.setString(4, actie.getNaam());
            ps.setDate(5, actie.getActie_invoerdatum());
            ps.setDate(6, actie.getActie_vervaldatum());
            ps.setString(7, actie.getActie_soort());
            ps.setString(8, actie.getOmschrijving());
            ps.setInt(9, actie.getPrioriteit());
            ps.setBoolean(10, actie.isAfgehandeld());
            if (ps.executeUpdate() == 0) {
            throw new ConcurrencyException("Item not found");
            }
            }
            catch (SQLException e) {
            e.printStackTrace();
            throw new DAOException(e);
            }
            finally {
            ConnectionHelper.closeConnection(ps, c);
            }
            }

            .....

            // Client-side

            // Actie.as
            package nl.rosado
            {
            [Managed]
            [RemoteClass(alias="nl.rosado.Actie")]
            public class Actie {

            public var actie_id:int;
            public var klant_id:int;
            public var vert_id:int;
            public var naam:String = "";
            public var actie_invoerdatum:Date;
            public var actie_vervaldatum:Date;
            public var actie_soort:String = "";
            public var omschrijving:String = "";
            public var prioriteit:int;
            public var afgehandeld:Boolean;

            public function Actie() {
            }
            }

            }

            .....

            //Acties
            [Bindable]
            public var actiesList:ArrayCollection = new ArrayCollection();
            [Bindable]
            public var thisActie:Actie;
            public var dsActie:DataService;

            .....

            // In data-management-config.xml (included in services-config.xml):
            <destination id="actieService">
            <adapter ref="java-dao" />
            <properties>
            <source>nl.rosado.ActieAssembler</source>
            <scope>application</scope>
            <metadata>
            <identity property="actie_id"/>
            </metadata>
            <network>
            <session-timeout>20</session-timeout>
            <paging enabled="false" pageSize="10" />
            <throttle-inbound policy="ERROR" max-frequency="500"/>
            <throttle-outbound policy="REPLACE" max-frequency="500"/>
            </network>
            </properties>
            </destination>

            .....

            // Acties dataservice stuff
            dsActie = new DataService("actieService");
            dsActie.addEventListener(ResultEvent.RESULT,actieResultHandler);
            dsActie.addEventListener(FaultEvent.FAULT,faultHandler);
            dsActie.autoCommit = false;

            .....

            private function actieResultHandler(event:ResultEvent):void {
            setActieButtons(); // makes some buttons/visible or not
            CursorManager.removeBusyCursor();
            }

            .....

            private function faultHandler(event:FaultEvent):void {
            Alert.show(event.fault.faultString,"DMS Foutmelding");
            }

            .....

            // Delete the prospect, and all actions attached to this prospect
            private function prospectVerwijderen():void {
            if(dgProspects.selectedIndex == -1) {
            Alert.show("Selecteer eerst de prospect die u wilt verwijderen.","Verwijderen ...");
            return;
            }
            function deleteClickHandler(event:CloseEvent):void {
            if(event.detail!=Alert.YES)
            return;
            CursorManager.setBusyCursor();
            // Filter the 'acties' of this prospect for the 'acties' to delete
            function filterActies(item:Object):Boolean {
            var actie:Actie = item as Actie;
            if(( actie.vert_id==thisProspect.vert_id) &&
            (actie.klant_id==thisProspect.klant_id))
            return true;
            return false;
            }
            function unfilterActies(item:Object):Boolean {
            return true;
            }
            // delete 'acties' of this prospect
            var i:int;
            var myActie:Actie;
            actiesList.filterFunction = filterActies;
            actiesList.refresh();
            for(i=0;i<actiesList.length;i++) {
            myActie = actiesList.getItemAt(i) as Actie;
            if( myActie!=null )
            dsActie.deleteItem(myActie);
            // SYNCHRONISATION ??
            }
            dsActie.commit();
            actiesList.filterFunction = unfilterActies;
            actiesList.refresh();
            // Delete the prospect
            dsProspect.deleteItem(thisProspect);
            dsProspect.commit();

            setProspectButtons();
            CursorManager.removeBusyCursor();
            }
            Alert.yesLabel = "Ja";
            Alert.noLabel = "Nee";
            // Check if one wants to delete prospect and all his 'acties'
            Alert.show("Bevestig a.u.b. het verwijderen van prospect:\n"+thisProspect.naam+
            "\nAlle acties van "+thisProspect.naam+" worden ook verwijderd!",
            "Prospect verwijderen",Alert.YES|Alert.NO,this,deleteClickHandler,
            null,Alert.NO);
            }


            • 3. Re: Deleting items from FDS arraycollection
              T._Ruggles Level 1
              Ok, that's what I suspected. Your for loop is the culprit.

              for(i=0;i<actiesList.length;i++) {
              myActie = actiesList.getItemAt(i) as Actie;
              if( myActie!=null )
              dsActie.deleteItem(myActie);
              // SYNCHRONISATION ??
              }

              Consider a list of four items.
              0: first
              1: second
              2: third
              3: fourth

              First iteration you delete 0:first. When you get to the second iteration the list has shifted.
              0: second
              1: third
              2: fourth

              So when you getItemAt(1) you get third. What you need to do is either reverse the loop such that you go from high to low or just do getItemAt(0) until the list is empty.
              • 4. Re: Deleting items from FDS arraycollection
                RuiRosao Level 1
                Thank you Tom.
                I learned something I had not realised before. I thought that actiesList would only get updated *after* the dsActie.commit because I'm doing dsActie.deleteItem and not actiesList.removeItemAt.

                You really helped me out.
                Rui
                • 5. Re: Deleting items from FDS arraycollection
                  T._Ruggles Level 1
                  Np. Yeah, the change is made immediately on the client but the change message doesn't go to the server until you commit.