{"action":"created","issue":{"url":"https://api.github.com/repos/mapstruct/mapstruct/issues/469","repository_url":"https://api.github.com/repos/mapstruct/mapstruct","labels_url":"https://api.github.com/repos/mapstruct/mapstruct/issues/469/labels{/name}","comments_url":"https://api.github.com/repos/mapstruct/mapstruct/issues/469/comments","events_url":"https://api.github.com/repos/mapstruct/mapstruct/issues/469/events","html_url":"https://github.com/mapstruct/mapstruct/issues/469","id":58474611,"number":469,"title":"Mapping Object Graphs with Cycles","user":{"login":"agudian","id":2737102,"avatar_url":"https://avatars.githubusercontent.com/u/2737102?v=3","gravatar_id":"","url":"https://api.github.com/users/agudian","html_url":"https://github.com/agudian","followers_url":"https://api.github.com/users/agudian/followers","following_url":"https://api.github.com/users/agudian/following{/other_user}","gists_url":"https://api.github.com/users/agudian/gists{/gist_id}","starred_url":"https://api.github.com/users/agudian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/agudian/subscriptions","organizations_url":"https://api.github.com/users/agudian/orgs","repos_url":"https://api.github.com/users/agudian/repos","events_url":"https://api.github.com/users/agudian/events{/privacy}","received_events_url":"https://api.github.com/users/agudian/received_events","type":"User","site_admin":false},"labels":[{"id":80715304,"url":"https://api.github.com/repos/mapstruct/mapstruct/labels/feature","name":"feature","color":"009800","default":false}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/mapstruct/mapstruct/milestones/15","html_url":"https://github.com/mapstruct/mapstruct/milestones/1.2.x","labels_url":"https://api.github.com/repos/mapstruct/mapstruct/milestones/15/labels","id":1960952,"number":15,"title":"1.2.x","description":"Features interesting for a 1.2 release.","creator":{"login":"gunnarmorling","id":28612,"avatar_url":"https://avatars.githubusercontent.com/u/28612?v=3","gravatar_id":"","url":"https://api.github.com/users/gunnarmorling","html_url":"https://github.com/gunnarmorling","followers_url":"https://api.github.com/users/gunnarmorling/followers","following_url":"https://api.github.com/users/gunnarmorling/following{/other_user}","gists_url":"https://api.github.com/users/gunnarmorling/gists{/gist_id}","starred_url":"https://api.github.com/users/gunnarmorling/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gunnarmorling/subscriptions","organizations_url":"https://api.github.com/users/gunnarmorling/orgs","repos_url":"https://api.github.com/users/gunnarmorling/repos","events_url":"https://api.github.com/users/gunnarmorling/events{/privacy}","received_events_url":"https://api.github.com/users/gunnarmorling/received_events","type":"User","site_admin":false},"open_issues":6,"closed_issues":6,"state":"open","created_at":"2016-08-24T16:04:54Z","updated_at":"2016-12-04T22:41:02Z","due_on":null,"closed_at":null},"comments":20,"created_at":"2015-02-21T20:56:36Z","updated_at":"2016-12-06T21:52:39Z","closed_at":"2016-12-04T15:23:20Z","body":"Currently, we have no support of handling cycles within mapping methods. That can be a problem if, for example, both source and target object structures contain bidirectional associations between parent and children. Generic frameworks detect and handle such cycles by maintaining identity-maps. \n\nWe -stubled upon- fell over that in production when suddenly some servers went blank, as it turned out due to stack-overflow-errors. We handled other potential cases with some manual mapping code, but that one spot was overlooked (and the unit tests didn't cover the exact situation). And it wasn't even an obvious spot, as it required two mapping steps to find the starting point of the cycle again.\n\nI think there are two things we could do here:\n1. Report-Only: issue warnings or errors if we detect potential cycles. Such an analysis could be performed by an additional processor that checks the model after the MapperCreationProcessor. Question is: what would a user do after spotting this thing.\n2. Support handling of cycles: we could maintain an identity-map of source->target instances and return the already mapped instance at the start of the mapping method. Question here is: where would that map be located? In a ThreadLocal? But then this has to be cleared at some point. Might get messy. Or we create a new type MappingContext in package org.mapstruct (would become a runtime-dep if used) and if a mapping method has that thing in its signature, then it is used. Users would pass in a new instance of the context when they want to start their mapping with their root object, e.g. with a static `MappingContext.create()`.\n\nAny thoughts?\n"},"comment":{"url":"https://api.github.com/repos/mapstruct/mapstruct/issues/comments/265284377","html_url":"https://github.com/mapstruct/mapstruct/issues/469#issuecomment-265284377","issue_url":"https://api.github.com/repos/mapstruct/mapstruct/issues/469","id":265284377,"user":{"login":"zt1983811","id":2559543,"avatar_url":"https://avatars.githubusercontent.com/u/2559543?v=3","gravatar_id":"","url":"https://api.github.com/users/zt1983811","html_url":"https://github.com/zt1983811","followers_url":"https://api.github.com/users/zt1983811/followers","following_url":"https://api.github.com/users/zt1983811/following{/other_user}","gists_url":"https://api.github.com/users/zt1983811/gists{/gist_id}","starred_url":"https://api.github.com/users/zt1983811/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zt1983811/subscriptions","organizations_url":"https://api.github.com/users/zt1983811/orgs","repos_url":"https://api.github.com/users/zt1983811/repos","events_url":"https://api.github.com/users/zt1983811/events{/privacy}","received_events_url":"https://api.github.com/users/zt1983811/received_events","type":"User","site_admin":false},"created_at":"2016-12-06T21:52:39Z","updated_at":"2016-12-06T21:52:39Z","body":"@filiphr I checked your pull request in example  mapstruct, and it works. Really appreciate for this fix. However, my concerting is why we need to create CycleAvoidanceMapper.java class in all the packages? If I make this in a common package it will not work. Also could you make it generic like annotation I can just use it? \r\n\r\nThanks"}}
{"actor":{"display_login":"zt1983811"}}