Faulting in to-one relationships

25 views
Skip to first unread message

Brendan Duddridge

unread,
Oct 8, 2015, 10:50:18 PM10/8/15
to Couchbase Mobile
Hi,

I have a couple of `CBLModel` subclasses in a to-one relationship: `TFLayoutItem -> TFField`

In order to get a field from the current layoutItem, I simply reference it like this: self.layoutItem.field

What I'm finding is that when I reference field, it seems like it can't be found in the database for some reason and creates a new one. But I know it exists in the database. It seems to eventually find it, but then I'm left with these new empty objects that eventually get deallocated. They're not saved to the database, but they still get created.

Maybe I've setup my relationship incorrectly?

On my TFLayoutItem class, I declared my field property as follows:

@property (nonatomic, strong) TFField *field;


and declared it dynamic:

@dynamic field;


I've also registered `TFField` with the modelFactory:

[factory registerClass:[TFField class] forDocumentType: @"TFField"];


Here's the stack trace of what happens when I reference my `field` property of my `TFLayoutItem` object.

#0    -[CBLModel initWithDocument:orDatabase:] at CBLModel.m:51
#1 +[CBLModel modelForDocument:] at CBLModel.m:86
#2 -[CBLModel modelWithDocID:forProperty:ofClass:] at CBLModel.m:543
#3 -[CBLModel(Properties) getModelProperty:] at CBLModel+Properties.m:120
#4 +[CBLModel(Properties) impForGetterOfProperty:ofClass:] at CBLModel+Properties.m:254
#5 -[TextFieldLayoutItem drawContentsInView:isSelected:] at TextFieldLayoutItem.m:75

My line of code at #5 is this:

self.fieldValue = [self.formEntry valueForField:self.layoutItem.field];


The layoutItem object is already loaded in. I was just referencing the `field` object and it's supposed to fault it in when referenced.

So I'm wondering if I'm missing something obvious?

Thanks,

Brendan

Jens Alfke

unread,
Oct 9, 2015, 12:31:50 PM10/9/15
to mobile-c...@googlegroups.com

On Oct 8, 2015, at 7:50 PM, Brendan Duddridge <bren...@gmail.com> wrote:

What I'm finding is that when I reference field, it seems like it can't be found in the database for some reason and creates a new one. But I know it exists in the database. It seems to eventually find it, but then I'm left with these new empty objects that eventually get deallocated. They're not saved to the database, but they still get created.

That definitely shouldn’t be happening; but I’m pretty confident in the code behind this, so I’m going to assume there’s some other explanation :) In particular, there are two invariants:
  1. There can only be one CBLDocument instance with a specific document ID in a CBLDatabase.
  2. There can only be one CBLModel instance for a CBLDocument.

In the cases where this problem occurs, please check the document IDs of the model objects in question, and also check the raw value of the source model's `field` property (which you can get from `model.document[@“field”]`.

Also, do you have active replications? One thing that can happen is a race condition where document A gets pulled before document B, but A has a field that references B; if you look at A immediately after it’s inserted, and follow the reference to B, you arrive at an empty document because B doesn’t exist locally yet. But B will get pulled soon thereafter, and you’ll see the document and the model populate with the correct data.

—Jens
Reply all
Reply to author
Forward
0 new messages