Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recursive relationship to same object #81

Closed
jcavar opened this issue Mar 31, 2017 · 6 comments
Closed

Recursive relationship to same object #81

jcavar opened this issue Mar 31, 2017 · 6 comments

Comments

@jcavar
Copy link
Contributor

jcavar commented Mar 31, 2017

Hi,
We have the following JSON structure:

{
    "chat": 
    {
        "identifier": 1,
        "message": 
        {
            "identifier": 2,
            "chat": 
            {
                "identifier": 1
            }
        }
    }
}

We are using CoreData and we encountered problem when transforming this. Chat with identifier 1 is created twice. I think we identified why is this happening:

So the issue is in FEMDeserializer.m
- (id)_objectFromRepresentation:(NSDictionary *)representation mapping:(FEMMapping *)mapping allocateIfNeeded:(BOOL)allocate.
If object is not in cache, it is inserted and then filled from external representation. When filling it, inner chat is encountered and not found in cache and inserted as well. So we end up with 2 same chats.

The issue could be solved by caching object before calling fillObject.
I hope this makes sense? Is this something that FastEasyMapping should handle?

@jcavar
Copy link
Contributor Author

jcavar commented Mar 31, 2017

So we would need to set primary key and cache before fill object which would look something like this:

- (id)_objectFromRepresentation:(NSDictionary *)representation mapping:(FEMMapping *)mapping allocateIfNeeded:(BOOL)allocate {
    id object = [self.store registeredObjectForRepresentation:representation mapping:mapping];
    if (!object && allocate) {
        object = [self.store newObjectForMapping:mapping];
    }
    
    if (!object) {
        return nil;
    }

    
    id primaryKey = representation[mapping.primaryKeyAttribute.keyPath];
    primaryKey = [mapping.primaryKeyAttribute mapValue:primaryKey];
    [object setValue:primaryKey forKey:mapping.primaryKey];
    
    if ([self.store canRegisterObject:object forMapping:mapping]) {
        [self.store registerObject:object forMapping:mapping];
    }
    
    if (_delegateFlags.willMapObject) {
        [self.delegate deserializer:self willMapObjectFromRepresentation:representation mapping:mapping];
    }

    [self _fillObject:object fromRepresentation:representation mapping:mapping];

    if (_delegateFlags.didMapObject) {
        [self.delegate deserializer:self didMapObject:object fromRepresentation:representation mapping:mapping];
    }

    return object;
}

@dimazen
Copy link
Contributor

dimazen commented Mar 31, 2017

Hello, @jcavar! Thanks for your issue! It looks like that FEM can handle this easily. Anyway primary key mapping has some specific rules and thus can be extracted from the object fulfilling method.

I'll fix it later today if it works for you :)

@jcavar
Copy link
Contributor Author

jcavar commented Mar 31, 2017

Well that was fast response 👍. Sure it works :)

@dimazen
Copy link
Contributor

dimazen commented Apr 2, 2017

I'll roll out update with fix later this morning (third of April)

@dimazen
Copy link
Contributor

dimazen commented Apr 3, 2017

@jcavar you can now use 1.1.2 version that contains this fix.
#80 postponed until 1.2 that I'm currently working on. It looks like that you gonna split your data into chunks, therefore I've decided to combine errors handling with new major release.

ping me if you have more issues :)

@jcavar
Copy link
Contributor Author

jcavar commented Apr 3, 2017

Nice, thank you :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants