Hibernate 搜索多个标记的文章-休眠多对多

Hibernate 搜索多个标记的文章-休眠多对多,hibernate,many-to-many,Hibernate,Many To Many,我存储具有多个标签的文章,如下所示: 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 publi

我存储具有多个标签的文章,如下所示:

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;

}
我想搜索包含一些标签的文章,例如,像这个问题
hibernate
many-to-many
。所以我试着:

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();
当replace
返回过多的项目时,因为生成的SQL是
。。。其中(tag1_u2;.name=?或tag1_2;.name=?)

我想要的正是梅的样子:

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'

当我只使用HQL时是否可能?

您应该尝试类似的方法:

    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++;
    }
实际上,问题是当你做一个简单的内部连接时,你已经用标记连接了你的结果,但问题是数据实际上在两行上。。。因此,如果您加入两次,就可以在一行中获取数据


我认为它不是很优雅,但应该可以工作…

谢谢你的回答,但它抛出了
org.hibernate.QueryException:replicate association path:tags
的异常。标准字符串是
criteriampl(com.cremoi.model.article.article:this[Subcriteria(tags:alias\u 0),Subcriteria(tags:alias\u 1)][alias\u 0.name=hibernate,alias\u 1.name=many to many])
,看起来效果不错,但是没有。我找到了另一个解决方案,使用了
连接词
分离标准
:这很有效,但也不优雅。坦率地说,这太难看了(
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'
    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++;
    }