0

I have the following records in a postgres database. The parent_pk is related to the pk in a parent-child relation. The pk = 1 is the parent of all children directly and indirectly.

pk             name             type            parent_pk
---            ----             ----            ---------
1              hnumber101       house           1
2              hnumber201       house           1
791            dodge_charger    vehicle         1
801            mustang          vehicle         791
595020         civic            vehicle         2
10077661099    john             user            10046725614
10046725614    mesto            dev             1
801            shen             house           791
44444444       crep             house           10046725614
22222222       keper            user            10046725614
11111111       show             house           10046725614
84257651       shen             house           801
11             lemp             house           2

And I want to generate a json out of the above in the following format-

{
  "children" : [
    { "pk" : "1", "name" : "hnumber101", "children" : [
      { "pk" : "10046725614", "name" : "mesto", "children" : [
          { "pk" : "10077661099", "name" : "john", "children" : [] },
          { "pk" : "44444444", "name" : "crep", "children" : [] },
          { "pk" : "22222222", "name" : "keper", "children" : [] },
          { "pk" : "11111111", "name" : "show", "children" : [] }
        ] }
      ] },
      { "pk" : "791", "name" : "dodge_charger", "children" : [
        { "pk" : "801", "name" : "mustang", "children" : [
          { "pk" : "84257651", "name" : "shen", "children" : [
          ] }
        ] },
        { "pk" : "2", "name" : "hnumber201", "children" : [
          { "pk" : "595020", "name" : "civic", "children" : [] },
          { "pk" : "11", "name" : "lemp", "children" : [] }
        ] }
      ] }
    ] }
  ]
}

With my present code, I can able to get only the children of children of pk = 1. But the deep recursion is not happening.

Collection<GatherEntity> gatherEntityChildren= gatherManager.findByParentGatherId(1);
getRecursiveGatherFromParent(gatherEntityChildren, gatherListParent);   

private List<Gather> getRecursiveGatherFromParent(Collection<GatherEntity> gatherEntityChildren, List<Gather> gatherListParent) throws JSONException {      


        if(gatherEntityChildren != null && gatherEntityChildren.size() > 0) {
            for (Iterator<gatherEntity> iterator = gatherEntityChildren.iterator(); iterator.hasNext();) {
                GatherEntity gatherEntity = (GatherEntity) iterator.next();

                Gather gather = getGatherFromEntity(gatherEntity);
                List<Gather> gatherChildren = populateGatherAndChild(gatherEntity);
                gather.setChildren(new HashSet<Gather>(gatherChildren));
                gatherListParent.add(gather);
            }   
        }
        return gatherListParent;
    }

    private List<Gather> populateGatherAndChild(GatherEntity gatherEntity) {
        Collection<GatherEntity> gatherEntityChildren= gatherManager.findByParentGatherId(gatherEntity.getGatherId());
        List<Gather> gatherList = gatherEntityChildren.stream().map(UserAPIImpl::getGatherFromEntity).collect(Collectors.toList());      
        return gatherList;
    }

    private static Gather getGatherFromEntity(GatherEntity gatherEntity) {
        Gather gather = new Gather();
        gather.setGatherId(gatherEntity.getGatherId());
        gather.setName(gatherEntity.getName());
        return gather;
    }
sjain
  • 23,126
  • 28
  • 107
  • 185
  • I'm not sure you interested; but for a pure PostgreSQL solution, have a look at http://stackoverflow.com/a/25683134/1499698 – pozs Oct 17 '16 at 08:20

1 Answers1

1

You have missed the recursive call on the children:

        if(gatherEntityChildren != null && gatherEntityChildren.size() > 0) {
        for (Iterator<gatherEntity> iterator = gatherEntityChildren.iterator(); iterator.hasNext();) {
            GatherEntity gatherEntity = (GatherEntity) iterator.next();

            Gather gather = getGatherFromEntity(gatherEntity);
            Collection<GatherEntity> gatherChildren = populateGatherAndChild(gatherEntity);

            List<Gather> gatherList = gatherEntityChildren.stream().map(UserAPIImpl::getGatherFromEntity).collect(Collectors.toList());
            gather.setChildren(new HashSet<Gather>(gatherList));
            gatherListParent.add(gather);

            getRecursiveGatherFromParent(gatherChildren, gatherListParent);
        }
    }
    return gatherListParent;
}

private List<GatherEntity> populateGatherAndChild(GatherEntity gatherEntity) {
    return gatherManager.findByParentGatherId(gatherEntity.getGatherId());
}
aviad
  • 1,553
  • 12
  • 15
  • It is giving StackOverError. I think this is because pk = 1 and parent_pk =1 so `findByParentGatherId(1)` is always the same. In other words, the children of `1` is also having `1`. I need to put some condition so that once parent =1 is set then don't process it again. – sjain Oct 17 '16 at 09:01
  • The first argument of my recursive function `gatherEntityChildren` is overwritting the previous values on the next subsequent recursive calls. That's the problem now that I am facing. – sjain Oct 17 '16 at 13:01
  • Interesting, I dont see why since every level you create new list of children. Let me know if you find what was the problem – aviad Oct 17 '16 at 13:24
  • Every level I am creating a new list of children but the previous level list is not completed. So it is overwritten by new list. For example: First Level list is having two children `a1` and `a2`. So it only recursively processes `a1` and its other children but `a2` is still un-processed and the second level iterator overwritten it. – sjain Oct 17 '16 at 13:29