objectbox-java icon indicating copy to clipboard operation
objectbox-java copied to clipboard

@Unique: more on conflict options

Open greenrobot-team opened this issue 3 years ago • 13 comments

@Unique currently supports FAIL and REPLACE that are compatible with Sync.

Proposal to add more options (that likely will not work with Sync):

@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=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.

Originally posted by @greenrobot in https://github.com/objectbox/objectbox-java/issues/509#issuecomment-425055199

greenrobot-team avatar Nov 15 '21 07:11 greenrobot-team

As stated on #509, my own use case can't rely on FAIL not REPLACE, but needs IGNORE.

RobbWatershed avatar Nov 21 '21 13:11 RobbWatershed

Implementing the current issue is enough in most cases, maybe in all cases. These options are extremely necessary and a must-have for many projects.

But what you think if user can himself decide the priority?

@Unique(onConflict=IGNORE, priority=4)
var name: String = ""

@Unique(onConflict=FAIL, priority=3)
var address: String = ""

@Unique(onConflict=REPLACE, priority=2)
var phone: String = ""

@Unique(onConflict=UPDATE, priority=1)
var lastSeen: Long = 1234567890

The put() operation would be done according to the highest priority.

fcat97 avatar Nov 23 '21 08:11 fcat97

The UPDATE strategy would be very useful for me. Currently I have to manually implement the update mechanism by running a query() for each object in a list, then set all the fields if an existing is found. The performance is not the end of the world, but I get a lot of log spam and the code looks ugly.

chakflying avatar Jan 12 '22 04:01 chakflying

@chakflying

then set all the fields

This sounds like the existing REPLACE strategy could work for this, no? https://docs.objectbox.io/entity-annotations#unique-constraints

greenrobot-team avatar Jan 12 '22 08:01 greenrobot-team

I would like to move the discussion about my new proposal here. https://github.com/objectbox/objectbox-java/issues/1046

andrew-ld avatar Jan 17 '22 10:01 andrew-ld

@greenrobot-team But REPLACE doesn't automatically update the relations? If I have to check whether it got replaced during insert, then fix the relations manually it would be even more messy, I think.

chakflying avatar Jan 17 '22 10:01 chakflying

Hello, there is some news? still need that implementation of ConflictStrategy.UPDATE @greenrobot-team

tanukijs avatar Feb 21 '22 10:02 tanukijs

Has there been any update about ConflictStrategy.UPDATE in the meanwhile? @greenrobot-team

deliqs avatar May 17 '22 06:05 deliqs

@deliqs What's your use case? E.g. why can't put be used in your case?

greenrobot-team avatar May 23 '22 06:05 greenrobot-team

@greenrobot-team I'm building an offline first mobile app. I link the local/offline data to the central/online data by saving the central PK locally as a separate identifier once the data has been uploaded. I want to keep the local data in sync with the central data. So I currently check if any data is missing or outdated locally and get the missing/updated data from my central database.

Please correct me if I'm wrong, but as far as I can see ConflictStrategy.REPLACE will also replace the existing local PK, and thus breaking all existing relationships. So I have to map the data from my central database on to the corresponding local data. It would be a improvement to the code if I could instead just update the local data by inserting the new data with the matching ConflictStrategy.UPDATE property without breaking the existing relationships.

deliqs avatar May 23 '22 10:05 deliqs

@deliqs Thanks for the details! Yes, if a replace occurs with ConflictStrategy.REPLACE the new inserted object will have a different @Id. And relations would still point to the removed objects @Id, so would be broken.

greenrobot-team avatar May 24 '22 06:05 greenrobot-team

I'm also looking forward to use this kind of UPDATE strategy. Is there any target date for releasing that feature?

Schmalztopf avatar Jun 19 '22 18:06 Schmalztopf

@Schmalztopf No, we will share once a feature is being worked on and when it's done. To help us track interest, thumbs up the first post.

greenrobot-team avatar Jun 20 '22 05:06 greenrobot-team