问题描述:

I store articles with multiple tag as follow:

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.ManyToMany;

@Entity

public class Article {

@Id

@GeneratedValue

private Integer id;

@ManyToMany

private List<Tag> tags;

private String subject;

}

and

import javax.persistence.Entity;

import javax.persistence.Id;

@Entity

public class Tag {

@Id

private String name;

private String description;

}

And I want to search articles which contains some tags, for example, like this question hibernate and many-to-many. So I tried as:

import static org.hibernate.criterion.Restrictions.*;

// ...

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

Criteria tagCriteria = criteria.createCriteria("tags");

tagCriteria.add(and(eq("name", "hibernate"), eq("name", "many-to-many")));

@SuppressWarnings("unchecked")

List<Article> list = criteria.list();

but, does not works and returned list is empty because logged SQL shows as:

select

this_.id as id1_1_,

this_.subject as subject1_1_,

tags3_.Article_id as Article1_,

tag1_.name as tags2_,

tag1_.name as name0_0_,

tag1_.description as descript2_0_0_

from

Article this_

inner join Article_Tag tags3_ on this_.id=tags3_.Article_id

inner join Tag tag1_ on tags3_.tags_name=tag1_.name

where

tag1_.name=? // assign 'hibernate'

and

tag1_.name=? // assign 'many-to-many'

When replace and to or returns too many articles because generated SQL was ... where (tag1_.name=? or tag1_.name=?).

What I want exactly may looks like:

select

this_.id as id1_1_,

this_.subject as subject1_1_,

tags3_.Article_id as Article1_,

tag1_.name as tags4_,

tag1_.name as name0_0_,

tag1_.description as descript2_0_0_

from

Article this_

inner join Article_Tag tags3_ on this_.id=tags3_.Article_id

inner join Tag tag1_ on tags3_.tags_name=tag1_.name

// following 2 lines are added

inner join Article_Tag tags4_ on this_.id=tags4_.Article_id

inner join Tag tag5_ on tags4_.tags_name=tag5_.name

where

tag1_.name=? // assign 'hibernate'

and

tag5_.name=? // assign 'many-to-many'

Is it possible when I use HQL only?

网友答案:

You should try something like that:

    Criteria criteria = getSession().createCriteria(Article.class);
    int i=0;
    for ( String tagName : tagNames ) {
        String aliasName = "alias_" + i;
        criteria.createAlias("tags", aliasName, Criteria.INNER_JOIN);
        criteria.add( Restrictions.eq(aliasName+".name",tagName) );
        i++;
    }

Actually the matter is that when you do a simple inner join, ok you have joined your results with the tags but the matter is that the data is actually on 2 rows... So if you join 2 times you'll be able to get the data on one rows.

I think it's not really elegant but it should work...

相关阅读:
Top