Carregar lista de objetos om um único acesso ao Banco

5 respostas
acesar

Tenho as seguintes classes:
Pais 1 X N Estado 1 X N Municipio 1 X N Propriedade

@Entity
public class Pais implements Serializable{

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
private Long id;

@Column(nullable=false, unique=true)
@NotNull
private String nome;

@OneToMany(mappedBy="pais")
private List<Estado> estados;

@Entity
public class Estado implements Serializable{

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
private Long id;

@Column(nullable=false, unique=true)
@NotNull
private String nome;


@ManyToOne(fetch=FetchType.LAZY)
@NotNull
private Pais pais;

@OneToMany(mappedBy="estado")
private List<Municipio> municipios;

@Entity
public class Municipio implements Serializable{

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
private Long id;

@Column(nullable=false, unique=true)
@NotNull
private String nome;

@ManyToOne(fetch=FetchType.LAZY)
@NotNull
private Estado estado;

@OneToMany(mappedBy="municipio")
private List<Propriedade> propriedades;

@Entity
public class Propriedade implements Serializable{

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
private Long id;

@Column(nullable=false)
@NotNull
private String nome;

@Column(nullable=false)
@NotNull
private Date dataCriacao;

@ManyToOne(fetch=FetchType.LAZY)
@NotNull
private Municipio municipio;

Bom, a partir deste modelo de classes, criei uma nova classe para amazenar uma lista que já pudesse ser carregada com os devidos objetos organizados, ou seja, para poder carregar uma lista de todas as propriedades com seus respectivos municipios, estados e países.

public class PropriedadeMunEstPaObj implements Serializable{

private static final long serialVersionUID = 1L;

private Propriedade propriedade;
private Municipio municipio;
private Estado estado;
private Pais pais;

No meu pacote DAO criei a classe PropriedadeDAO e coloquei o consulta que retorna todos os dados.

@SuppressWarnings(unchecked)

public List<PropriedadeMunEstPaObj> listaPropriedadeMunEstPaObjs(){

String sql = "from Propriedade propriedade " +

"join propriedade.municipio as municipio " +

"join municipio.estado as estado " +

join estado.pais as pais;

Query query = ss.createQuery(sql);

return query.list();

}

A query executada no banco é :

?select
propriedad0_.id as id4_0_,
municipio1_.id as id8_1_,
estado2_.id as id7_2_,
pais3_.id as id6_3_,
propriedad0_.dataCriacao as dataCria2_4_0_,
propriedad0_.marker as marker4_0_,
propriedad0_.municipio_id as municipio6_4_0_,
propriedad0_.nome as nome4_0_,
propriedad0_.zoom as zoom4_0_,
municipio1_.estado_id as estado4_8_1_,
municipio1_.marker as marker8_1_,
municipio1_.nome as nome8_1_,
estado2_.nome as nome7_2_,
estado2_.pais_id as pais3_7_2_,
pais3_.nome as nome6_3_
from
Propriedade propriedad0_
inner join
Municipio municipio1_
on propriedad0_.municipio_id=municipio1_.id
inner join
Estado estado2_
on municipio1_.estado_id=estado2_.id
inner join
Pais pais3_
on estado2_.pais_id=pais3_.id?

[b]e retorna todas as colunas de todas as tabelas…

mas quando executo o teste…[/b]

public static void main(String[] args) {

Long inicio = System.currentTimeMillis();
	
	Session session = new HibernateUtil().getSession();
	session.getTransaction().begin();
	List&lt;PropriedadeMunEstPaObj&gt; propriedadeMunEstPaObjs = new PropriedadeDAO(session).listaPropriedadeMunEstPaObjs();
	for(PropriedadeMunEstPaObj result: propriedadeMunEstPaObjs){
		result.getPais().getNome();
		result.getEstado().getNome();
		result.getMunicipio().getNome();
		result.getPropriedade().getNome();
	}
	session.getTransaction().commit();
	session.close();		
	
	Long fim = System.currentTimeMillis();
	
	System.out.println("");
	System.out.println("Execução em " +(fim - inicio) + " ms.");
}

}

[b]Ocorre o seguinte erro…

Exception in thread “main” java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to br.com.frontfaces.view.PropriedadeMunEstPaObj
at br.com.frontfaces.testes.TestaListaPropriedadeMunEstPaObjs.main(TestaListaPropriedadeMunEstPaObjs.java:20)

Minha intenção é carregar toda esta lista com 1 único acesso ao Banco de Dados…
Não sei se estou indo para o lado certo… Consegui carregar a lista descrita, mas somente com vários acessos ao banco de dados…
Agradeço se puderem me sugerir uma maneira de fazer isso…
[/b]

5 Respostas

romarcio

Coloca seu codigo entre as tags CODE, para melhorar a visualização.

Se está usando Hibernate ou outro Framework de persistência, basta mapear corretamente os relacionamentos que ao carregar País já terá todos os objetos carregados também.

Veja, você teria a classe Pais que tem um atributo com todos os Estados. Estados tem um atributo com todos os Municípios e Municípios tem um atributo com todas Propriedades. Então ao carregar Pais, tera todos outros carregados também dentro de cada objeto.

Não precisa criar um classe extra (PropriedadeMunEstPaObj) para fazer isso.

Uma consulta simples no banco em País, já te trará todos os dados que você quer.

acesar

ola romarcio, obrigado pela resposta…
Eu estou usando o Hibernate com JSF e Primefaces… Estou carregando um datatable com o nome do Pais, nome do Estado, nome do Municipio e nome da Propriedade. Criei o objeto PropriedadeMunEstPaObj, e dentro do meu Bean eu carrego uma lista com esta classe e depois monto o datatable na tela.
Como estou usando o Fetch Lazy ao carregar o Pais eu preciso chamar o metodo getEstados para carregar os Estados, e na sequencia, para cada Estado tenho que chamar getMunicipios, e assim por diante…
Isso gera uma série de “chamadas” no banco de dados para carregar minha lista.
Eu estou tentado fazer isso gerando apenas uma execução de query no banco de dados…

romarcio
acesar:
ola romarcio, obrigado pela resposta.... Eu estou usando o Hibernate com JSF e Primefaces.... Estou carregando um datatable com o nome do Pais, nome do Estado, nome do Municipio e nome da Propriedade. Criei o objeto PropriedadeMunEstPaObj, e dentro do meu Bean eu carrego uma lista com esta classe e depois monto o datatable na tela. Como estou usando o Fetch Lazy ao carregar o Pais eu preciso chamar o metodo getEstados para carregar os Estados, e na sequencia, para cada Estado tenho que chamar getMunicipios, e assim por diante..... Isso gera uma série de "chamadas" no banco de dados para carregar minha lista. Eu estou tentado fazer isso gerando apenas uma execução de query no banco de dados.....

É como eu te disse, faz um consulta na tabela País que te retorne uma lista com todos os Países.

Dai você faz o seguinte:

List<Pais> paises = findAllPais();

//Dai você pode recuperar o Estado, Minicipio e Propriedade assim:

for (Pais p : paises) {
    Estado e = p.getEstado();
    Municipio m = e.getMunicipio();
    Propriedade prop = m.getPropriedade ();
}

O objeto Pais contem todos os outros que você precisa é só usar o método get() de cada um.

Poderia ainda fazer isso:

Propriedade prop = p.getEstado().getMunicipio().getPropriedade();
É só usar os métodos.
acesar

Então, desta forma eu consegui fazer, mas a cada método que eu executo o Hibernate gera um consulta no banco de dados. Sendo assim para eu carregar minha lista com o campos que eu quero preciso gerar uma grande quantidade de “querys” no banco.
Agora percebi que via Hibernate também consigo gerar uma query única com todos os campos da seguinte forma…

String sql = "from Propriedade propriedade " + "join propriedade.municipio as municipio " + "join municipio.estado as estado " + "join estado.pais as pais"; Query query = ss.createQuery(sql); return query.list();

Essa rotina executa a query que, de uma única vez traz a lista de todos os objetos… Mas na hora de carregar a lista da erro de “CAST”…

romarcio

Eu faria assim:

public List&lt;Pais&gt; findAll() {
    return ss.createCriteria(Pais.class).list();
}
Criado 21 de março de 2012
Ultima resposta 22 de mar. de 2012
Respostas 5
Participantes 2