cancel
Showing results for 
Search instead for 
Did you mean: 

Synchronization parameter not filtering the records from SUP

Former Member
0 Kudos

Business Scenario :

     There are 2 or more project in a company and n-number of people working in any of them. Each project is given a project ID. Now in my iOS application i need to fetch the employees of the specific project and display them in form of a table structured details.

Concern :

     For this i had been provided a GC with a Synchronization Parameter. I set this parameter with the project ID (details of the employee under the Project ID) and later SYNC the group with SUP.

     Even after setting this Sync Param, i get all the records from the SUP (Employees from all Projects) . 

Code Snippet used :

                    CHECK_IN_DATASubscription *test = [CHECK_IN_DATASubscription new];

                    [test setProject_SP:[TKSettingsStorage stringForKey:@"ProjectID"]]; // @"00038"

                    [CHECK_IN_DATA addSubscription:test];

                

                    [DB synchronize:@"CheckInSynchGroup"];

    The findAll call after this is not the filtered records. Not sure if it's a issue with Generated Code or my iOS client code.

Can anyone help me out in getting me this work. I am using SUP 2.2.

Accepted Solutions (0)

Answers (2)

Answers (2)

DoanManhQuynh
Active Contributor
0 Kudos

Ok, I have done 2 scenriano, they work fine:

1. Load argument mapped with sychronization parameter + no personalization parameter:

<yourMbo>SynchronizationParameters *sp = <yourMbo>SynchronizationParameters alloc] init];         sp.<synckey> = value;

[sp save];

[<yourMbo>DB synchronize];

[<yourMbo>DB closeConnection]; // release connection

2. Load argument mapped with personalization parameter + no synchronization parameter:

PersonalizationParameters pp = new PersonalizationParameters();

pp.<perkey> = value;

pp.Save();

<yourMbo>DB.Synchronize();


When I develope app in .net, I were tried to use bot of parameter and i used to got the same error like you, no data return even preview work well. maybe you could try one of these scenriano. Good luck

Former Member
0 Kudos

Hi Quynh,

We have other applications which work in both the ways you have mentioned. Only in one application we are facing this unique issue, where cache is getting filled with the right data, but the findAll returns wrong result.

Regards,

Aparnna Prasad

Former Member
0 Kudos

Hi Aparnna,

Find all is a query on your device database. So  if you are using synchronization parameters the data fetched by all inputs of your synchronization parameters will remain on your device database and so in findAll object query you will get all the records .

In case you are using personalization parameters then the old data is deleted and new data is fetched. So in FindAll object query you will return only the last sync records.

Hope this helps.

Regards.

Anjali.

DoanManhQuynh
Active Contributor
0 Kudos

you said:

"Currently, Personalization key is mapped to Load parameter.  There is a synchronization parameter mapped to MBO attribute PROJECT"

I understand that mean you map sychronization like this


and load arguments like this:

Then it's different with mine...

1. have you try to use personalization parameter only? and make sure PK's store properties = transit?

2. have you try to set your own query?

Former Member
0 Kudos

Hi Quynh,

Thank you for the details.

Please find answers for the Questions you asked below:

1. We tried with Personalization key only, Store property is Transient. - The cache was filled with the right data. But Device had more records which not present in cache. When things were not working with a Synch Param, I started checking with personalization key

2. We tried with our own query. It is working.

My understanding is this: Once a synch call is finished successfully, the device database should have only those records which are matching the filter criteria. (In our case PK or Synch Param is mapped to load parameter). 

Please correct if my understanding is wrong.

Regards,

Aparnna Prasad

Former Member
0 Kudos

Hi Quynh,

Adding to Aparnna comments above , below are additional details :

    NOTE  : We are using the Synchronization Parameter mapped to Load Parameter.

The Cache table has 3 records (2 from 0038 and 1 from 0035 for example) . The payload log from SUP showed only 2 intended records. But the findAll call on the client gives out all the 3 records and the one which was not the records as in the response payload.

DoanManhQuynh
Active Contributor
0 Kudos

Hi Aparnna.

Yes, data on clent side should have only records that filter with your key as my knowledge too.What I said above just for make sure and maybe help you in some advice. Now as you said, cacheDB work fine => PK work fine => your synchronize fine.then the problem here is device database or the generate query "findAll" from sybase.

1. Have you tried to delete device database and re-create it to make sure no old data remain, like this:

if (yourDB.DatabaseExists())

{

yourDB.DeleteDatabase();

yourDB.CreateDatabase();

}

If you want to check client database, you could follow this link:

http://scn.sap.com/community/developer-center/mobility-platform/blog/2013/04/29/how-to-accessread-de...

2.With query: me ideal is create a new query under Attributes/Objectqueries tab in workspace like this:

the point here is try to make a new query, change return type to recheck. If you success in your own query then maybe there are some mysteries here and i dont know why too,

Some of my ideal... .

Former Member
0 Kudos

Hi Quynh,

I had read the below comment in SUP101 sample project :

  

"Normally you would not delete the local database. For this simple example, though, deleting and creating an empty database will cause all data to be sent from the server, and we can use [CallbackHandler onImportSuccess:] to know when to proceed."

Thus i was doing something as below during an MBO initialization :

 

     SUPConnectionProfile *cp = [ConcostTimeKeepingDB getConnectionProfile];


     if(![DB databaseExists]) {

           

            [DB createDatabase];

           

            [cp.syncProfile setDomainName:@"default"];

            [cp enableTrace:YES];

            [cp.syncProfile enableTrace:YES];

           

            [DB generateEncryptionKey];

            [timeKeepingVault setString:@"encryptionkey" withValue:[cp getEncryptionKey]];

            [TKSettingsStorage setString:[cp getEncryptionKey] forKey:@"EncryptionKeyForDB"];

           

        }

       

        NSString *key = [TKSettingsStorage stringForKey:@"EncryptionKeyForDB"];

        NSLog(@"Got the encryption key: %@",key);

        [cp setEncryptionKey:key];

        [cp setCacheSize:102400];

Now after recreating a DB every-time , we might have solved our issue here. Is it good to recreate a DB on every run ?

DoanManhQuynh
Active Contributor
0 Kudos

In normal case,device DB and cache DB would be have the same records. We dont need to recreate device database, this DB is for offline mode, base on my knowledge, then if you dont have this mode i think recreate it have no problem.anyway, this is not a best practice, just a workaround for your issue and i think you should try some another solutions to find out exactly what is going on unless you satisfied with this solution .

Former Member
0 Kudos

Thanks Quyhn and other for your help.

Re-creating the DB every-time solved this issue. Not sure if its correct, untill i have a better solution this is a best one .

Former Member
0 Kudos

Hi,

What I can see is you are not deleting the synchronization key before setting a new one.

So what it will do is it will get you records for the current as well as previously set synchronization key values.

So as per your requirement, delete the synchronization key before setting a new one in your iOS code.

As well as please check if the Synchronization Key is mapped to the Project Id in SUP Model.

If not, it will always return you whatever records are available in CDB for your particular MBO.

Regards,

Dharmaraj Patil.

Former Member
0 Kudos

Dharmaraj,

Thanks a lot for your reply.

I had even tried by calling a delete method on a Synchronization Parameter before setting a New Value during SUP 2.1.3 . It didn't work. (All records kept flowing into the device) .

After SUP Upgrade to 2.2, i now even tried using process of removing a synchronization parameter , below is the snippet :

    

CHECK_IN_DATASubscription *test = [CHECK_IN_DATASubscription new];

                    SUPObjectList* r = [CHECK_IN_DATA getSubscriptions];

                    ConcostCHECK_IN_DATASubscription* sub = (ConcostCHECK_IN_DATASubscription*)[r item:0];

                    [ConcostCHECK_IN_DATA removeSubscription:sub];

                    [test setProject_SP:[TKSettingsStorage stringForKey:@"ProjectID"]];

                    [ConcostCHECK_IN_DATA addSubscription:test];

                    [DB synchronize:@"CheckInSynchGroup"];

Even this gives all the records and not the filtered (based on the ProjectID) records. Also, Synchronization Key is mapped to the Project Id in SUP Model - Cross Checked.

My WorkAround : I tried writing a Dynamic Query to check the results, i did get the intended (filtered) records in the QueryResultSet. But we here feel its a big loophole in using this DynamicQuery as it impacts the application performance when there are more records.

Is there anything else that you can figure out from these info.

midhun_vp
Active Contributor
0 Kudos

Specifying Synchronization Parameters

Use synchronization parameters within the mobile application to download filtered MBO data.

Assign the synchronization parameters of an MBO before a synchronization session. The next synchronize sends the updated synchronization parameters to the server. The SynchronizationParameters class is within the generated code for your project.

Note: If you do not save the SynchronizationParameters, no data is downloaded to the device even if there are default values set for those SynchronizationParameters. Call the save method for all SynchronizationParameters and for all MBOs when the application is first started. Do this after application registration and the first synchronization. This only applies to non-DOE-based applications.

  1. Retrieve the synchronization parameters object from the MBO instance. For example, if you have an MBO named Customer, the synchronization parameters object is accessed as a public field and returned as a CustomerSynchronizationParameters object:CustomerSynchronizationParameters *sp = [Customer getSynchronizationParameters];
  2. Assign values to the synchronization parameter. For example, if the Customer MBO contains a parameter named cityname, assign the value to theCustomerSynchronizationParameters object's cityname field:sp.cityname = @"Kansas City";
  3. Save your changes by calling the synchronization parameters object's save method:[sp save];

    Note: If you defined a default value or bound a PersonalizationParameters in the SynchronizationParameters, then that value will not take effect unless you callsp.save().

  4. When using synchronization parameters to retrieve data from an MBO during a synchronization session, clear the previous synchronization parameter values:

    [params delete]; <MBO>SynchronizationParameters *params = [<MBO> getSynchronizationParameters]; //must re-get the sync parameter instance params.Param1 = @value1; //set new sync parameter value params.Param2 = @value2; //set new sync parameter value [params save];

    What is the cache group you are using?

    Is there any load parameter for the MBO? Are you passing personalization key as load parameter or sync key as load parameter?

    -Midhun VP

Former Member
0 Kudos

Midhun,

Firstly, i had used a same approach over using the Synchronization Parameter in SUP 2.1.3 . Below is the snippet :

CHECK_IN_DATASynchronizationParameters *test = [CHECK_IN_DATA getSynchronizationParameters];

[test delete];

[test setProject_SP:[TKSettingsStorage stringForKey:@"ProjectID"]];

[test save];

[DB synchronize:@"CheckInSynchGroup"];

Even this didn't work for me earlier. i.e the records obtained were not filtered with Project_ID.

Since the SUP is now upgraded to 2.2 i am using the code shared earlier for dataSubscription.

Answering to your question :

What is the cache group you are using?  -------- We are using the On-Demand Cache policy.

Is there any load parameter for the MBO? Are you passing personalization key as load parameter or sync key as load parameter? -------- No (for all questions).

Do you have any comments over these information shared now?

DoanManhQuynh
Active Contributor
0 Kudos

If you dont pass sync parameter as load parameter so how could you pass the project Id to sup to trigge MBO?

Former Member
0 Kudos

Quynh,

We have added a Personalization parameter which is mapped to the load parameter. Issue is still the same, record filtration is not happening.

Observation :

Client :  The PersonalizationParameters in the Generated Code are set to the project id , saved and then called Synchronization on a particular Group. Snippet below

    

       PersonalizationParameters *testPK = [DB getPersonalizationParameters];

       testPK.ProjectINPK = [TKSettingsStorage stringForKey:@"ProjectID"];

      [testPK save];

      DB synchronize:@"CheckInSynchGroup"];

Synchronization call gives out allt he records and not the filtered ones.


SUP : It was observed that the cache is having a filtered data based on the ProjectID assigned to the employee , but after the Synchronization call from iPhone the findAll receives all the records irrespective of projectID assignment.

Is it something that the Cache data in SUP is not getting replicated on to the device DB on Synchronization (findAll will always fetch data from the local DB, right?). Is it something related to the libsupUltralite library file been used ?

DoanManhQuynh
Active Contributor
0 Kudos

Hi Shri Harsha.

Im sure that if you pass correctly parameter, the Mbo will work and filter data as your key passed. You can check your Mbo by "preview" function in your workspace to make sure this.Other hand, have you check your logic in backend? if you call bapi from SAP, I think you should check the BAPI too.Cause i dont know which scenario you are trying, I have this link could help you more clear about sychronize and personel parameter:

http://scn.sap.com/docs/DOC-36422#comment-343594

http://www.sdn.sap.com/irj/scn/go/portal/prtroot/docs/library/uuid/c08b163e-495e-3010-4a92-d0b96472c...

hope this help .

Former Member
0 Kudos

Quynh,

1) Its parameters are passed on correctly to SUP. Tested and confirmed from SUP end.

2) MBO preview puts out correct output with filtered records.

3) BAPI call also works fine.

Scenario Explained :

  • We have 2 projects in a company. 0038 and 0035 (Project ID's).
  • Employees are to be Checked-in to the respective project assigned to them.
  • When the manager is logging into the App and enters the Project ID , records in the table must be only with the employees Checked-in with the entered Project ID. (Now we are gettin the un-filtered records from both the Project ID's).

Checked with the link you shared, it was very helpful. We are still unable to resolve this filtering of records. Is there anything else you wanted us to check.?

midhun_vp
Active Contributor
0 Kudos

What is the cache policy of the MBO ?

Can you please give the screen shot of the properties of the MBO where you configured the syc keys.

DoanManhQuynh
Active Contributor
0 Kudos

Hi Shri Harsha.

Please make sure your cache group policy is partition by requester and device identity, this policy usually automatic but recheck it. Another han, have you tried to use self-define queries? uncheck "generate findAll query" and add your own under Attribute/Object Queries.

Incase of our app, we use synchronize parameter mapped with load arguments without using personel parameter and it work fine.Maybe you should give some screenshot like Midhun said .

Former Member
0 Kudos

Hi Quynh,

A few additions/corrections to the details provided by Harsha :

1. We are facing this issue in Database MBO. MBO's based on BAPI's are working fine.

2. I tried different options like - mapping synch parameter to the load parameter. Cache group policy was partition by requester and device identity. Now I have changed it.

3. Currently, Personalization key is mapped to Load parameter.  There is a synchronization parameter mapped to MBO attribute PROJECT

When we check in the cache after a synch call, I see that the cache is filled with data based on the value set in the Personalization key. But when the findAll query is triggered from the iOS code, it either shows 0 records or some other records which is not in cache.

MBO query definition is similar to the one given below

SELECT FNAME, LNAME, CHECKINTIME, PROJECT FROM TESTDB.TABLE1 WHERE TABLE1.PROJECT = :Project

MBO preview works fine.

Please revert if you want more details.

Regards,

Aparnna Prasad

Former Member
0 Kudos

Hi Aparnna,

     If you are mapping the load arguments and  personalization parameter i.e. the project id  in your case and the cache policy is on demand with zero cache interval then you only pass the project id in personalization parameter and synchronize your MBO.

     Then, you can use the find all object query which will return the objects with your specific Project ID. You don't need to set synchronization parameters for filtering because Personalization parameters deletes the last fetched results and load it with fresh data in your cache database as well your device database when you synchronize.

Hopes this helps.

Former Member
0 Kudos

Rather than using dynamic query make use of predicates in this case it can filter lakhs of records in seconds.

Regards,

Goutham.