Duvida query do hibernate

Pessoal to quebrando a cabeça aqui usando um HQL deve ser coisa facil mas nao to conseguindo fazer funcionar…

Tenho duas Classes Pai -> Filho 1 pai pode ter varios filhos, so que estou trabalhando com delecao logica , ou seja, tenho uma coluna ativo que é marcada como não,
so que não to conseguindo fazer um query que so traga os ativos , estou tentando

select p from Pai p left join p.filhos c where c.ativo = :ativo and p.id = :paiId

classe Pai

@Entity
public class Pai {
         @Id
         @GeneratedValue
         private Long id;

         private String nome;

         @OneToMany
         private List<Filho> filhos;

         //getters,setters
}

classe Filho

@Entity
public class Filho{
         @Id
         @GeneratedValue
         private Long id;

         private String nome;

         //getters,setters
}

Alguem poderia me ajudar??

O left join trás todos os registros , relacionados ou não…

Usa o inner join (join simples)

Mas essa sua query está trazendo todos ou nenhum dos itens ativos? Você poderia postar mais detalhes do mapeamento (tipo do atributo ativo, etc…)

Troque isso:

select p from Pai p left join p.filhos c where c.ativo = :ativo and p.id = :paiId

Por isso:

select p from Pai p inner join fetch p.filhos c where c.ativo = :ativo

[quote=vinicius.martinez]Troque isso:

select p from Pai p left join p.filhos c where c.ativo = :ativo and p.id = :paiId

Por isso:

select p from Pai p inner join fetch p.filhos c where c.ativo = :ativo

[/quote]

Oww rapaz funcionou era isso mesmo!! Brigadão pela ajuda!!!

Putz essa query ta ficando cada veis mais nervosa a resposta de cima funcionou beleza so que tem mais uma classe ainda que eu preciso ordenar os resultados
porque ainda 1 filho pode ter varios brinquedos e cada um tem a ordem em que eles devem ser guardados ai tentei continuar a query utilizando abaixo.

select p from Pai p inner join fetch p.filhos c inner join fetch c.brinquedos b where c.ativo = :ativo and b.ativo = :ativo order by b.ordem asc

Mas dai levei uma exception na cara…
Exception in thread “main” org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags

Alguem se habilita?? Sou novo no uso de hibernate e to me enroscando bastante com relacionamento…
Vo postar as classes pra ver se alguem me ajuda

Basicamente preciso de um select da classe principal pai em que ele busque todos os filhos ativos e todos os brinquedos ativo ordenados pela ordem em que são guardados…

Pq vo correr dentro dele

Pai pai = (Pai) session.createQuery("a query que eu nao sei...");
syso("Nome do pai"+pai.getNome());
for(Filho filho:pai.getFilhos()){
     syso("Nome do filho"+filho.getNome()+"=> Ativo : "+filho.getAtivo());
     for(Brinquedo brinquedo:filho.getBrinquedos){
        syso("Ordem do brinquedo =>"+brinquedo.getOrdem());
     }
}
   @Entity  
    public class Pai {  
             @Id  
             @GeneratedValue  
             private Long id;  
      
            private String nome;  
      
            @OneToMany  
            private List<Filho> filhos;  
     
            //getters,setters  
   }  
@Entity
public class Filho{
         @Id
         @GeneratedValue
         private Long id;

         private String nome;

         private char ativo='S';

         @OneToMany  
         private List<Brinquedo> brinquedos;  

         //getters,setters
}
@Entity
public class Filho{
         @Id
         @GeneratedValue
         private Long id;

         private Integer ordem;

         private char ativo='S'

         //getters,setters
}

Ve q cuticuti fazendo com criteria…

List&lt;Pais&gt; pais = session .createCriteria(Pai.class) .createAliase("filho","F") .add(Restrictions.eq("F.ativo",'S')) .list();

easy way em ?

agora com comentarios…

List&lt;Pais&gt; pais = session .createCriteria(Pai.class) //Cria um criterio de busca para PAI .createAliase("filho","F") //Agora marque um alias para o campo "filho", com "F" .add(Restrictions.eq("F.ativo",'S')) //Adicione uma restrição onde o campo ativo do objeto F seja igual ao caracter S .list(); //me liste os resultados

[quote=Lavieri]Ve q cuticuti fazendo com criteria…

List&lt;Pais&gt; pais = session .createCriteria(Pai.class) .createAliase("filho","F") .add(Restrictions.eq("F.ativo",'S')) .list();

easy way em ?

agora com comentarios…

List&lt;Pais&gt; pais = session .createCriteria(Pai.class) //Cria um criterio de busca para PAI .createAliase("filho","F") //Agora marque um alias para o campo "filho", com "F" .add(Restrictions.eq("F.ativo",'S')) //Adicione uma restrição onde o campo ativo do objeto F seja igual ao caracter S .list(); //me liste os resultados[/quote]

Mas mesmo assim ainda ta faltando coisa nessa criteria…
Ainda faltou relacionar filho com brinquedos ativos ordenados pela ordem…

.addOrder(Order.asc("nome da propriedade"))

vc pode inclusve adicionar várias ordens…

List&lt;Pais&gt; pais = session .createCriteria(Pai.class) .createAliase(&quot;filho&quot;,&quot;F&quot;) .add(Restrictions.eq(&quot;F.ativo&quot;,'S')) .addOrder(Order.asc(&quot;F.ordem&quot;)) .list();

Obs… se o que vc quer, é que a lista de Filha -> Neto seja ordenado, vc pode fazer assim

class Filho { @Order(&quot;ordem&quot;) //agora os netos são ligados aos filhos ordenadamente pelo atributo ordem do neto public List&lt;Neto&gt; netos() { } }

[quote=Lavieri].addOrder(Order.asc("nome da propriedade"))

vc pode inclusve adicionar várias ordens…

List&lt;Pais&gt; pais = session .createCriteria(Pai.class) .createAliase(&quot;filho&quot;,&quot;F&quot;) .add(Restrictions.eq(&quot;F.ativo&quot;,'S')) .addOrder(Order.asc(&quot;F.ordem&quot;)) .list();

Obs… se o que vc quer, é que a lista de Filha -> Neto seja ordenado, vc pode fazer assim

class Filho { @Order(&quot;ordem&quot;) //agora os netos são ligados aos filhos ordenadamente pelo atributo ordem do neto public List&lt;Neto&gt; netos() { } }
[/quote]

Humm agora foi em lavieri a solucao era esse ordem na collection mesmo…brigadão pela ajuda…

Se sabe me explicar porque o hibernate nao faz 2 fetch inner join…pois parece ser algo tão normal…

1 Pai -> N Filho ---- 1 Filho -> N Brinquedos

Outra coisa estranha que não entendi… porque eu preciso usar esse fetch pra falar pra eles colocar dentro das classes o que foi passado na query…

A query em si ja não bastaria ? Ele nao teria de popular de acordo com a query realizada??

Por exemplo :

select p from Pai p inner join p.filhos f inner join f.brinquedos b where f.ativo = :ativo and b.ativo = :ativo order by b.ordem asc

Porque ele nao aceita isso ?? Quando eu usava um framework ORM pra php no caso eu passa o HQL e ele populava as classes certinho de acordo com a query passada…
Não entendi muito bem qual a do hibernate em relação a isso e porque preciso dos fetch e porque ele nao aceita 2 fetch na mesma query…

Alguem saberia me explicar??

O Hibernate não aceito duplos fechs…

isso é uma regra dele… ele não popula 2 relacionamentos diferentes de 1 pra muitos…

o motivo real disso eu não sei…

a saber:

popular 1-N é bem perigoso e pode causar transtornos…

vc pode escolher que campos buscar em uma consulta, e como popular um objeto com eles

eu não uso 1-N, não uso pq causa tantos problemas, que não caberia listar nesse post, já li em diversos lugares pra não fazer isso, ja achei que em alguns casos eu deveria fazer, e sempre, inevitavelmente, eu me arrepdendi de ter usado, e parei…

apesar de vc não conseguir fazer o que queria… conseguria listar todos os NETOS, e fazer fecht nele até o pai, e essa sim seria uma abordagem coerente… mas o contrario o hiberante julga perigoso…

[quote=Lavieri]O Hibernate não aceito duplos fechs…

isso é uma regra dele… ele não popula 2 relacionamentos diferentes de 1 pra muitos…

o motivo real disso eu não sei…

a saber:

popular 1-N é bem perigoso e pode causar transtornos…

vc pode escolher que campos buscar em uma consulta, e como popular um objeto com eles

eu não uso 1-N, não uso pq causa tantos problemas, que não caberia listar nesse post, já li em diversos lugares pra não fazer isso, ja achei que em alguns casos eu deveria fazer, e sempre, inevitavelmente, eu me arrepdendi de ter usado, e parei…

apesar de vc não conseguir fazer o que queria… conseguria listar todos os NETOS, e fazer fecht nele até o pai, e essa sim seria uma abordagem coerente… mas o contrario o hiberante julga perigoso…

[/quote]

Nossa num sabia desse problema em relacionamentos 1-N, mas como voce resolveria sem esses relacionamentos 1-N , tem algum material que voce indicaria??

Nao sei bem te indiciar… eu ja li EJB in Action… e gostei…

de mais a mais, vc so precisa lembrar de popular apenas o lado sem o mappedBy, assim vc protege bem sua aplicacao …

por exemplo

Pais 1->N Estado -> 1-N Cidade -> 1-N Bairro

em vez de vc criar os relacionamentos 1-N … vc so escreve a outra ponta, o N-1

[code]public Bairro {
private Long id;
private String nome;
private String abreviacao;
private Cidade cidade;

//getters n setters

@ManyToOne
public Cidade getCidade() {
return cidade;
}
}[/code]

[code]public Cidade {
private Long id;
private String nome;
private Estado cidade;

//getters n setters

@ManyToOne
public Estado getEstado() {
return cidade;
}

//nada de List<Bairro> … apenas a ponta @ManyToOne apaerece
}[/code]

quando precisa do getBairros de uma cidade… vc faz o seguinte…

“select from Bairro b where b.cidade = :cidade” e pronto

[quote=Lavieri]Nao sei bem te indiciar… eu ja li EJB in Action… e gostei…

de mais a mais, vc so precisa lembrar de popular apenas o lado sem o mappedBy, assim vc protege bem sua aplicacao …

por exemplo

Pais 1->N Estado -> 1-N Cidade -> 1-N Bairro

em vez de vc criar os relacionamentos 1-N … vc so escreve a outra ponta, o N-1

[code]public Bairro {
private Long id;
private String nome;
private String abreviacao;
private Cidade cidade;

//getters n setters

@ManyToOne
public Cidade getCidade() {
return cidade;
}
}[/code]

[code]public Cidade {
private Long id;
private String nome;
private Estado cidade;

//getters n setters

@ManyToOne
public Estado getEstado() {
return cidade;
}

//nada de List<Bairro> … apenas a ponta @ManyToOne apaerece
}[/code]

quando precisa do getBairros de uma cidade… vc faz o seguinte…

“select from Bairro b where b.cidade = :cidade” e pronto[/quote]

Um entendi sua ideia em relacao ao mapeamento !! Obrigado pela explicação!!!

[quote=boneazul][quote=Lavieri]Nao sei bem te indiciar… eu ja li EJB in Action… e gostei…

de mais a mais, vc so precisa lembrar de popular apenas o lado sem o mappedBy, assim vc protege bem sua aplicacao …

por exemplo

Pais 1->N Estado -> 1-N Cidade -> 1-N Bairro

em vez de vc criar os relacionamentos 1-N … vc so escreve a outra ponta, o N-1

[code]public Bairro {
private Long id;
private String nome;
private String abreviacao;
private Cidade cidade;

//getters n setters

@ManyToOne
public Cidade getCidade() {
return cidade;
}
}[/code]

[code]public Cidade {
private Long id;
private String nome;
private Estado cidade;

//getters n setters

@ManyToOne
public Estado getEstado() {
return cidade;
}

//nada de List<Bairro> … apenas a ponta @ManyToOne apaerece
}[/code]

quando precisa do getBairros de uma cidade… vc faz o seguinte…

“select from Bairro b where b.cidade = :cidade” e pronto[/quote]

Um entendi sua ideia em relacao ao mapeamento !! Obrigado pela explicação!!![/quote]

Mas ainda restou uma ultima duvida.

Se eu precisasse saber a partir de uma pais todas as cidades ? Não teria como teria??
e se eu tivesse uma relação pro usuario que faça uma treeview com isso tudo?? descartando uso de ajax é claro.

Como ficaria por nao tenho a parte onetomany.

entao nao conseguiria usar

select from Pais p inner join fetch p.cidades c inner join fetch c.bairros b and p.ativo = :ativo and b.ativo = :ativo and c.ativo = :ativo where p.id = :paisId

Ou seja me traga tudo relacionado a 1 pais com id tal

e a treeview ficasse assim

BRASIL
|---------SÃO PAULO
|---------------CENTRO
|---------------LAVAPÉS
|
|---------RIO DE JANEIRO
|---------------GAVIA
|---------------COPACABANA

isso fazendo analogia a outras classes , como voce resolveria?

Voce cria uma classe intermediaria e 3 querys?

Pq precisaria saber se brasil esta ativo
Ai quais cidades do brasil esta ativa
Ai qual bairro da cidade esta ativa

[quote=boneazul][quote=Lavieri]Nao sei bem te indiciar… eu ja li EJB in Action… e gostei…

de mais a mais, vc so precisa lembrar de popular apenas o lado sem o mappedBy, assim vc protege bem sua aplicacao …

por exemplo

Pais 1->N Estado -> 1-N Cidade -> 1-N Bairro

em vez de vc criar os relacionamentos 1-N … vc so escreve a outra ponta, o N-1

[code]public Bairro {
private Long id;
private String nome;
private String abreviacao;
private Cidade cidade;

//getters n setters

@ManyToOne
public Cidade getCidade() {
return cidade;
}
}[/code]

[code]public Cidade {
private Long id;
private String nome;
private Estado cidade;

//getters n setters

@ManyToOne
public Estado getEstado() {
return cidade;
}

//nada de List<Bairro> … apenas a ponta @ManyToOne apaerece
}[/code]

quando precisa do getBairros de uma cidade… vc faz o seguinte…

“select from Bairro b where b.cidade = :cidade” e pronto[/quote]

Um entendi sua ideia em relacao ao mapeamento !! Obrigado pela explicação!!![/quote]

Mas ainda restou uma ultima duvida.

Se eu precisasse saber a partir de uma pais todas as cidades ? Não teria como teria??
e se eu tivesse uma relação pro usuario que faça uma treeview com isso tudo?? descartando uso de ajax é claro.

Como ficaria por nao tenho a parte onetomany.

entao nao conseguiria usar

select from Pais p inner join fetch p.cidades c inner join fetch c.bairros b and p.ativo = :ativo and b.ativo = :ativo and c.ativo = :ativo where p.id = :paisId

Ou seja me traga tudo relacionado a 1 pais com id tal

e a treeview ficasse assim

BRASIL
|---------SÃO PAULO
|---------------CENTRO
|---------------LAVAPÉS
|
|---------RIO DE JANEIRO
|---------------GAVIA
|---------------COPACABANA

isso fazendo analogia a outras classes , como voce resolveria?

Voce cria uma classe intermediaria e 3 querys?

Pq precisaria saber se brasil esta ativo
Ai quais cidades do brasil esta ativa
Ai qual bairro da cidade esta ativa