I'm new to Apex (actually in programming in general) and am trying to build a hierarchy tree with 4 objects: Account, Carteira__c, Produtos_das_carteiras__r and AtivosFundo__c

One Account can have N Carteira__c

One Carteira__c can have N Produtos_das_carteiras__r

One Produtos_das_carteiras__r can have N AtivosFundo__c

I wrote the code below as my Controller:

Public with sharing class TreeDetalhes {
Private final Account acct;
Public TreeDetalhes(ApexPages.StandardController stdController) {
    this.acct = (Account)stdController.getRecord();

Class cNodes {
Public Account gparent {get;set;}
Public List<Carteira__c> parent {get; set;}
Public List<AtivosFundo__c> gchildren {get; set;}

Public cNodes(Account gp, List<Carteira__c> p, List<AtivosFundo__c> gc)
 gparent = gp;
 parent = p;
 gchildren = gc;

Public List<cNodes> hierarchy;

Public List<cNodes> getmainnodes()
    hierarchy = new List<cNodes>();
    List<Account> tempparent = [Select Id,Name from Account where id = :acct.Id];
    for (Integer i =0; i< tempparent.size() ; i++)
        List<Carteira__c> tempchildren = [Select Id,Name,(Select Id,Aloc__c, Fundos__r.Name, Fundos__c from Produtos_das_carteiras__r r) from Carteira__c where Integrante__c = :tempparent[i].Id];
        List<AtivosFundo__c> tempativos = new List<AtivosFundo__c>();
        List<AtivosFundo__c> check = new List<AtivosFundo__c>();
        for (Carteira__c c : tempchildren) {
            for (AtivosCarteira__c ac : c.Produtos_das_carteiras__r) {
                check = [Select Id, FundoRelacionado__r.Name, Aloc__c From AtivosFundo__c where Fundos__c = :ac.Fundos__c];
                if (check.size() > 0){
                tempativos.add([Select Id, FundoRelacionado__r.Name, Aloc__c From AtivosFundo__c where Fundos__c = :ac.Fundos__c]); 
    hierarchy.add(new cNodes(tempparent[i],tempchildren,tempativos));
    return hierarchy;

And that's my VFPage code:

<apex:page sidebar="false" standardController="Account" extensions="TreeDetalhes" lightningStylesheets="true" tabStyle="Account" showheader="false">
<!-- Incluindo Jquery Script  -->
<link rel="stylesheet" href= {!URLFOR($Resource.Jtreeview,'Jquerytreeview/jquery.treeview.css')}"/>
<script src="{!URLFOR($Resource.Jtreeview,'Jquerytreeview/jquery.js')}" type="text/javascript"></script>
<script src="{!URLFOR($Resource.Jtreeview,'Jquerytreeview/jquery.cookie.js')}" type="text/javascript"></script>
<script src="{!URLFOR($Resource.Jtreeview,'Jquerytreeview/jquery.treeview.js')}" type="text/javascript"></script>
<!-- Fim -->
<script type="text/javascript">
        $(function() {
            collapsed: false,
            animated: "medium",
            persist: "location"
<br/> <br/> <br/>
<!-- Tree -->
<div class="treeheader" >&nbsp;</div>
<div id="sidetreecontrol"><a href="?#"><font style="color:blue;">Collapse All</font></a> | <a href="?#"><font style="color:blue;">Expand All</font></a> 
    <ul id="tree">
<apex:repeat value="{!mainnodes}" var="parent">
    <li><h2><strong><apex:outputtext style="color:#333333;" escape="false" value="{!parent.gparent.Name}"/></strong></h2>
             <apex:repeat value="{!parent.parent}" var="cart">
                 <li><h3><span class="formattextcon"><apex:outputtext style="color:#808080;" escape="false" value="{!cart.Name}"/></span></h3>
                        <apex:repeat value="{!cart.Produtos_das_carteiras__r}" var="acart">
                           <li> <span class="formattextcon"> <apex:outputtext escape="false" style="color:red;" value="{!acart.Fundos__r.Name}"/> <b>||</b> &nbsp;<apex:outputtext escape="false" value="{!acart.Aloc__c}"/> %</span> </li>
                                <apex:repeat value="{!parent.gchildren}" var="gativo">
                                    <li> <span class="formattextcon"> <apex:outputtext escape="false" style="color:blue;" value="{!gativo.FundoRelacionado__r.Name}"/> <b>||</b> &nbsp;<apex:outputtext escape="false" value="{!gativo.Aloc__c}"/> %</span> </li>

The problem is the return: as you can see in this image

The blues was suppost to be the last level, but I think I'm doing something wrong with the lists, because the blues are not under their parent. The records are correct, but it was to show only one blue for each red, (not the whole list for everyone)

Can someone help me, please?

2 Answers 2


If you're building a "tree" I don't think list is what you want.

I would probably do a wrapper class:

public class accountWrapper {
    Account obj;
    List<CarteiraWrapper> carteiras;

    public accountWrapper (Account obj) {
        this.obj = obj;
        carteiras = new List<CarteiraWrapper>();

public class CarteiraWrapper {
    Carteira__c obj;
    List<ProdutosDasCarteirasWrapper> produtos;

    public CarteiraWrapper (Carteira__c obj) {
        this.obj = obj;
        produtos = new List<ProdutosDasCarteirasWrapper>();

public class ProdutosDasCarteirasWrapper() {
    Produtos_das_carteiras__c obj;
    List<AtivosFundo__c> ativosFundos;

    public ProdutosDasCarteirasWrapper(Produtos_das_carteiras__c obj) {
        this.obj = obj;
        ativosFundos = new List<AtivosFundo__c>();

Then something like this:

List<accountWrapper> accounts = /* What ever you do to get this info */;

for (AccountWrapper aw : accounts) {
    for (CarteiraWrapper cw : aw.carteiras) {
        for (ProdutosDasCarteirasWrapper pw : cw.produtos) {
            for (AtivosFundo__c af : pw.ativosFundos) {
                /* Do Stuff */;


You could also probably do maps of maps of maps of maps if you wanted

Map<Account, Map<Carteira__c, Map<Produtos_das_carteiras__r, AtivosFundo__c>>>

This has other issues that you may want to consider so I don't recommend it.


There's a lot of ways to build out a tree, but I would avoid just using lists.


It's not working gNerb :( I made the wrapper classes but when I'm writting the controller i'm recieving the error "Expecting '}' but was: 'for'" at the first for:

Public with sharing class TreeController {
Private final Account acct;
Public TreeController(ApexPages.StandardController stdController) {
    this.acct = (Account)stdController.getRecord();
List<Account> tempaccount = [Select Id,Name from Account where id = :acct.Id];
List<AccountWrapper> accounts; 
for (Account temp : tempaccount) {
    AccountWrapper acc = new AccountWrapper();
    acc.Id = temp.Id;
    acc.Name = temp.Name;

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .