Backendless Support
 
Solved

SDK creates additional columns

Currently I have NDevice object with fields. One of them is digit_it.

After every new creation of NDevice and saving to the backend it creates additional fields: digitId and notEmpty

Please look at the screenshot.

I have no any place in my code where I'm change this field name or add notEmpty.

How to prevent creation of unknown fields?

  1. protected Integer updateDevices(final BackendlessUser user) {

    List<NDevice> devices = new ArrayList<>();

    .........

    for (NDevice device : devices)

    if (TextUtils.isEmpty(device.getObjectId())) {

    NDevice savedDevice = Backendless.Persistence.of(NDevice.class).save(device);

    }

    Integer result = null;

    if (ListUtil.isNotEmpty(devices))

    result = Backendless.Persistence.of(BackendlessUser.class).setRelation(user, Consts.DEVICES, devices);

    return result;

    }

  1. public class NDevice implements Serializable {

    public String android_id;

    public String gcm_token;

    public String model;

    public String digit_id;

    private String objectId;

    private java.util.Date created;

    private java.util.Date updated;

    public String androidId() {

    return android_id;

    }

    public void setAndroId(String androidId) {

    this.android_id = androidId;

    }

    public String gcmToken() {

    return gcm_token;

    }

    public void setGcmToken(String gcmToken) {

    this.gcm_token = gcmToken;

    }

    public String model() {

    return model;

    }

    public void setModel(String model) {

    this.model = model;

    }

    public long digitId() {

    long digitId = 0;

    if (!TextUtils.isEmpty(digit_id)) {

    try {

    digitId = Long.parseLong(digit_id);

    } catch (Throwable throwable){

    throwable.printStackTrace();

    }

    }

    return digitId;

    }

    public String getDigitId() {

    return digit_id;

    }

    public void setDigitId(long digitId) {

    if (digitId != Consts.NONE_LONG)

    this.digit_id = String.valueOf(digitId);

    }

    /**

    * Methods

    */

    public NDevice create() {

    android_id = TechUtil.getAndroidId();

    model = TechUtil.getDeviceModel();

    return this;

    }

    public boolean isNotEmpty() {

    boolean isNotEmpty = gcm_token != null && android_id != null && digit_id != null;

    return isNotEmpty;

    }

    public static NDevice update(NDevice device) {

    device.setAndroId(NUser.i().device().androidId());

    device.setGcmToken(NUser.i().device().gcmToken());

    device.setModel(NUser.i().device().model());

    device.setDigitId(NUser.i().device().digitId());

    return device;

    }

    @Override

    public int hashCode() {

    return 31 * android_id.hashCode();

    }

    @Override

    public boolean equals(Object obj) {

    if (this == obj)

    return true;

    if (obj == null || !(obj instanceof NDevice))

    return false;

    NDevice device = (NDevice) obj;

    return android_id.equalsIgnoreCase(device.android_id);

    }

    public String getAndroid_id() {

    return android_id;

    }

    public void setAndroid_id(String android_id) {

    this.android_id = android_id;

    }

    public String getGcm_token() {

    return gcm_token;

    }

    public void setGcm_token(String gcm_token) {

    this.gcm_token = gcm_token;

    }

    public String getModel() {

    return model;

    }

    public String getDigit_id() {

    return digit_id;

    }

    public void setDigit_id(String digit_id) {

    this.digit_id = digit_id;

    }

    public String getObjectId() {

    return objectId;

    }

    public void setObjectId(String objectId) {

    this.objectId = objectId;

    }

    public Date getCreated() {

    return created;

    }

    public void setCreated(Date created) {

    this.created = created;

    }

    public Date getUpdated() {

    return updated;

    }

    public void setUpdated(Date updated) {

    this.updated = updated;

    }

    }

I want to move update of my app to google play, but I can't because I have a lot of issues with v.4

Please help.

Leave a Comment

Comments (8)

photo
1

Hi Oleg,

I think I see what causes the problem, but it will take a few days to make a fix for that. The additional column names are created from the names of the getters. As a quicker workaround you could just rename the fields and columns in Data Tables: digit_id -> digitId etc. Is it possible for you to do that?

photo
1

Hi Sergey,

Thank you for reply. It's very important for me. I will wait for fix. And I can't rename any field name, because I use them on another services.

Please let me know when you finish.

Have a nice day!

photo
photo
1

What if you disable the dynamic schema option in console? It will prevent fields being created on the fly.

photo
1

In this case I've got next fault:

BackendlessException{ code: '1169', message: 'Dynamic schema definition is disabled for this application' }

Without any saved data.

photo
photo
1

Try adding the following class annotation, it goes right before the class definition:

import weborb.service.ExcludeProperties;

@ExcludeProperties( propertyNames = {"digitId", "notEmpty"})

photo
1

Works like a charm! Thanks Mark.

photo
photo
1

Hi Oleg,

I've investigated your class a bit and here is what happening: our SDK treat each Java Bean property as a field (column), e.g. all public fields AND also all getters, which are methods with name starting with 'get' or 'is'. In your case, you have methods 'getDigitId' and 'isNotEmpty', thus the columns are created.

One solution would be to exclude there 'properties' via annotation, as Mark suggested.

But I suppose it would be more logical for you to just get rid of the 'getDigitId' method (since its duplicated by 'getDigit_id' one), and rename 'isNotEmpty' method to something not starting with 'get' or 'is' (merely 'notEmpty' for example).

Hope this clarified the situation for you!

photo
1

Hi Sergey,

Sounds good. Thank you for your explanation and help.

photo