Custom ID with ObjectBox
You've correctly assumed you can set relation.target
(or relation.targetId
) - it can point to an existing object, in which case ObjectBox won't try to create it. An adaptation of the following code should work for you:
final docTemplate = DocumentTemplateEntity(...)
final familyQuery = store.box<DocumentFamilyEntity>().query(DocumentFamilyEntity_.id.equals('unique ID of an existing family entity').build();
// and one of the following
docTemplate.family.target = familyQuery.findFirst();
// or
docTemplate.family.targetId = (familyQuery..limit = 1).findIds().firstOrNull;
Teio07
Updated on November 25, 2022Comments
-
Teio07 over 1 year
I'm using ObjectBox with Flutter and I'm having some trouble with the mandatory
int id
required by ObjectBox on eachEntity
.In my app I'm using custom ids using the uuid package and I'm mapping those
Entity
classes to my ownDomain
classes to make abstraction of the ObjectBox implementation.Those
Entity
classes have the mandatoryint id
required by ObjectBox that I defined asint obid
annotated with@Id()
and my ownDomain
id defined asString id
with the@Unique()
annotation.It just gives me a little bit more work when I need to get an
Entity
by id, but that's fine. The problem is when I need to add anEntity
having a relation with another one, since myDomain
classes don't have theobid
when I convert from aDomain
to anEntity
class, theobid
is omitted and defaults to 0, then ObjectBox tries to persist/create a newEntity
and fail because of the@Unique()
annotation of theid
. I don't even want to create a newEntity
for the relation. What I want is create anEntity
and just put a reference to an already persistedEntity
as the the relation.I think the way to do it is by setting
relation.target
or therelation.targetId
but in my case, this won't work because it doesn't rely on myid
.How can I make my own
id
work as a real id and not just aUnique
constraint ?Here are some examples of those
Entity
andDomain
classes :DocumentTemplateEntity :
@Entity() class DocumentTemplateEntity { @Id() int obid = 0; @Unique() String id; String title; double leftMargin; double topMargin; double rightMargin; double bottomMargin; DateTime? insertedAt; DateTime? updatedAt; final family = ToOne<DocumentFamilyEntity>(); DocumentTemplateEntity({ required this.id, required this.title, required this.leftMargin, required this.topMargin, required this.rightMargin, required this.bottomMargin, this.insertedAt, this.updatedAt, }); DocumentTemplate toDomain() => DocumentTemplate( id: UniqueId.fromUniqueString(id), title: DocumentTemplateTitle(title), leftMargin: leftMargin, topMargin: topMargin, rightMargin: rightMargin, bottomMargin: bottomMargin, insertedAt: insertedAt, updatedAt: updatedAt, family: family.target!.toDomain(), ); factory DocumentTemplateEntity.fromDomain(DocumentTemplate template) => DocumentTemplateEntity( id: template.id.getOrCrash(), title: template.title.getOrCrash(), leftMargin: template.leftMargin, topMargin: template.topMargin, rightMargin: template.rightMargin, bottomMargin: template.bottomMargin, insertedAt: template.insertedAt, updatedAt: template.updatedAt, )..family.target = DocumentFamilyEntity.fromDomain(template.family); }
DocumentFamilyEntity :
@Entity() class DocumentFamilyEntity { @Id() int obid = 0; @Unique() String id; String title; int sortOrder; DateTime? insertedAt; DateTime? updatedAt; DocumentFamilyEntity({ required this.id, required this.title, required this.sortOrder, this.insertedAt, this.updatedAt, }); DocumentFamily toDomain() => DocumentFamily( id: UniqueId.fromUniqueString(id), title: title, sortOrder: sortOrder, insertedAt: insertedAt, updatedAt: updatedAt, ); factory DocumentFamilyEntity.fromDomain(DocumentFamily family) => DocumentFamilyEntity( id: family.id.getOrCrash(), title: family.title, sortOrder: family.sortOrder, insertedAt: family.insertedAt, updatedAt: family.updatedAt, ); }
DocumentTemplate (Domain) :
@freezed class DocumentTemplate with _$DocumentTemplate { factory DocumentTemplate({ required UniqueId id, required DocumentTemplateTitle title, required double leftMargin, required double topMargin, required double rightMargin, required double bottomMargin, required DocumentFamily family, DateTime? insertedAt, DateTime? updatedAt, }) = _DocumentTemplate; factory DocumentTemplate.initial() => DocumentTemplate( id: UniqueId(), title: DocumentTemplateTitle(''), leftMargin: 1.0, topMargin: 1.0, rightMargin: 1.0, bottomMargin: 1.0, family: DocumentFamily.initial(), ); }
DocumentFamily (Domain) :
@freezed class DocumentFamily with _$DocumentFamily { factory DocumentFamily({ required UniqueId id, required int sortOrder, required String title, DateTime? insertedAt, DateTime? updatedAt, }) = _DocumentFamily; factory DocumentFamily.initial() => DocumentFamily( id: UniqueId(), sortOrder: 0, title: '', ); }
-
Teio07 almost 3 yearsYes, it seems like the only solution for now but I found out that with ObjectBox Java, you had the option of adding a parameter to the @Unique() annotation (something like @Unique(onConflict = ConflictStrategy.REPLACE) ) that would replace the Entity in the case it already existed. As referenced here : github.com/objectbox/objectbox-java/issues/… I guess it would solve my problem and make the @Unique() annotation behave more like a real ID. Will this feature come to ObjectBox Dart too ? Thanks for the help !
-
vaind almost 3 yearsI'm not aware of anyone working on this at the moment. If that's something you'd like to use, you can create a feature request (issue) on github for objectbox-dart. Even better, you can contribute the change :)
-
Tanuki about 2 yearsHello! I saw you're a objectbox's collaborator, what about a
ConflictStrategy.UPDATE
@vaind ? github.com/objectbox/objectbox-dart/issues/378