0

I have made a POC Android App to test this behaviour.

Looks like Loopback's Android SDK is not recognizing the Id field of a model in some operations.

I have written a basic operation to delete a record on a MySQL DB. First I gather an object I know exists in the table "findById" and I call the destroy() method in the onSuccess callback. The destroy() method returns an Internal Server Error Exception.

This is my model class code loopbackpoc-booking.json:

{
  "name": "loopbackpocBooking",
  "base": "PersistedModel",
  **"idInjection": false**,
  "mysql": {
    "schema": "loopback_poc",
    "table": "loopbackPOC_bookings"
  },
  "properties": {
    "bookBoSync": {
      "type": "Number",
      "required": false,
      "length": null,
      "precision": 3,
      "scale": 0,
      "mysql": {
        "columnName": "book_bo_sync",
        "dataType": "tinyint",
        "dataLength": null,
        "dataPrecision": 3,
        "dataScale": 0,
        "nullable": "Y"
      },
      "_selectable": true
    },
    "bookCdBooking": {
      "type": "Number",
      **"id": true**,
      "required": true,
      "length": null,
      "precision": 10,
      "scale": 0,
      "mysql": {
        "columnName": "book_cd_booking",
        "dataType": "int",
        "dataLength": null,
        "dataPrecision": 10,
        "dataScale": 0,
        "nullable": "N"
      },
      "_selectable": false
    },
    "bookCdItinerary": {
      "type": "Number",
      "required": true,
      "length": null,
      "precision": 10,
      "scale": 0,
      "mysql": {
        "columnName": "book_cd_itinerary",
        "dataType": "int",
        "dataLength": null,
        "dataPrecision": 10,
        "dataScale": 0,
        "nullable": "N"
      },
      "_selectable": false
    },
    "bookDtSync": {
      "type": "Date",
      "required": false,
      "length": null,
      "precision": null,
      "scale": null,
      "mysql": {
        "columnName": "book_dt_sync",
        "dataType": "datetime",
        "dataLength": null,
        "dataPrecision": null,
        "dataScale": null,
        "nullable": "Y"
      },
      "_selectable": true
    },
    "bookNrAmount": {
      "type": "Number",
      "required": false,
      "length": null,
      "precision": 22,
      "scale": null,
      "mysql": {
        "columnName": "book_nr_amount",
        "dataType": "double",
        "dataLength": null,
        "dataPrecision": 22,
        "dataScale": null,
        "nullable": "Y"
      },
      "_selectable": true
    }
  },
  "validations": [],
  "relations": {},
  "acls": [],
  "methods": []
}

Model class (BookingPOCModel.java)

public class BookingPOCModel extends Model {

    protected int bookCdBooking;
    protected int bookCdItinerary;
    protected double bookNrAmount;
    protected Boolean bookBoSync;
    protected String bookDtSync;

    public int getBookCdBooking() {
        return bookCdBooking;
    }

    public void setBookCdBooking(int bookCdBooking) {
        this.bookCdBooking = bookCdBooking;
    }

    public int getBookCdItinerary() {
        return bookCdItinerary;
    }

    public void setBookCdItinerary(int bookCdItinerary) {
        this.bookCdItinerary = bookCdItinerary;
    }

    public double getBookNrAmount() {
        return bookNrAmount;
    }

    public void setBookNrAmount(double bookNrAmount) {
        this.bookNrAmount = bookNrAmount;
    }

    public Boolean getBookBoSync() {
        return bookBoSync;
    }

    public void setBookBoSync(Boolean bookBoSync) {
        this.bookBoSync = bookBoSync;
    }

    public String getBookDtSync() {
        return bookDtSync;
    }

    public void setBookDtSync(String bookDtSync) {
        this.bookDtSync = bookDtSync;
    }
}

And the interesting code in the activity:

private void deleteData(final RestAdapter adapter, BookingPOCRepository repository) {
    repository.findById(28, new ObjectCallback<BookingPOCModel>() {
        @Override
        public void onSuccess(final BookingPOCModel object) {
            Log.i("findById", "Got object ID: " + object.getBookCdBooking());
            object.destroy(new VoidCallback() {
                @Override
                public void onSuccess() {
                    Log.i("deleteData", "Deleted object ID: " + object.getBookCdBooking());
                }

                @Override
                public void onError(Throwable t) {
                    Log.e("deleteData", "Failed to delete object ID: " + object.getBookCdBooking() + " - " + t);
                }
            });
        }

        @Override
        public void onError(Throwable t) {
            Log.e("findById", "Couldn't get object.");
        }
    });
}

I know for sure there is a record in the database with "bookCdBooking": 28. This field is the one identified as "id" in the model. The model is correctly gathered from the DB but the 500 error is returned when I call the destroy() method.

I have debugged to see the URL actually generated on the call and I got this:

http://192.168.1.10:3000/api/loopbackpocBookings/null?bookDtSync=null&id=null&bookBoSync=null&bookNrAmount=100.0&bookCdItinerary=1&bookCdBooking=28

Notice the null where the Id should be?

I have checked the model object that I got from the DB (named "object" in the code) and the "id" property is null. I wonder if this has something to do with the issue.

enter image description here

Still pending to investigate but it seems this problem also happens when using the save() method to update an existing model.

Any ideas?

  • Try setting "is id" on the actual key column from arc. You can do it in loopbackpoc-booking.json also, but I don't know the exact property name. – Geoffrey Burdett Apr 07 '15 at 20:52
  • That setting in arc changes the "id": true/false property in the JSON model definition. It is already set to true for the correct column, which is "bookCdBooking", as you can see in the code attached in the question. – José Luis Gallego Apr 07 '15 at 21:15

0 Answers0