9 Replies Latest reply on May 8, 2007 4:29 PM by dimival

    Detecting changes made inside a fill method

    dimival Level 1
      Hello, i am having troubles when using DataServices in my app. Here's
      the thing:

      I have an Assembler and a DataService component that points to that Assembler. I have a Datagrid for showing a list of elements and a Form for inserting new one. The DataGrid is filled by pressing a button that calls the fill method of the Assembler.

      The type of object i am using has a property called winner that is a boolean and defaults to false, the fill method obtains a list of bids from the database and before the return statement, it iterates it to determine if each bid is a possible winner or not, setting the winner property to true or false. So each time the fill method is executed by the client or by a refreshFill it checks these conditions and determines possible winners.

      I call the fill method and the DG is filled with the result of the fill method, then i create a new Bid and fill it with the Form (the
      default value for winner is false) and then call the createItem method, which inserts it into the database and automatically triggers an refreshFill that once again obtains the list of bids and determines which one is a possible winner and which isn't.

      The problem is that if the recently added item is a possible winner i am setting its property to true but on Flex it remains as false. Additionally if any other bid that was already on the list changes its property from true to false or viceversa, Flex won't see these changes.
      Before the return statement of the fill method i am printing the values of the bids and there i see that the values of the winner property are in fact being done but on the DataGrid those changes don't occur :S.

      So the thing is that the refreshFill that is automatically triggered after the createItem is obtaining the right data but Flex just doesn't show it correctly.

      Any ideas? Please help!!!
        • 1. Re: Detecting changes made inside a fill method
          aBill Level 1

          Did you check the DataServiceTransaction API. I think you should push the new winner by using the update method

          William Chan
          • 2. Re: Detecting changes made inside a fill method
            dimival Level 1
            Thanks for replying, i have been trying to solve this for a week now. I found that changes made to items on the collection are not detected, only added or removed items, and as you mentioned, according to documentation, you should do an update but my question is how to do this? i mean where should i call the update, do you have an example? I have been trying this but no success :(

            If you have an example PLEASE PLEASE help me out
            • 3. Re: Detecting changes made inside a fill method
              aBill Level 1

              Suggest to have a previousWinner stored in your assembler, when there is an update, delete or create. Run your logic to determine who is the winner.

              public void pushNewWinner()
              Member previousWinner = winner;
              winner = findWinner();
              if (winner.id == previousWinner.id)
              DataServiceTransaction dst = DataServiceTransaction.begin(useJTA);
              String[] changedProperties = {"isWinner"};
              Member original = winner.clone();
              original.isWinner = false;
              winner.isWinner = true;
              dst.updateItem("Members", winner , original ,changedProperties);
              orignal = previousWinner.clone();
              previousWinner.isWinner = false;
              previousWinner.isWinner = true;
              dst.updateItem("Members", prevopisWinner , original ,changedProperties);


              You might need to try catch updates and dst.commit() infinally, catch exception to dst.setRollbackOnly();

              William Chan
              • 4. Re: Detecting changes made inside a fill method
                dimival Level 1
                Thanks a lot for replying, your example is being of help but i think you misunderstood my post and i still have some doubts.

                More than one item can be a winner, not just one, so i will have to call an update for each item.

                On my fill method i have something like this:

                public List fill(List fillParameters){
                List results = new ArrayList();
                results = dao.getBids();
                results = checkWinners(results); //this function checks each item and sets the winner porperty to true or false.
                return results;

                So when i call on Flex DataService.fill() it obtains the list of bids and each has its winner property to true or false. Then i insert a new item and the fill method is executed again (due to autoRefreshFill) and winner properties is set again but the updateCollection message only includes the new added item, it doesn't check for updates.

                So now, the real deal is where would i call the updateItem to push the changes? Should i call the updateItem inside the createItem function? on the refreshFill function? inside the fill function?

                I have checkWinners() function which is the one i call inside the fill function and that sets the winner property of each item, should i call the DataServiceTransaction.updateItem from there? I have my doubts because i am calling this function inside the fill method.

                So it all sums up in "where should i call the updateItem?"

                Thanks for you help, hope you can help me out with this last issue :)
                • 5. Re: Detecting changes made inside a fill method
                  aBill Level 1

                  I made a mistake in previous message. It should use the current transaction inside the create, since there is already a datatransaction.
                  DataServiceTransaction dt = DataServiceTransaction.getCurrentDataServiceTransaction();
                  You don't need to call commit in this case. I suggest to put the updates in the create when you don't want any update messages from regular fill.
                  Another solution create a message destination in the app, and use message handler to force other clients to refill

                  William Chan

                  William Chan
                  • 6. Re: Detecting changes made inside a fill method
                    dimival Level 1
                    I thought about putting the updateItem inside the createItem but the thing is how to access the managed list from there? i mean, is it possible to access a managed list from other place that is not the fill method?
                    • 7. Re: Detecting changes made inside a fill method
                      aBill Level 1

                      I think you can use org.apache.commons.collections.CollectionUtils. When you run your fill method, put all winners to a collection. At the end of the fill method compare lastWinnders collection by CollectionUtils.subtract(winners, lastWinner) if lastWinners collection is not null. You can get new winners. Then you use DataServiceTransaction to push the update by changing winner from false to true. Vice versa, CollectionUtils.subtract( lastWinner, winner) from true to false. After the updates pushed, assign lastWinners = winners. In this case, there is no updates push to clients if winners == lastWinners

                      William Chan
                      • 8. Re: Detecting changes made inside a fill method
                        aBill Level 1

                        Did you get it working? I found there is an issue where the submitted client didn't get update message. I think the workaround is the submitter refill after the result event. Would like to hear from you. Please free feel to email me if there is anything which I can help.

                        William Chan
                        • 9. Detecting changes made inside a fill method
                          dimival Level 1
                          Couldn't actually make it using the transaction.updateItem( ) method, so what i did was to refill on the submitter on the result event and then refill on the other clients on the message event. That seemed to work but i still wonder what could be the correct approach.

                          I did a sample using the Flex CRM Sample application, i can email it to you so you can check out for yourself what the real deal is, please let me know.