2011-04-27 82 views
2

我存儲與多個標籤的文章如下:搜索多個標籤的文章 - 休眠許多一對多

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; 

} 

import javax.persistence.Entity; 
import javax.persistence.Id; 

@Entity 
public class Tag { 

    @Id 
    private String name; 

    private String description; 

} 

我想搜索的文章裏面包含了一些標記,爲例如,像這個問題hibernatemany-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(); 

但是,沒有工作和返回的列表是空的,因爲登錄SQL顯示爲:

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' 

當更換andor返回太多的文章,因爲生成的SQL是... where (tag1_.name=? or tag1_.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?

回答

1

你應該嘗試類似的東西:

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++; 
    } 

其實這個問題是,當你做一個簡單的內連接,OK,你已經加入你的結果與標籤,但問題是,該數據實際上是在2行...所以如果你加入2次,你將能夠獲得一行數據。

,我認爲它不是真正的優雅,但它應該工作...

+0

謝謝您的回答,但它拋出'org.hibernate.QueryException的例外:重複協會路徑:tags'。條件字符串是CriteriaImpl(com.cremoi.model.article.Article:this [Subcriteria(tags:alias_0),Subcriteria(tags:alias_1)] [alias_0.name = hibernate,alias_1.name = many-to-many] )'這看起來很好,但沒有。 – leafriend 2011-04-27 18:57:57

+0

我發現了另一個使用'Conjunction'和'DetachedCriteria'的解決方案:http://opensource.atlassian.com/projects/hibernate/browse/HHH-879?focusedCommentId=39793&page=com.atlassian.jira.plugin.system.issuetabpanels% 3Acomment-tabpanel#action_39793 這是行之有效的,但也不優雅。坦率地說,這太難看了。 :( – leafriend 2011-04-27 19:26:34

+0

對不起,我不知道這是不可能的;)祝你好運 – 2011-04-27 21:40:37