Para entender um metodo recursivo, primeiro voce deve entender um metodo recursivo.Eu me orgulho de poucos codigos. ESTE e um deles.--------------------------------------------public class DataObjectMetadataService { @Resource(name = "dataObjectMetadataDAOImpl") private DataObjectMetadataDAO domDAO; private List<Programa> progs = new ArrayList<Programa>(); private Boolean carregaCampos; public List<DataObjectMetadata> createOrRetrieveByClassName(DataObjectMetadataFilter filter) { List<DataObjectMetadata> newDatas = null; this.carregaCampos = filter.getCarregaCampos(); filter.setNmPrograma(domDAO.buscaClassNameCompleto(filter)); progs = domDAO.pesquisaPrograma(filter); if(filter.getNmPrograma() != null) { List<DataObjectMetadata> impedeRetorno = new ArrayList<DataObjectMetadata>(); newDatas = criaEstruturaClasse(filter.getNmPrograma(), impedeRetorno); if(this.carregaCampos){ percorreNivelCampos(newDatas); while(newDatas.get(0).getLevel() == null) { defineNivel(newDatas); } } } return newDatas; } private List<DataObjectMetadata> criaEstruturaClasse(String className, List<DataObjectMetadata> impedeRetorno) { List<DataObjectMetadata> datas = null; try { AbstractEntityPersister persister = buscaPropriedadesBanco(Class.forName(className)); DataObjectMetadata data = new DataObjectMetadata(); data.setClassName(persister.getName()); impedeRetorno.add(data); if(carregaCampos){ datas = montaDadosClasse(persister, impedeRetorno); completaDadosData(datas); } else { datas = montaDadosProgs(persister, impedeRetorno); } } catch(ClassNotFoundException e) { e.printStackTrace(); } return datas; } private <T> AbstractEntityPersister buscaPropriedadesBanco(Object cls) { AbstractEntityPersister persister = null; ClassMetadata hibernateMetadata = domDAO.findHibernateMetadata((Class<?>) cls); if(hibernateMetadata != null) { if(hibernateMetadata instanceof AbstractEntityPersister) { persister = (AbstractEntityPersister) hibernateMetadata; } } return persister; } private List<DataObjectMetadata> montaDadosClasse(AbstractEntityPersister persister, List<DataObjectMetadata> impedeRetorno) { List<DataObjectMetadata> ir = copiaListaRetorno(impedeRetorno); List<DataObjectMetadata> datas = new ArrayList<DataObjectMetadata>(); DataObjectMetadata data = null; if(persister != null) { String[] columnKey = persister.getKeyColumnNames(); String[] columnNames = persister.getPropertyNames(); Type[] columnTypes = persister.getPropertyTypes(); boolean[] columnNullable = persister.getPropertyNullability(); if(columnKey != null) { List<String> keys = new ArrayList<String>(Arrays.asList(columnKey)); for(String key : keys) { data = new DataObjectMetadata(); data.setDataStamp(new Date()); data.setTableName(persister.getTableName()); data.setClassName(persister.getName()); data.setColumnName(key); data.setColumnType("Integer"); data.setIsNullable(SimNao.NAO); data.setIsClassAntara(SimNao.NAO); data.setMustInspectElement(SimNao.NAO); data.setDataObjectMetadata(verificaSubObjetos(data, ir)); datas.add(data); } } if((columnNames != null) && (columnTypes != null)) { List<String> colunas = new ArrayList<String>(Arrays.asList(columnNames)); List<Type> tipos = new ArrayList<Type>(Arrays.asList(columnTypes)); if((colunas != null) && (tipos != null)) { for(int i = 0; i < colunas.size(); i++) { data = new DataObjectMetadata(); data.setDataStamp(new Date()); data.setTableName(persister.getTableName()); data.setClassName(persister.getName()); data.setColumnName(colunas.get(i)); data.setColumnType(tipos.get(i).getName()); data.setIsNullable(columnNullable[i] ? SimNao.SIM : SimNao.NAO); data.setIsClassAntara(isClasseAntara(data.getColumnType())); if(SimNao.SIM.equals(data.getIsClassAntara())) { data.setMustInspectElement(deveInspecionarElemento(data.getColumnType(), ir)); } else { data.setMustInspectElement(SimNao.NAO); } data.setDataObjectMetadata(verificaSubObjetos(data, ir)); datas.add(data); } } } } return datas; } private void completaDadosData(List<DataObjectMetadata> datas) { List<DataObjectMetadata> loadDatas = new ArrayList<DataObjectMetadata>(); loadDatas = domDAO.loadMedatadas(datas); if(loadDatas != null) { for(ListIterator<DataObjectMetadata> it = datas.listIterator(); it.hasNext();) { DataObjectMetadata dom = it.next(); for (DataObjectMetadata load : loadDatas) { if(dom.getTableName().equals(load.getTableName()) && dom.getColumnName().equals(load.getColumnName())){ it.remove(); it.add(load); load.setLevel(null); load.setMustInspectElement(dom.getMustInspectElement()); load.setDataObjectMetadata(dom.getDataObjectMetadata()); if(!StrUtil.validateString(load.getProgramName()) || !StrUtil.validateString(load.getProgramCode())){ completaDadosCampos(load); } break; } } } } loadDatas.clear(); } private List<DataObjectMetadata> copiaListaRetorno(List<DataObjectMetadata> impedeRetorno) { List<DataObjectMetadata> copia = new ArrayList<DataObjectMetadata>(); DataObjectMetadata c = null; for(DataObjectMetadata dom : impedeRetorno) { c = new DataObjectMetadata(); c.setClassName(dom.getClassName()); copia.add(c); } return copia; } private List<DataObjectMetadata> verificaSubObjetos(DataObjectMetadata data, List<DataObjectMetadata> impedeRetorno) { List<DataObjectMetadata> datas = null; if(SimNao.SIM.equals(data.getMustInspectElement())) { datas = criaEstruturaClasse(data.getColumnType(), impedeRetorno); } return datas; } private SimNao isClasseAntara(String columnType) { if(columnType.contains(".")) { String[] caminho = columnType.split(Pattern.quote(".")); int tam = caminho.length; for(int j = 0; j < tam; j++) { if("domain".equals(caminho[j])) { return SimNao.SIM; } else { if("util".equals(caminho[j])) { return SimNao.NAO; } if("java".equals(caminho[j])) { return SimNao.NAO; } if("hibernate".equals(caminho[j])) { return SimNao.NAO; } } } return SimNao.SIM; } return SimNao.NAO; } private SimNao deveInspecionarElemento(String columnType, List<DataObjectMetadata> impedeRetorno) { for(DataObjectMetadata tipoJaUsado : impedeRetorno) { if(columnType.equals(tipoJaUsado.getClassName())) { return SimNao.NAO; } } DataObjectMetadata aux = new DataObjectMetadata(); aux.setClassName(columnType); impedeRetorno.add(aux); return SimNao.SIM; } private void percorreNivelCampos(List<DataObjectMetadata> datas) { Boolean encontrouUltimoNivel = false; for(DataObjectMetadata data : datas) { if(SimNao.SIM.equals(data.getMustInspectElement())) { percorreNivelCampos(data.getDataObjectMetadata()); encontrouUltimoNivel = false; } } if(!encontrouUltimoNivel) { for(DataObjectMetadata