Pesquisa com criteria em tabelas many to many e many to one

5 respostas
J

Pessoal, to com um problema pra fazer uma pesquisa com criteria

tenho a classe Montadora, que possui uma lista de carros

@OneToMany(cascade = CascadeType.ALL)
     private List<Carros> listaDeCarros;
E tenho a classe Carros, que possui uma referencia a classe pecas com many to many:
@ManyToMany(mappedBy = "listaDeCarros")
    @NotFound(action=NotFoundAction.IGNORE)
    private java.util.List<Pecas> listaDePecas;
	.
	.
	.
	@ManyToOne(optional = true)
      private Montadora montadora;
tambem tenho a classe Pecas, referenciando os Carros da seguinte forma
@ManyToMany(cascade = { CascadeType.MERGE})
    private java.util.List<Carros> listaDeCarros;
O problema esta acontecendo quando quero, por exemplo, buscar uma lista de pecas que faça parte de uma lista de carros de determinada montadora.

Por exemplo: quero todos os carburadores que caibam em qualquer carro da montadora FORD.

sei que pra pegar os carros da montadora FORD basta:
Root<Montadora> mont = criteriaQuery.from(Montadora>.class);
            criteriaQuery.select(mont);
                                  criteriaQuery.where(criteriaBuilder.equal(mont.get("nome"), "FORD"));
            TypedQuery<Montadora> query = entityManager.createQuery(criteriaQuery);
            return query.getSingleResult().getListaDeCarros;
o problema agora eh nesta mesma funcao retornar as pecas deste carro, sendo que ao contrario da Montadora, que eh unica, posso ter N pecas no mesmo veiculo, entre elas o carburador Alguem pode me ajudar com alguma ideia? Obrigado.

5 Respostas

D

Seguinte. Como o relacionamento entre carro e montadora é one to many, carro possui uma FK referenciando montadora, certo?
Bem, partindo daí, você pode instanciar o Criteria para tua entity carro, com um alias para Montadora (pelo nome da montadora) e aí fazer a lista de peças que quiser.

J

cara, nao entendi a logica ainda…

vc diz eu pegar todos os resultdaos dos carros da montadora e depois filtrar as pecas deste carro?

se sim, como conseguiria fazer isso?

D

Assim, quando você instancia

Root<Montadora> mont = criteriaQuery.from(Montadora.class);

Você consegue todos os dados de montadora, incluindo a lista de carros.
Agora, se você fizer

Root<Montadora> mont = criteriaQuery.from(Carro.class);

Você pode criar um alias para montadora, além de, conseguir pegar a lista de peças.

J

Deixa eu ver se eu consigo entender o raciocinio:

primeiro devo pegar os carros pela Montadora:

Root<Montadora> mont= criteriaQuery.from(Montadora.class);
        criteriaQuery.select(mont);
        Predicate predicate= criteriaBuilder.equal(mont.get("nome"), "FORD");
  TypedQuery<Montadora> tq= entityManager.createQuery(criteriaQuery);

Montadora montNew = tq.getSingleResult();

feito isso, o problema de filtrar pela montadora ta resolvido

List<Carros> listaDeCarros = montNew.getListaDeCarros();

O proximo passo seria pegar a lista de pecas destes carros e verificar se nesta lista contem as pecas que passei como parametro, e se sim, recupero o carro.

mas eh nesta parte que nao consigo fazer mais nada, pois nao sei como fazer um query pra comparar as duas listas, eu pensei em usar o IN, mas nao consegui nada de util.

Pode me ajudar nesta parte?

D

Não, camarada.
Você vai criar um Criteria para pesquisar sobre Carro, ok?

Criteria criteria = session.createCriteria(Carro.class);

Então, você cria um Alias

criteria.createAlias("montadora_id", "mont");

Passa o código da montadora

criteria.add(Restriction.like("mont", 1);

Aí faz o outro Restriction para buscar as peças que deseja.
Deve retornar o código que você precisa.

Criado 24 de junho de 2011
Ultima resposta 24 de jun. de 2011
Respostas 5
Participantes 2