objectbox / objectbox-java

Android Database - first and fast, lightweight on-device vector database
https://objectbox.io
Apache License 2.0
4.39k stars 302 forks source link

How to implement Parcelable about ToOne and ToMany? #235

Closed AllenCoder closed 6 years ago

AllenCoder commented 6 years ago

@Entity
public class Note implements Parcelable {

    @Id
    long id;

    String text;
    String comment;
    Date date;

    ToOne<InnerClass1> class1ToOne;
    ToMany<InnerClass1> innerClass1List;

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(this.id);
        dest.writeString(this.text);
        dest.writeString(this.comment);
        dest.writeLong(this.date != null ? this.date.getTime() : -1);
        dest.writeSerializable(this.class1ToOne);
        dest.writeTypedList(this.innerClass1List);
    }

    public Note() {
    }

    protected Note(Parcel in) {
        this.id = in.readLong();
        this.text = in.readString();
        this.comment = in.readString();
        long tmpDate = in.readLong();
        this.date = tmpDate == -1 ? null : new Date(tmpDate);
        this.class1ToOne = (ToOne<InnerClass1>) in.readSerializable();
        this.innerClass1List = in.createTypedArrayList(InnerClass1.CREATOR);
    }

    public static final Creator<Note> CREATOR = new Creator<Note>() {
        @Override
        public Note createFromParcel(Parcel source) {
            return new Note(source);
        }

        @Override
        public Note[] newArray(int size) {
            return new Note[size];
        }
    };
}

how to set this code ?

   protected Note(Parcel in) {
        this.id = in.readLong();
        this.text = in.readString();
        this.comment = in.readString();
        long tmpDate = in.readLong();
        this.date = tmpDate == -1 ? null : new Date(tmpDate);
        this.class1ToOne = (ToOne<InnerClass1>) in.readSerializable();
        this.innerClass1List = in.createTypedArrayList(InnerClass1.CREATOR);
    }

or

  protected Note(Parcel in) {
        this.id = in.readLong();
        this.text = in.readString();
        this.comment = in.readString();
        long tmpDate = in.readLong();
        this.date = tmpDate == -1 ? null : new Date(tmpDate);
        this.class1ToOne = (ToOne<InnerClass1>) in.readSerializable();

        in.readTypedList(this.innerClass1List, InnerClass1.CREATOR);
    }
greenrobot commented 6 years ago

Note: Parcables are often used to pass around data via intent. Here, usually passing around just the ID is better.

Other than that: do you need to include the relations in the parcel?

AllenCoder commented 6 years ago

yes , I want to send the data that has been queried , Parcelable is more efficient than Serializable,

greenrobot commented 6 years ago

My point was to pass just the ID and load it via ObjectBox if that's an option for you?

AllenCoder commented 6 years ago

I understand, thank you

silviahisham commented 6 years ago

Would be a lot better if we could pass the data we queried between activities/fragments via parcelable, that way I don't have to query the data again everytime I open an activity that uses the object.

greenrobot commented 6 years ago

Why better? Passing an ID and getting the object by ID is straight forward.

silviahisham commented 6 years ago

sometimes the object would be deleted from the database already, and i need to pass it between activities/fragments

greenrobot commented 6 years ago

@silviahisham Never stumbled on a use case like this. Could you explain a bit more why this is neccessary in your app?

silviahisham commented 6 years ago

@greenrobot There was a use case for it but you're right, it makes sense actually to delete it after I'm finally done with it. Thanks.

greenrobot-team commented 6 years ago

Great, closing then. -ut

valentynsmetanin commented 6 years ago

Hi @greenrobot. Could you add Parcelable support (ToOne and ToMany) on the next version of the ObjectBox, or explain way to implement this?

greenrobot-team commented 6 years ago

@valentynsmetanin Please read the previous comments. The main question: please explain why you can't just pass the object id and re-query the object when needed, instead of parceling it? -ut

valentynsmetanin commented 6 years ago

@greenrobot In some cases we have easier to have 1 model for the database and data transfer object (Parcelable entity). You can use this entity in scopes without DB, but you can't because it's doesnt implement parcelable or this parcelable implementation is wrong. So, it's need in scope when you doesn't save entity to DB, but you need to pass this as Parcelable. This imposes limitations for Android developers.

greenrobot-team commented 6 years ago

@valentynsmetanin Are you talking about passing data between apps? If no, you can get a hold of a BoxStore pretty much anywhere you have a Context. -ut

JaDogg commented 4 years ago

If you need to store/get multiple random elements simply store a long[]of IDs and then get the related entities back by boxOfX.get(myIDs)

jiaoya commented 4 years ago

Sometimes the data transfer between pages does not need to operate the database. These data are temporary, but the entity class is marked @entity, then Parcelable cannot be used. Does objectbox not support it? Otherwise, it must be stored in the database every time, read and deleted by id. . . @greenrobot @greenrobot-team

greenrobot-team commented 4 years ago

@jiaoya I don't follow how the ObjectBox annotations might prevent you from implementing the Parcelable interface (assuming you do not use relations). Care to elaborate, possibly in a new issue or on Stack Overflow?

mecoFarid commented 3 years ago

@greenrobot-team ObjectBox doesn't prevent you from implementing a Serializable/Parcelable interface but ToOne/ToMany breaks it as mentioned here #110. I have seen lots of comments by the ObjectBox team to not serialize models when passing data between UI components but that is not a valid excuse to break the original java API. You may use serialization for other purposes not just for passing data between UI components

greenrobot commented 3 years ago

@mecoFarid #110 has long been fixed. Also this issue is closed. :ghost: If you experience a problem, please open an issue with all info needed.

mecoFarid commented 3 years ago

@greenrobot Sorry, my bad tagging wrong issue. I have been looking for a solution (workaround) past 3 days and mixed up issues with similar causes. The issue I should have tagged is #342

We're using this library in production and that tiny problem frustrated me and my comment sounded harsh. :)

Thanks for the great library, BTW