Seguinte, estou fazendo um sistema web usando Hibernate e VisualJSF, e em todos os meus métodos DAO estou retornando uma String (“success” ou “failure”), para fazer o mapeamento no faces.config.xml.
A duvida surgiu neste método do meu UsuarioDAO, pois este método e uma List, e logo deverá retornar uma LIST, porem preciso que ele retorne tambem uma String success ou failure. Como posso fazer isso ?
Obrigado
[code]public List listar() {
try {
sessao = HibernateUtil.getSessionFactory().getCurrentSession();
sessao.beginTransaction();
List l1 = sessao.createQuery(“from jnb_user”).list();
sessao.getTransaction().commit();
resultado = SUCESSO;
return l1;
} catch (HibernateException ex) {
sessao.getTransaction().rollback();
System.err.println(“Erro durante abertura de sessão do banco de dados” + ex);
resultado = FALHA;
return null;
}
}[/code]
Uma forma de você fazer isso é assim:
public String listar (List resultado) {
resultado.clear();
...
List ll = sessao.createQuery...
resultado.addAll (ll);
}
...
...
List resultado = new ArrayList();
String successOrFailure = dao.listar (resultado);
...
Uma observação: voltar uma lista vazia normalmente é melhor que voltar null. É que se o outro lado não ficar esperto para o fato que pode receber null, então vai ocorrer uma NullPointerException, enquanto se você voltar uma lista vazia é mais simples tratar o resultado.
[quote=thingol]Uma forma de você fazer isso é assim:
public String listar (List resultado) {
resultado.clear();
...
List ll = sessao.createQuery...
resultado.addAll (ll);
}
...
...
List resultado = new ArrayList();
String successOrFailure = dao.listar (resultado);
...
Uma observação: voltar uma lista vazia normalmente é melhor que voltar null. É que se o outro lado não ficar esperto para o fato que pode receber null, então vai ocorrer uma NullPointerException, enquanto se você voltar uma lista vazia é mais simples tratar o resultado.
[/quote]
Cara, confesso que nao entendi mto bem isso que vc fez. Poderia me explicar como isso resolve meu problema ? Desculpe se estou sendo chato, mas nao estou afim apenas de dar CTRL C CTRL V no codigo, quero entender e aprender… hehehehe Obrigado !
É assim. Você reserva o retorno do método para retornar o tal status (“success” / “failure”. )
Enquanto isso, você usa o parâmetro como se fosse um parâmetro “de saída”, ou seja, em vez de você passar dados para o método através dele, o método é que copia o resultado dentro desse parâmetro. Isso é muito comum em C, C#, C++, Pascal, VB e outras linguagens que deixam fazer isso (você modificar o parâmetro).
É que a gente se esquece que, embora o Java sempre passe parâmetros por valor e não por referência, ele deixa modificar os objetos que você passou como parâmetros.
Por isso o que fiz foi mais ou menos o seguinte:
-
Dentro do método, pego o parâmetro (que é uma lista), limpo tudo por via das dúvidas, e então chamo o método sessao.createQuery para me retornar um resultado.
-
Então, eu copio a lista dentro da lista que recebi como parâmetro, usando addAll.
-
Quem chama o método deve então criar uma lista vazia, passar para esse método, que a retornará cheia (se o método retornar “success”) ou vazia (se houver um problema e o método retornar “failure”). OK?
Valeu cara, muito esclarecedor sua resposta ! Deu certo aqui !
Mais uma que vai pra minha bagagem de conhecimentos que estou iniciando em Java.
Na verdade eu faria de uma forma um pouco diferente
Eu costumo ter na minha caixa de ferramentas uma classe Pair<T, U> que é uma classe bem boba, só para conter um par de objetos de classes distintas.
Nesse caso, eu retornaria um Pair<String, List>.
Aí o primeiro elemento seria o “success/failure”, e o segundo elemento seria a tal lista. Mas não expliquei desse jeito porque muita gente é contra criar essas classes “nojentas” para fazer esse tipo de coisa.
Entendo, mas se quiser explicar, estou a disposição para ler e estudar sobre, para então decidir. Achei interessante vc falar nessa segunda maneira pq eu tinha pensado justamente na possibilidade de retornar dois objetos, qdo eu me deparei com o problema hoje pela manha.
Eu normalmente codifico a tal classe mais ou menos assim:
[code]
public class Pair < T extends Comparable < T > , U extends Comparable < U > >
implements Comparable < Pair < T, U > > {
public T first;
public U second;
public Pair (T t, U u) { first = t; second = u; }
public int compareTo (Pair < T, U > that) {
// Para simplificar, digo que ambos os campos não podem ser nulos.
int c = first.compareTo (that.first);
if (c != 0) return c;
return second.compareTo (that.second);
}
public String toString() { return “<” + first.toString() + ", " +
second.toString() + “>”; }
}
class Teste {
public Pair < String, Integer > exemplo1 () {
return new Pair < String,Integer > (“Exemplo”, 1);
}
public static void main(String[] args) {
Teste t = new Teste();
Pair < String, Integer > p = t.exemplo1();
System.out.println (p);
}
}[/code]
Essas classes são nojentas?
Então o que falariam de uma classe assim que eu uso.
package mark.utils.map;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class MappedMap<U, T, K> {
private Map<U, Map<T, K>> map = new HashMap<U, Map<T, K>>();
public void put(U firstKey, T secondKey, K value) {
Map<T, K> uMap = map.get(firstKey);
if (uMap == null) {
uMap = new HashMap<T, K>();
map.put(firstKey, uMap);
}
uMap.put(secondKey, value);
}
public K get(U firstKey, T secondKey) {
Map<T, K> uMap = map.get(firstKey);
if (uMap == null)
return null;
return uMap.get(secondKey);
}
public Map<T, K> getMap(U key) {
return map.get(key);
}
public List<U> getKeys() {
List<U> list = new ArrayList<U>();
for (Entry<U, Map<T, K>> ent : map.entrySet())
list.add(ent.getKey());
return list;
}
}