Backendless Support
 
Answered

Cannot save entity with primitive collection property users

Hi, I'm updating a table entity but it always gets in handleFault, the error is 'Cannot save an entity with primitive collection property users'. I have updated the 'CommentThread' object successfully on client side but when I save the updated object in backendless it shows the error.

kindly help.

I have attached a screenshot of my table.

and here is my Code,

  1. Backendless.Data.of(CommentThreads.class).findById(id, new AsyncCallback<CommentThreads>() {
  2. @Override
  3. public void handleResponse(CommentThreads response) {
  4. currentthread=response;
  5. progressBar.setVisibility(View.GONE);
  6. adapter.addToEnd(response.getComments(),true);
  7. }
  8. @Override
  9. public void handleFault(BackendlessFault fault) {
  10. progressBar.setVisibility(View.GONE);
  11. makeToast("Error in retrieving");
  12. }
  13. });
  14. input.setInputListener(new MessageInput.InputListener() {
  15. @Override
  16. public boolean onSubmit(final CharSequence inputText) {
  17. final HelpComments comments = new HelpComments();
  18. comments.setMessage(inputText.toString());
  19. comments.setCreator(currentUser);
  20. Backendless.Data.of(HelpComments.class).save(comments, new AsyncCallback<HelpComments>() {
  21. @Override
  22. public void handleResponse(HelpComments response) {
  23. currentthread.addComment(response);
  24. Backendless.Data.of(CommentThreads.class).save(currentthread, new AsyncCallback<CommentThreads>() {
  25. @Override
  26. public void handleResponse(CommentThreads response) {
  27. makeToast(inputText.toString());
  28. adapter.addToStart(comments, true);
  29. makeToast("Message Sent!");
  30. }
  31. @Override
  32. public void handleFault(BackendlessFault fault) {
  33. makeToast("Error! Failed to send!");
  34. Log.d("thread:",currentthread.getObjectId());
  35. Log.d("thread:",currentthread.getOwnerId());
  36. Log.d("thread:",currentthread.getComments().toString());
  37. Log.d("thread:",currentthread.getHelper().getProperty("name").toString());
  38. Log.d("error:",fault.getMessage()+"\nError! Failed to send!\n"+fault.getDetail());
  39. }
  40. });
  41. }
  42. @Override
  43. public void handleFault(BackendlessFault fault) {
  44. makeToast("Error! Failed to send!");
  45. }
  46. });
  47. return true;
  48. }
  49. });
  50. and here is the out put of Log
  51. 04-06 12:40:44.638 18460-18460/com.example.mubtadanaqvi.stunexus D/thread:: C5D305DF-7687-D056-FFA8-A932A5DFC000
  52. 04-06 12:40:44.638 18460-18460/com.example.mubtadanaqvi.stunexus D/thread:: DE1C161F-49AA-CBEE-FFCB-C549DA75D600
  53. 04-06 12:40:44.648 18460-18460/com.example.mubtadanaqvi.stunexus D/thread:: [com.example.mubtadanaqvi.stunexus.HelpComments@42662178, com.example.mubtadanaqvi.stunexus.HelpComments@422a5f70, com.example.mubtadanaqvi.stunexus.HelpComments@42329a78]
  54. 04-06 12:40:44.648 18460-18460/com.example.mubtadanaqvi.stunexus D/thread:: Jawad

Leave a Comment

Comments (21)

photo
1

Could you show what the CommentThread looks like? (As text, NOT a screenshot please).

photo
1

This is the complete class of CommentThreads

  1. package com.example.mubtadanaqvi.stunexus;

    import android.util.Log;

    import com.backendless.BackendlessUser;

    import com.stfalcon.chatkit.commons.models.IDialog;

    import com.stfalcon.chatkit.commons.models.IMessage;

    import com.stfalcon.chatkit.commons.models.IUser;

    import java.util.ArrayList;

    import java.util.List;

    public class CommentThreads implements IDialog

    {

    private java.util.Date created;

    private String ownerId;

    private String objectId;

    private java.util.Date updated;

    private java.util.List<HelpComments> comments;

    private BackendlessUser helper;

    private int unRead=0;

    private IMessage lastMessage;

    private List<IUser> usersList = new ArrayList<>();

    public java.util.Date getCreated()

    {

    return created;

    }

    public String getOwnerId()

    {

    return ownerId;

    }

    public String getObjectId()

    {

    return objectId;

    }

    public java.util.Date getUpdated()

    {

    return updated;

    }

    public java.util.List<HelpComments> getComments()

    {

    return comments;

    }

    public void setComments( java.util.List<HelpComments> comments )

    {

    this.comments = comments;

    }

    public void addComment(HelpComments comments){this.comments.add(comments);}

    public BackendlessUser getHelper()

    {

    return helper;

    }

    public void setHelper( BackendlessUser helper )

    {

    this.helper = helper;

    }

    @Override

    public String getId() {

    return getObjectId();

    }

    @Override

    public String getDialogPhoto() {

    Log.d("test:",getHelper().getProperty("profileImage")+"");

    if (getHelper().getProperty("profileImage")==null)

    return null;

    else

    return getHelper().getProperty("profileImage").toString();

    }

    @Override

    public String getDialogName() {

    return getHelper().getProperty("name").toString();

    }

    @Override

    public List<IUser> getUsers() {

    return this.usersList;

    }

    @Override

    public IMessage getLastMessage() {

    return getComments().get(getComments().size()-1);

    }

    @Override

    public void setLastMessage(IMessage message) {

    this.lastMessage=message;

    }

    @Override

    public int getUnreadCount() {

    return unRead;

    }

    public void addUser(IUser user){

    this.usersList.add(user);

    }

    }

photo
1

What is IUser? The problem is with the following field/property:

private List<IUser> usersList = new ArrayList<>();

photo
1

It is interface's property, but it is not added to the database as it is not visible. I created this property after that object in database, does that matter?

photo
1

Of course it is visible because you have a public getUsers method. As a result, that collection of objects is sent to Backendless where it tries to persist them as well.

photo
1

how can I restrict some class attributes not to save in database.

photo
1

Remove get/add methods, make the field public and add the "transient" keyword for the field.

photo
1

I can't remove get/add methods, it's necessary. What if I only add 'transient' for the field?

photo
1

In that case, add the following annotation to the class:

@ExcludeProperty( propertyName = "usersList" )

photo
1

I have tried the @ExcludeProperty but the problem is still there, It saves the new object but when i try to update it gave the error of "Cannot save entity with primitive collection property users"

photo
1

Can you post here the code of the CommentsThread class again?

photo
1

I have uploaded the said details.

???

photo
photo
1

CommentThreads's class

  1. package com.example.mubtadanaqvi.stunexus;

    import android.util.Log;

    import com.backendless.BackendlessUser;

    import com.stfalcon.chatkit.commons.models.IDialog;

    import com.stfalcon.chatkit.commons.models.IMessage;

    import com.stfalcon.chatkit.commons.models.IUser;

    import java.util.ArrayList;

    import java.util.List;

    import weborb.service.ExcludeProperties;

    @ExcludeProperties( propertyNames = {"usersList","unreadCount","dialogName","dialogPhoto","lastMessage"})

    public class CommentThreads implements IDialog

    {

    private java.util.Date created;

    private String ownerId;

    private String objectId;

    private java.util.Date updated;

    private java.util.List<HelpComments> comments;

    private BackendlessUser helper;

    private int unRead=0;

    private IMessage lastMessage;

    private List<IUser> usersList = new ArrayList<>();

    public java.util.Date getCreated()

    {

    return created;

    }

    public String getOwnerId()

    {

    return ownerId;

    }

    public String getObjectId()

    {

    return objectId;

    }

    public java.util.Date getUpdated()

    {

    return updated;

    }

    public java.util.List<HelpComments> getComments()

    {

    return comments;

    }

    public void setComments( java.util.List<HelpComments> comments )

    {

    this.comments = comments;

    }

    public void addComment(HelpComments comments){this.comments.add(comments);}

    public BackendlessUser getHelper()

    {

    return helper;

    }

    public void setHelper( BackendlessUser helper )

    {

    this.helper = helper;

    }

    @Override

    public String getId() {

    return getObjectId();

    }

    @Override

    public String getDialogPhoto() {

    Log.d("test:",getHelper().getProperty("profileImage")+"");

    if (getHelper().getProperty("profileImage")==null)

    return null;

    else

    return getHelper().getProperty("profileImage").toString();

    }

    @Override

    public String getDialogName() {

    return getHelper().getProperty("name").toString();

    }

    @Override

    public List<IUser> getUsers() {

    return this.usersList;

    }

    @Override

    public IMessage getLastMessage() {

    return getComments().get(getComments().size()-1);

    }

    @Override

    public void setLastMessage(IMessage message) {

    this.lastMessage=message;

    }

    @Override

    public int getUnreadCount() {

    return unRead;

    }

    public void addUser(IUser user){

    this.usersList.add(user);

    }

    }

And Here is HelpComments's Class

  1. package com.example.mubtadanaqvi.stunexus;

    import android.util.Log;

    import com.backendless.BackendlessUser;

    import com.stfalcon.chatkit.commons.models.IMessage;

    import com.stfalcon.chatkit.commons.models.IUser;

    import java.util.Date;

    import weborb.service.ExcludeProperties;

    @ExcludeProperties( propertyNames = {"createdAt","id","text","user"})

    public class HelpComments implements IMessage

    {

    private String message;

    private String ownerId;

    private String objectId;

    private java.util.Date created;

    private java.util.Date updated;

    private BackendlessUser creator;

    public String getMessage()

    {

    return message;

    }

    public void setMessage( String message )

    {

    this.message = message;

    }

    public String getOwnerId()

    {

    return ownerId;

    }

    public String getObjectId()

    {

    return objectId;

    }

    public java.util.Date getCreated()

    {

    return created;

    }

    public java.util.Date getUpdated()

    {

    return updated;

    }

    public BackendlessUser getCreator()

    {

    return creator;

    }

    public void setCreator( BackendlessUser creator )

    {

    this.creator = creator;

    }

    @Override

    public String getId() {

    return getObjectId();

    }

    @Override

    public String getText() {

    return getMessage();

    }

    @Override

    public IUser getUser() {

    DialogAuthor a= new DialogAuthor();

    a.setName(getCreator().getProperty("name").toString());

    if (getCreator().getProperty("profileImage")==null)

    a.setAvtar(null);

    else

    a.setAvtar(getCreator().getProperty("profileImage").toString());

    Log.d("avtarNew:",getCreator().getProperty("profileImage").toString());

    a.setId(getCreator().getObjectId());

    return a;

    }

    @Override

    public Date getCreatedAt() {

    return getCreated();

    }

    }

And here is the code how I try to update it,

  1. input.setInputListener(new MessageInput.InputListener() {

    @Override

    public boolean onSubmit(final CharSequence inputText) {

    final HelpComments comments = new HelpComments();

    comments.setMessage(inputText.toString());

    comments.setCreator(currentUser);

    Backendless.Data.of(HelpComments.class).save(comments, new AsyncCallback<HelpComments>() {

    @Override

    public void handleResponse(HelpComments response) {

    currentthread.addComment(response);

    Backendless.Data.of(CommentThreads.class).save(currentthread, new AsyncCallback<CommentThreads>() {

    @Override

    public void handleResponse(CommentThreads response) {

    makeToast(inputText.toString());

    adapter.addToStart(comments, true);

    makeToast("Message Sent!");

    }

    @Override

    public void handleFault(BackendlessFault fault) {

    makeToast("Error! Failed to send!");

    Log.d("thread:",currentthread.getObjectId());

    Log.d("thread:",currentthread.getOwnerId());

    Log.d("thread:",currentthread.getComments().toString());

    Log.d("thread:",currentthread.getHelper().getProperty("name").toString());

    Log.d("error:",fault.getMessage()+"\nError! Failed to send!\n"+fault.getDetail());

    }

    });

    }

    @Override

    public void handleFault(BackendlessFault fault) {

    makeToast("Error! Failed to send!");

    }

    });

    return true;

    }

    });

photo
1

Hello ? I have provided your required information, kindly help me, it's urgent. It would be a great favor. Thanks in advance.

photo
1

@Mark ? are you here ?

photo
1

Mark is not a bot, he needs to sleep too...))

Mark

p.s. I'll take a look at it and respond soon

photo
1

Thanks :) waiting for your reply!

photo
photo
1

Here's the problem with your code:

When you use the @ExcludeProperty or @ExcludeProperties, the properties you reference in these annotations must have both get and set methods. In both classes (CommentThreads and HelpComments) you define only getters, as a result, our code does not recognize listed properties as "properties".

Regards,

Mark

photo
1

I have made changes as you suggested, but it didn't work.

Here are my updated classes

Comment Threads:

  1. package com.example.mubtadanaqvi.stunexus;

    import android.util.Log;

    import com.backendless.BackendlessUser;

    import com.stfalcon.chatkit.commons.models.IDialog;

    import com.stfalcon.chatkit.commons.models.IMessage;

    import com.stfalcon.chatkit.commons.models.IUser;

    import java.util.ArrayList;

    import java.util.List;

    import weborb.service.ExcludeProperties;

    @ExcludeProperties( propertyNames = {"usersList","unreadCount","dialogName","dialogPhoto","lastMessage","id"})

    public class CommentThreads implements IDialog

    {

    private java.util.Date created;

    private String ownerId;

    private String objectId;

    private java.util.Date updated;

    private java.util.List<HelpComments> comments;

    private BackendlessUser helper;

    private int unRead=0;

    private String id;

    private String dialogPhoto;

    private String dialogName;

    private IMessage lastMessage;

    private List<IUser> usersList = new ArrayList<>();

    public java.util.Date getCreated()

    {

    return created;

    }

    public String getOwnerId()

    {

    return ownerId;

    }

    public String getObjectId()

    {

    return objectId;

    }

    public java.util.Date getUpdated()

    {

    return updated;

    }

    public java.util.List<HelpComments> getComments()

    {

    return comments;

    }

    public void setComments( java.util.List<HelpComments> comments )

    {

    this.comments = comments;

    }

    public void addComment(HelpComments comments){this.comments.add(comments);}

    public BackendlessUser getHelper()

    {

    return helper;

    }

    public void setHelper( BackendlessUser helper )

    {

    this.helper = helper;

    }

    @Override

    public String getId() {

    return getObjectId();

    }

    public void setId(String s){

    this.id=s;

    }

    @Override

    public String getDialogPhoto() {

    Log.d("test:",getHelper().getProperty("profileImage")+"");

    if (getHelper().getProperty("profileImage")==null)

    return null;

    else

    return getHelper().getProperty("profileImage").toString();

    }

    public void setDialogPhoto(String s){

    this.dialogPhoto=s;

    }

    @Override

    public String getDialogName() {

    return getHelper().getProperty("name").toString();

    }

    public void setDialogName(String s){

    this.dialogName=s;

    }

    @Override

    public List<IUser> getUsers() {

    return this.usersList;

    }

    public void setUsers(List<IUser> users){

    this.usersList=users;

    }

    @Override

    public IMessage getLastMessage() {

    if (getComments().size()>0)

    return getComments().get(getComments().size()-1);

    return null;

    }

    @Override

    public void setLastMessage(IMessage message) {

    this.lastMessage=message;

    }

    @Override

    public int getUnreadCount() {

    return unRead;

    }

    public void setUnreadCount(int i){

    this.unRead=i;

    }

    public void addUser(IUser user){

    this.usersList.add(user);

    }

    }

HelpComments:

  1. package com.example.mubtadanaqvi.stunexus;

    import android.util.Log;

    import com.backendless.BackendlessUser;

    import com.stfalcon.chatkit.commons.models.IMessage;

    import com.stfalcon.chatkit.commons.models.IUser;

    import java.util.Date;

    import weborb.service.ExcludeProperties;

    @ExcludeProperties( propertyNames = {"createdAt","id","text","user"})

    public class HelpComments implements IMessage

    {

    private String message;

    private String ownerId;

    private String objectId;

    private java.util.Date created;

    private java.util.Date updated;

    private BackendlessUser creator;

    private String id;

    private String text;

    private IUser user;

    private Date date;

    public String getMessage()

    {

    return message;

    }

    public void setMessage( String message )

    {

    this.message = message;

    }

    public String getOwnerId()

    {

    return ownerId;

    }

    public String getObjectId()

    {

    return objectId;

    }

    public java.util.Date getCreated()

    {

    return created;

    }

    public java.util.Date getUpdated()

    {

    return updated;

    }

    public BackendlessUser getCreator()

    {

    return creator;

    }

    public void setCreator( BackendlessUser creator )

    {

    this.creator = creator;

    }

    @Override

    public String getId() {

    return getObjectId();

    }

    public void setId(String s){

    this.id=s;

    }

    @Override

    public String getText() {

    return getMessage();

    }

    public void setText(String s){

    this.text=s;

    }

    public void setUser(IUser user){

    this.user=user;

    }

    @Override

    public IUser getUser() {

    DialogAuthor a= new DialogAuthor();

    a.setName(getCreator().getProperty("name").toString());

    if (getCreator().getProperty("profileImage")==null)

    a.setAvtar(null);

    else

    a.setAvtar(getCreator().getProperty("profileImage").toString());

    Log.d("avtarNew:",getCreator().getProperty("profileImage").toString());

    a.setId(getCreator().getObjectId());

    return a;

    }

    public void setCreatedAt(Date date){

    this.date=date;

    }

    @Override

    public Date getCreatedAt() {

    return getCreated();

    }

    }

When I insert new rows in both tables it works fine but when I update commentThreads it gave error, kindly help

Thanks in advance. Thanks for you cooperation so far. You guys are awesome especially @Mark. :)

Waiting for your reply

photo
1

It gives you an error? I thought the problem you're solving is that it creates unnecessary columns. Is the problem with the not needed columns solved? if NOT, then create a small program with SIMPLE class that has a few properties. Here's an example:

@ExcludeProperty( propertyName = "secretProp" )

public class Person

{

public String getSecretProp()

{

return secretProp;

}

public void setSecretProp( String secretProp )

{

this.secretProp = secretProp;

}

public String getName()

{

return name;

}

public void setName( String name )

{

this.name = name;

}

private String secretProp;

private String name;

}

Experiment with that class, see how it works. Only then move on to your program which is more complex and make the same changes.

Regards,

Mark

photo
1

Thank God, It worked! Thanks @Mark literally you are awesome, Thanks for your cooperation.