2013-04-05 60 views
6

我希望在一個實體上擁有多個Hibernate過濾器,我已經嘗試過所有的邏輯,但沒有幸運,而且谷歌已經在這個過程中做出了簡短的介紹,就像Hibernate doc一樣。我無法想象這是不可能的。 (使用Java 6休眠4.1.9.final)休眠:實體上的多個過濾器

目前,我有這樣的:

@Entity 
@Table(name = "CATEGORY") 
public class Category implements Serializable 
{ 
    private static final long serialVersionUID = 1L; 

    @Id 
    @Column(name = "CATEGORYID") 
    private int ID; 

    @Column(name = "CATEGORYNAME") 
    private String name; 

    @OneToMany(fetch = FetchType.EAGER) 
    @JoinColumn(name = "CATEGORYID") 
    @OrderBy("TESTCASEID desc") 
    @Filter(name = "TEST_RUN_ID_FILTER") 
    private Collection<TestCase> testCases; 
... 
} 

@Entity 
@Table(name = "TESTCASE_NEW") 
@FilterDef(name = "TEST_RUN_ID_FILTER", defaultCondition = "TESTRUNID in (:IDS)", parameters = { @ParamDef(name = "IDS", type = "int") }) 
public class TestCase implements Serializable 
{ 
    private static final long serialVersionUID = 1L; 

    @Id 
    @Column(name = "TESTCASEID") 
    private int ID; 

    @Column(name = "TESTCASENAME") 
    private String name; 

... 
} 

我想第二個獨立的過濾器添加到測試用例類。我所經過是這樣的:

Select ... 
    From CATEGORY INNER JOIN TESTCASE on CATEGORY.CATEGORYID = TESTCASE.CATEGORYID 
Where TESTCASE.TESTRUNID in (....) 
    and TESTCASE.TESTCASENAME like '%..%' 

這是我試過

我嘗試添加多個@FilterDefs到測試用例喜歡這樣,但是這並沒有編譯:

@Entity 
    @Table(name = "TESTCASE_NEW") 
    @FilterDef(name = "TEST_RUN_ID_FILTER", defaultCondition = "TESTRUNID in (:IDS)", 
parameters = { @ParamDef(name = "IDS", type = "int") }) 
    @FilterDef(name = "TESTCASE_NAME_FILTER", defaultCondition = "TESTCASENAME like :TESTCASE_NAME", 
parameters = { @ParamDef(name = "TESTCASE_NAME", type = "string") }) 

    public class TestCase implements Serializable 
    { 
     private static final long serialVersionUID = 1L; 

     @Id 
     @Column(name = "TESTCASEID") 
     private int ID; 

     @Column(name = "TESTCASENAME") 
     private String name; 

    ... 
    } 

Hibernate文檔導致嘗試類似這樣的抱怨testrunid過濾器不存在的東西

@Entity 
    @Table(name = "CATEGORY") 
    public class Category implements Serializable 
    { 
     private static final long serialVersionUID = 1L; 

     @Id 
     @Column(name = "CATEGORYID") 
     private int ID; 

     @Column(name = "CATEGORYNAME") 
     private String name; 

     @OneToMany(fetch = FetchType.EAGER) 
     @JoinColumn(name = "CATEGORYID") 
     @OrderBy("TESTCASEID desc") 
     private Collection<TestCase> testCases; 
    ... 
    } 


     @Entity 
    @Table(name = "TESTCASE_NEW") 
    @FilterDef(name = "TESTCASE_FILTER", parameters = { @ParamDef(name = "IDS", type = "int"), @ParamDef(name = "TESTCASE_NAME", type = "string") }) 
    @Filters({ @Filter(name = "TEST_RUN_ID_FILTER", condition = "TESTRUNID in (:IDS)"), @Filter(name = "TESTCASE_NAME_FILTER", condition = "TESTCASENAME like :TESTCASE_NAME") }) 
    // @FilterDef(name = "TEST_RUN_ID_FILTER", defaultCondition = "TESTRUNID in (:IDS)", parameters = { @ParamDef(name = 
    // "IDS", type = "int") }) 
    public class TestCase implements Serializable 
    { 
     private static final long serialVersionUID = 1L; 

     @Id 
     @Column(name = "TESTCASEID") 
     private int ID; 

     @Column(name = "TESTCASENAME") 
     private String name; 
     ... 
    } 
    @SuppressWarnings("unchecked") 
     public List<Category> getCategories(List<Integer> testRunIDs, String category, String testCaseName) 
     { 
      Session session = getSession(); 
      session.enableFilter("FILE_TYPE_FILTER"); 
      if (testRunIDs != null && testRunIDs.size() != 0) 
      { 
       session.enableFilter("TEST_RUN_ID_FILTER").setParameterList("IDS", testRunIDs); 
      } 
      if (category != null && !category.equals("0") && !category.equals("")) 
      { 
       session.enableFilter("CATEGORY_FILTER").setParameter("CATEGORY", category); 
      } 

      /* 
      * Hibernate wants to do an (left) outer join be default. 
      * This bit of HQL is required to get it to do an inner join. 
      * The query tells Hibernate to do an inner join on the testCases property inside the Category object 
      */ 

      Query query = session.createQuery("select distinct c from Category c inner join c.testCases tc"); 
      List<Category> result = query.list(); 
      return result; 

.. 
} 

非常感謝您的幫助

+5

+1。用戶發佈了他所嘗試的內容。 – dcernahoschi 2013-04-05 22:26:23

回答

11

我已經解決了它,但感謝您的幫助。解決方案(下面詳細介紹)是在@FilterDef註釋中包裝多個@FilterDef註釋。奇怪的是,我沒有發現這個地方或Hibernate文檔,我看到這篇文章(Multiple annotations of the same type on one element?),並認爲嘿可能@FilterDefs存在,它確實存在。

@Entity 
@Table(name = "TESTCASE_NEW") 
@FilterDefs({ 
     @FilterDef(name = "TESTCASE_NAME_FILTER", defaultCondition = "TESTCASENAME like :TESTCASENAME", parameters = { @ParamDef(name = "TESTCASENAME", type = "string") }), 
     @FilterDef(name = "TEST_RUN_ID_FILTER", defaultCondition = "TESTRUNID in (:IDS)", parameters = { @ParamDef(name = "IDS", type = "int") }) 
}) 
public class TestCase implements Serializable 
{ 
    private static final long serialVersionUID = 1L; 

    @Id 
    @Column(name = "TESTCASEID") 
    private int ID; 

    @Column(name = "TESTCASENAME") 
    private String name; 

... 
} 

@Entity 
public class Category implements Serializable 
{ 
    private static final long serialVersionUID = 1L; 

    @Id 
    @Column(name = "CATEGORYID") 
    private int ID; 

    @Column(name = "CATEGORYNAME") 
    private String name; 

    @OneToMany(fetch = FetchType.EAGER) 
    @JoinColumn(name = "CATEGORYID") 
    @OrderBy("TESTCASEID desc") 
    @Filters({ 
      @Filter(name = "TEST_RUN_ID_FILTER"), 
      @Filter(name = "TESTCASE_NAME_FILTER") }) 
    private Collection<TestCase> testCases; 

... 
} 

在DAO,我只是打開那些我需要

public List<Category> getCategories(List<Integer> testRunIDs, String category, String testCaseName) 
    { 
     Session session = getSession(); 


     if (testRunIDs != null && testRunIDs.size() != 0) 
     { 
      session.enableFilter("TEST_RUN_ID_FILTER").setParameterList("IDS", testRunIDs); 
     } 

     if (testCaseName != null) 
     { 
      session.enableFilter("TESTCASE_NAME_FILTER").setParameter("TESTCASENAME", testCaseName); 
     } 

     /* 
     * Hibernate wants to do an (left) outer join be default. 
     * This bit of HQL is required to get it to do an inner join. 
     * The query tells Hibernate to do an inner join on the testCases property inside the Category object 
     */ 

     Query query = session.createQuery("select distinct c from Category c inner join c.testCases tc"); 
     List<Category> result = query.list(); 
     return result; 
    } 
+1

+1。這裏有一個hibernate參考的參考:http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html/ch19.html#objectstate-filters我也錯過了。 – dcernahoschi 2013-04-06 07:19:37