Hibernate:一个实体上的多个过滤器

9
我想在一个实体上使用多个 Hibernate 过滤器,我已经尝试了一切逻辑上可以想到的办法,但没有成功,Google 和 Hibernate 文档也没有找到相关信息。我无法想象这是不可能的。(使用 Java 6 Hibernate 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;

...
}

我想给Testcase类添加第二个独立的过滤器。我想要的是像这样的东西:
Select ...  
  From CATEGORY INNER JOIN TESTCASE on CATEGORY.CATEGORYID = TESTCASE.CATEGORYID
 Where TESTCASE.TESTRUNID in (....)
   and TESTCASE.TESTCASENAME like '%..%'

这是我尝试的:
我尝试将多个@FilterDefs添加到TestCase中,但那样并没有编译成功。
    @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
用户发布了他尝试过的内容。 - dcernahoschi
1个回答

15

实际上,我已经解决了它,但还是谢谢你的帮助。 解决方案(如下所述)是在@FilterDefs注释中包装多个@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
请注意 http://learningprogramming.net/java/hibernate5/multiple-filters-on-an-entity-in-hibernate-5/ - gihan-maduranga

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接