Many to many query com Hibernate

5 respostas
Paulo_Silveira

oi pessoal

tenho uma relacao muitos para muitos, de Curso<–>Oferta
claro que tem uma tabela associativa ai no meio, mas pra mim eh transparente por causa do hibernate.

quero fazer o seguinte select: dado um id de curso, pegar todas as suas ofertas ordenadas por algum campo.

como faco isso com HQL? tentei usar uns IN e tal mas nao rolou.

5 Respostas

ricardolecheta

digamos que no many-to-many em Curso.hbm.xml vc chamou o relacionamento de “ofertas”.

select oferta from Curso as curso inner join curso.ofertas as oferta where curso.id=? order by ....

Se vc quiser deixar transparente, em Curso vai existir um Set ofertas. No xml vc pode definir um atributo order-by para indicar a ordenação na Collection.

Paulo_Silveira

oi ricardo
foi assim mesmo que resolvi! valeu! ele traduz pra dois joins, usando a associativa do meio, doido demais.
com IN o mysql nao tem suporte.

L

Olá Paulo, estou com um problema parecido…

Estou fazendo uma lista paginada, e uma coluna é um campo de outra tabela só que o relacionamento é ManyToMany então não consigo ordenar…

Tem alguma idéia???

Valeu!

faelcavalcanti

acho estranho o mysql não suportá-lo. você tem certeza paulo?

na JSR 220 para especificação [Java Persistence API], especifica a motivação para resolução do seu caso no item 4.4.6 na página 87 onde possui o seguinte trecho:

4.4.6 Collection Member Declarations

An identification variable declared by a collection_member_declaration ranges over values of a collection obtained by navigation using a path expression. Such a path expression represents a navigation involving the association-fields of an entity abstract schema type. Because a path expression can be based on another path expression, the navigation can use the association-fields of related entities.

An identification variable of a collection member declaration is declared using a special operator, the reserved identifier IN. The argument to the IN operator is a collection-valued path expression. The path expression evaluates to a collection type specified as a result of navigation to a collection-valued association-field of an entity abstract schema type.

The syntax for declaring a collection member identification variable is as follows:

collection_member_declaration ::= IN (collection_valued_path_expression) [AS] identification_variable

For example, the query

SELECT DISTINCT o FROM Order o JOIN o.lineItems l JOIN l.product p WHERE p.productType = ?office_supplies?

may equivalently be expressed as follows, using the IN operator:

SELECT DISTINCT o FROM Order o, IN(o.lineItems) l WHERE l.product.productType = ?office_supplies?

In this example, lineItems is the name of an association-field whose value is a collection of instances of the abstract schema type LineItem. The identification variable l designates a member of this collection, a single LineItem abstract schema type instance. In this example, o is an identification variable of the abstract schema type Order.

seguindo a recomendação a partir da especificação, e seguindo o mesmo exemplo do amigo sugerido, obteríamos algo assim:

select object(oferta) from Curso curso, IN(curso.ofertas) oferta where ....

não estou dizendo que a maneira anterior está errada, senão não funcionaria, apenas indicando uma alternativa equivalente e segura em que o uso do operador IN irá garantir de que existe ao menos o relacionamento existente.

geralmente em relacionamentos, sempre existe o dono do relacionamento, mas para o caso de ManyToMany, este não é o caso para entrarmos em detalhes, pois estamos falando apenas em consultas, onde o objetivo final me parece ser apenas obter ofertas de produto(s) especifico(s).

Gobain

Em HQL pode fazer bem simples como:

createQuery("from Ofertas o inner join fetch o.curso c where c.id_curso = " + id_curso + " order by campo_escolhido");
Criado 26 de abril de 2004
Ultima resposta 17 de out. de 2008
Respostas 5
Participantes 5