Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Freezed (immutable) support with 0 id fails due to assignment to final id #307

Open
ilikerobots opened this issue Aug 29, 2021 · 7 comments
Labels
enhancement New feature or request

Comments

@ilikerobots
Copy link

ilikerobots commented Aug 29, 2021

In #229, the example supporting freezed entities uses assignable ids. Since freezed demands entities to be immutable, attempts to use value 0 ids fail in

if (prevId == 0) _entity.setId(object, result);
with error

Unhandled Exception: Invalid argument(s): Field Model.id is read-only (final or getter-only) and it was declared to be self-assigned. However, the currently inserted object (.id=0) doesn't match the inserted ID (ID 1). You must assign an ID before calling [box.put()].

Is it possible to use non-assignable ids with immutable entities currently? If not, would it be beneficial to make it so, e.g. by modifying the code above to use a copyWith or some other mechanism to set newly assigned ids?

@ilikerobots ilikerobots added the bug Something isn't working label Aug 29, 2021
@ilikerobots ilikerobots changed the title Freezed support with non-assignable id Freezed (immutable) support with non-assignable id fails due to assignment of final id Aug 29, 2021
@ilikerobots ilikerobots changed the title Freezed (immutable) support with non-assignable id fails due to assignment of final id Freezed (immutable) support with 0 id fails due to assignment of final id Aug 29, 2021
@ilikerobots ilikerobots changed the title Freezed (immutable) support with 0 id fails due to assignment of final id Freezed (immutable) support with 0 id fails due to assignment to final id Aug 29, 2021
@vaind
Copy link
Contributor

vaind commented Aug 30, 2021

Not sure how we could do this. The contract of box.put() (and putMany()) is that it sets the ID on the given object, if it was previously zero. This is especially important with relations (and relation cycles) so that when the related data is being put, the existing objects aren't reinserted always as new ones (that would result in an infinite recursion).

@ilikerobots
Copy link
Author

Ok, thanks. If I understand correctly,then, a project that uses objectbox and immutable models is required to fully manage IDs independently, right?

@tomwyr
Copy link

tomwyr commented Sep 21, 2021

Do you think it would be possible to either use models that are mutable or immutable and they declare a function that transforms given instance with zero id to an instance with id generated by ObjectBox (which is then added to database)?
So something like:

@Entity()
@freezed
class Book with _$Book {
  factory Book({
    @Id(assignBy: getBookWithId) @Default(0) int id,
  }) = _Book;
}

Book getBookWithId(Book book, int id) => book.copyWith(id: id);

@lampian
Copy link

lampian commented Oct 16, 2021

Using Equatable requires entity class to be immutable.
This then require the Id field to be final, which currently is not supported.
Please consider providing a way to update the entity as a whole with all fields as final.
The solution suggested by @tomwyr is pointing in the right direction - not sure what side effects there would be.

@vaind
Copy link
Contributor

vaind commented Dec 29, 2021

@tomwyr - unfortunately that still won't satisfy the current "contract" of box.put() (or putMany()) which says it updates the given object. Besides this being possibly relied upon in client apps, it's also used when working with relations, requiring the relation target object instance to be updated with the inserted ID. Getting around this may require some more thought...

Anyone interested in this, please upvote the original issue (at the top) so the interest can be tracked when prioritizing development.

@rafuck
Copy link

rafuck commented Mar 4, 2022

#393

@greenrobot-team greenrobot-team added enhancement New feature or request and removed bug Something isn't working labels Feb 13, 2024
@raj457036
Copy link

raj457036 commented Mar 10, 2024

This works btw! ( note: this will make your properties mutable else everything will be same )

@Freezed(addImplicitFinal: false)
sealed class YourClass with _$YourClass {
    @Entity(realClass: YourClass)
    factory YourClass({
        @Default(0) @Id() int localId,
        @Unique() String? id,
    }) = _YourClass;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

7 participants