Wednesday, January 5, 2022

Adding multiple of the same object in ObjectBox ToMany relationship

If you're using ObjectBox for handling your local data storage, it's possible you've run into the restriction that a single ToMany relationship can not contain multiple of the same object. For example, if you have two classes Pattern and Color:
@Entity
data class Color(var name: String) {
}

@Entity
data class Pattern(var name: String) {
	lateinit var colors : ToMany
}
then you may have the following colors:
+----+---------------+
| ID |   name        |
+----+---------------+
|  1 |   Blue        |
+----+---------------+
|  2 |   Yellow      |
+----+---------------+
But you cannot have a Pattern object with say, Blue, Yellow, Blue. One possible workaround is to add another Color Blue (with say, ID 3), but this can get ugly if you later change Blue to Purple and expect the Pattern to now be Purple, Yellow, Purple. One simple workaround I've found is to create a proxy class for the target entity. The proxy class will simply contain a ToOne relationship to the target entity type. You then change the ToMany relationship to point to the proxy class instead. So in our example above, we add a new ColorProxy class:
@Entity
data class ColorProxy() {
  lateinit var color : ToOne
}
and change the Pattern class to:
@Entity
data class Pattern(var name: String) {
	lateinit var colorProxies : ToMany
}
An extra Box will be required to hold the proxy objects and extra care must be taken to put() the proxy objects into their box, but it allows for a Pattern to contain multiple references to the same actual Color object. I know this is a bit of weird use case, but if you are reading this, hopefully this helped you out.