Backendless Support
 
Solved

Using Business Logic Feature to limit number of objects in related tables on update of parent table

My Users table has a column pointing to a relation with another table for whose objects are inserted after calling Backendless.UserService.update on the Users table for the logged in User. Adding Event Handlers on the Data Tables category with a beforeUpdate timer does not seem to work, my guess is because the update is on the parent table(Users). I would like to limit the number of entries in the related table to say 1 entry, the existing entry being replaced each time the logged in user calls an update on the Users table targeting the 1:1 related table.

I am using Coderunner with IntelliJ to add the event handler in the Data Tables category which, as i have said before does not work.

Much appreciated.

Much appreciated.

Leave a Comment

Comments (10)

photo
1

Adding an event handler to the the Users table category results in the below. I specifically would like to get the number of objects in the related table from the below business logic generated code

  1. public class GenericUserEventHandler extends com.backendless.servercode.extension.UserExtender
  2. {
  3. @Async
  4. @Override
  5. public void beforeUpdate( RunnerContext context, HashMap userValues ) throws Exception {
  6. // add your code here
  7. System.out.println("Related table object inserted.........");
  8. }
  9. }

I am able to get the println in the coderunner window.

photo
1

Hello!

I'm not sure that I understand your case. So, you have table "Related". There is a relation 1:1 from "Users" to "Related". You want to have only one row in "Related" table and update it each time "Users" object is updated. And all your "Users" point the same "Related" object.

Am I right?

photo
1

Alexandr, yes. That's correct.

This is where am updating the Users table.

  1. // I have saved current logged in user objectId in shared preferences
  2. // so retrieving it
  3. String currentUserId = Utils.getCurrentUserId(getContext());
  4. if (!currentUserId.equals("")) {
  5. Backendless.UserService.findById(currentUserId, new DefaultCallback<BackendlessUser>(getContext()) {
  6. @Override
  7. public void handleResponse(BackendlessUser currentUser) {
  8. Related related = new Related();
  9. related.eyeColor = mEyeColor.getText.toString;
  10. related.hairColor = mHairColor.getText().toString();
  11. currentUser.setProperty("related", related); // creating the Related table with a 1:1 relationship
  12. Backendless.UserService.update(currentUser, new DefaultCallback<BackendlessUser>(getContext()) {
  13. @Override
  14. public void handleResponse(BackendlessUser response) {
  15. }
  16. @Override
  17. public void handleFault(BackendlessFault fault) {
  18. }
  19. });
  20. super.handleResponse(currentUser);
  21. }
  22. @Override
  23. public void handleFault(BackendlessFault fault) {
  24. }
  25. });

photo
1

In order to prevent creating related object - retrieve parent object together with the related object. Use the following "findById" signature:

  1. public void findById(String id, int relationsDepth, AsyncCallback<Map> responder)

Then inside responder check if the retrieved User already has "related" object. If it does - update it, otherwise create new one.

So, your code would look something like this:

  1. Backendless.Data.of(BackendlessUser.class).findById("usersObjectId", 1, new AsyncCallback<BackendlessUser>{
  2. @Override
  3. public void handleResponse(BackendlessUser user) {
  4. Related related = user.getProperty("related");
  5. if(related == null)
  6. related = new Related();
  7. related.setPropertyOne("value");
  8. related.setPropertyTwo("value");
  9. user.setProperty("related", related);
  10. Backendless.UserService.update(user, new AsyncCallback<BackendlessUser>) {
  11. ........ and so on
  12. }
  13. // handling fault
  14. });

Here you do not need to use any custom business logic. Please, try this approach.

regards,

Alex

photo
1

I am able to check the existence of related object in the below line

  1. Related related = user.getProperty("related"); // this returns an object

and create a new one if the below line returns true

  1. if(related == null) // true or false

but unable to update the returned related object if the above line returns false.

To update it i am calling

  1. Backendless.Persistence.of(Related.class).save(related, new AsyncCallback<Related>() {
  2. @Override
  3. public void handleResponse(Related response) {
  4. }
  5. }@Override
  6. public void handleFault(BackendlessFault fault) {
  7. }

the above creates a new object in the Related table without an objectId.

photo
1

Maybe for case if "related" is null you'd retrieve the "Related" object directly from table "Related" using, for example, "findFirst" method?

As I understand, table "Related" contains only one object in your app, so it should work.

photo
1

How to update the retrieved object?

photo
photo
1

Use "save" method. If object contains objectId - it would be updated, otherwise - created.

photo
1

Bravo. Works perfect with save method. Thank you very much Alexandr.

Just a small related issue; one of my model classes that has been working fine creating 1:N relations with the Users table is suddenly giving me "wrong schema" error. I notice the returned class name mysteriously has a $1 appended at the end. What could i have broken? I know i am probably supposed to raise another ticket for this, but please please, just a pointer to what could have gone wrong. I have tried deleting and coding the class afresh but nothing, other classes in the app are working fine, and everything done the same.

photo
1

It's better to open a separate topic for this issue, it needs investigation.

Please, describe steps to reproduce and put there your application id.

photo