2013-04-05 20 views
6

Chcę mieć wiele filtrów w hibernacji na encji, próbowałem wszystkiego logicznie bez powodzenia, a Google nie wymyślił tego, podobnie jak dokument Hibernate. Nie mogę sobie wyobrazić, że nie jest to możliwe. (Korzystanie z Java 6 hibernacji 4.1.9.final)Hibernacja: wiele filtrów na jednostce

Obecnie mam to:

@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; 

... 
} 

Chcę dodać drugi niezależny filtr do klasy TESTCASE. Jestem po co jest mniej więcej tak:

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

To co próbowałem

Próbowałem, dodając kilka @FilterDefs do TESTCASE jak takie, ale nie kompilacji:

@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; 

    ... 
    } 

Dokumentacja hibernacji doprowadziła do wypróbowania czegoś takiego, co narzekało na to, że filtr testrunid nie istniał.

@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; 

.. 
} 

Twoja pomoc jest bardzo wdzięczna

+5

+1. użytkownik opublikował to, co próbował. – dcernahoschi

Odpowiedz

11

Rozwiązałem ją właściwie, ale dzięki za pomoc. Rozwiązaniem (opisanym poniżej) jest umieszczenie wielu adnotacji @FilterDef w adnotacjach @FilterDef s. Co dziwne, nie znalazłem tego nigdzie ani w dokumencie hibernacji, zobaczyłem ten post (Multiple annotations of the same type on one element?) i pomyślałem, że hej maybee @FilterDefs istnieje i to działa.

@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; 

... 
} 

W DAO, po prostu włączyć te muszę

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. W odnośniku do hibernacji znajduje się odniesienie: http://docs.jboss.org/hibernate/orm/4.1/manual/en-US/html/ch19.html#objectstate-filters Też to przegapiłem. – dcernahoschi

Powiązane problemy