objectbox-java: @Unique: replace on conflict flag
Right now, @Unique throws an exception if there’s a violation.
We could also offer to replace old entities with newer ones, e.g. by doing a @Unique(replaceOnConflict = true).
Keep in mind: If there are multiple unique properties, on entity might replace several others.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 51
- Comments: 64 (14 by maintainers)
Current proposal:
@Uniquehas the default on-conflict strategy FAIL; any unique violation throws an exception.@Unique(onConflict=IGNORE): ignore the offending object (no changes to the existing conflicting object). If there are multiple unique properties in an entity, this strategy is evaluated first: if the property conflicts, no other properties will be checked for conflicts.@Unique(onConflict=REPLACE): the offending object replaces the existing conflicting object (deletes it). If there are multiple properties using this strategy, a single put can potentially replace (delete) multiple existing objects.@Unique(onConflict=UPDATE): the offending object overwrites the existing conflicting object while keeping its ID. Thus, all relations pointing to the existing entity stay intact. This is useful for a “secondary” ID, e.g. a string “ID”. Within an entity, this strategy may be used once only (update target would be ambiguous otherwise).Multiple strategies in an entity are processed in this order: IGNORE, FAIL, REPLACE, UPDATE.
Are you guys actively working on this? This is a major pain-point for us!
We can’t properly use relations in our models and let ObjectBox figure out when an object is new or needs updates, so we have to do a manual look-up each time we want to save something.
We used Realm & started migration to ObjectBox because of better API, better support for Architecture Components & no weirdness caused by the no-copy model. And because Realm is so damn slow at implementing features requested by the community (there still are a couple of issues from 2017 I’m still waiting for).
We’re building a chat platform with lots of features that would benefit from ObjectBox’s upcoming sync. But if I can’t build the app today without making lots of error & bug prone workarounds there won’t be a day when we’ll happily pay for the sync service.
I moved away from SQL in 2014 and never looked back. Realm worked pretty well for not very complex scenarios & it was still better than writing tons of boilerplate code for SQL. ObjectBox came along at it seemed to be something even better, especially in the context of Android Architecture Components. But for a slightly more complex scenario that doesn’t use Long ids, everything falls apart. I’m seriously considering going back to SQL. Room became a pretty solid library. It even supports
suspendfunctions!If the ObjectBox team is not interested in working on this, or has other priorities, just say so! Don’t keep us waiting for months on end, for nothing.
Thanks, and sorry for the long & ranty message!
Is this issue still in the roadmap? When will you release it?
New year is coming .
The flower has faded three times .
It’s going to bloom again this year .
Just leaving a note here that we are still waiting and rooting for the team 🙂
@mehdiyari We are all waiting patiently for this feature to become available. 😃
For once, some background here: we were in the middle of implementing this when we realized that this feature might impact data synchronization in a complex way. E.g. this feature brings implicit deletes; and with potentially multiple data states across clients and servers; this might become problematic. We want to implement this feature in a future safe way that plays well with sync.
Throwing exception break’s box.put(Collection<Entity> ) method loop, there is a need for quick solution for that
You may want to try the new
@Unique(onConflict = ConflictStrategy.REPLACE)of the 2.9.2-RC preview release.Currently there can only be a single property annotated with this.
I have migrated from greendao to objectBox, and stuck in this @unique. Any update please? Should I revert back my whole project again? Or I have to insert data iteratively?
Any updates?
Bump. Still really really need this.
Does this look like a reasonable workaround when you need to update the local db with some objects from a server?
any ETA for this feature?
Is there any news for this feature?
Yep, I can’t update via put method. I’m getting crash when entity with unique annotation exists but I just want to update
@kordianbruck Not sure what you are arguing for, could you explain? Do it as annotations? SQLite supports conflict resolution within column definition (inflexible), but also inside INSERT/UPSERT (flexible). I tend to prefer the flexible option, e.g.
box.put(person, REPLACE)because at another code section you might want to dobox.put(person, IGNORE)because you might have another use case.@avcial Maybe be a mess for lists, but OK for single entities; e.g.
Person conflict = box.putOrGet(person). Same with lists would be possible but you would loose the connection of offending and existing entity.There is a bit more specific documentation in the SQLite docs: https://sqlite.org/lang_conflict.html
So yes, its a good idea and general industry standard when talking about SQLite based things: https://developer.android.com/reference/android/arch/persistence/room/OnConflictStrategy
Maybe SQLite is not the reference here, but I think when devs come from using an ORM like room, they at least expect similar ways how those things work 👍
This is now available with the
3.0.1release.Thank you so much for this! 😃 So far with my testing it seems to be working great and my app is running noticeably smoother than the old hack I had!
When my only value is a string, I can only insert data iteratively at present. I don’t think it’s a good way. Is there a better way?
is gonna be released any time soon?
I know the logic will be a mess but when you add the exception throwing on conflict at ver2.0.0 i expected that maybe you would return the original entity inside the error so we can do whatever we want to do with conflicted row, maybe try to put it again after some changes??