【问题标题】:how to @FilterJoinTable with EntityManager in Hibernate JPA?如何在 Hibernate JPA 中使用 EntityManager @FilterJoinTable?
【发布时间】:2011-12-26 02:53:47
【问题描述】:

我想限制来自 OneToMany 关系的数据。在我的程序中,老板帐户可以查看公司在给定月份和年份的所有订单。公司类可以 f.e.计算这些订单的收入。我使用了@FilterJoinTable,但由于我必须使用 EntityManager,所以我不能再这样做了。这是我与 Session 对象一起使用的代码。

订单类

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

private Company company;
private int month;
private int year;
[...]

@JoinColumn(name = "company_idcompany", referencedColumnName = "idcompany")
@ManyToOne(optional = false, fetch = FetchType.EAGER)
public Company getCompany() {
    return company;
}

public void setCompany(Company company) {
    this.company = company;
}
[...]

公司类

@Entity(name="company")
@FilterDef(name="orderFilter", parameters = {
                       @ParamDef(name = "month", type = "int"),
                       @ParamDef(name = "year", type = "int")
                       })
public class Company implements Serializable 
{
private static final long serialVersionUID = 1L;

private List<Order> orderList = new ArrayList<Order>();
[...]

@OneToMany(
        fetch = FetchType.LAZY,
        mappedBy="company"
)
@JoinTable(
        name = "order",
        joinColumns = { @JoinColumn(name = "idcompany") },
        inverseJoinColumns = { @JoinColumn(name = "idorder") }
)
@FilterJoinTable(name="orderFilter", condition=":month = month and :year = year")
public List<Order> getOrderList() {
    return orderList;
}
[...]

get 方法如下所示

public List<Company> get(int month, int year) throws AdException
{
    try
    {
        begin();

        //will get only the orders in given month and year
        Filter filtr = getSession().enableFilter("orderFilter");

        filtr.setParameter("month", month);
        filtr.setParameter("year", year);

        //this criteria didn't work well so I've added a loop below 
        Criteria crit = getSession().createCriteria(Company.class);
        crit.add(Restrictions.isNotEmpty("companyList"));


        List<Company> companys = crit.list();

        Iterator iter = companys.iterator();

        //throwing out the companys that have no orders in given month and year
        while(iter.hasNext())
        {
            Company com = (Company)iter.next();
            if(com.getOrderList().isEmpty())
            {
                companys.remove(com);
                iter = companys.iterator();
            }
        }

        getSession().disableFilter("orderFilter");
        commit();

        return companys;
    }
    catch( HibernateException e )
    {
        rollback();
        throw new AdException("ex message",e);
    }
 }

get 方法仅返回在给定月份和年份有订单的公司。每个公司的 orderList 仅包含给定月份和年份的订单。我知道 get 方法并不漂亮,但它有效。你能告诉我如何解决这个问题吗?我一无所知。

已解决感谢 Joshua Davis

   Query q = em.createQuery("SELECT DISTINCT o.company FROM Order z WHERE o.month=:month AND z.year=:year");

            q.setParameter("month", month);
            q.setParameter("year", year);

            List<Company> companys = q.getResultList();

            for(Company com : companys)
            {
                Query q2 = em.createQuery("from Order where month = :month and year = :year and company.idCompany = :id");
                q2.setParameter("month", month);
                q2.setParameter("year", year);
                q2.setParameter("id", com.getIdCompany());

                com.setOrderList(q2.getResultList());
            }

【问题讨论】:

    标签: hibernate entitymanager hibernate-entitymanager


    【解决方案1】:

    更简单的方法是:

    em.createQuery("select o from Order o " +
            "where o.company.id=:id and o.month=:m and o.year=:y")
            .setParameter("id",someCompany.getId())
            .setParameter("y",year)
            .setParameter("m",month)
            .getResultList();
    

    本质上,您正在使用对象图导航来解决一个可以通过普通 JPA 查询轻松解决的问题。

    如果您需要修改列表中的订单,这将透明地工作,因为查询将返回持久实例。如果您需要添加或删除订单,则可能需要访问 Firma(公司)中的集合。

    【讨论】:

    • 感谢您的回复,但这不是我想要的。我可能问错了问题。 get 函数的重点是返回在给定年份和月份有订单的公司列表。我需要 Company 对象,因为它们具有一些特定功能,例如计算给定月份的订单收入。
    • @Szajba 您也可以使用 JPAQL 来做到这一点:“select distinct o.company from Order o ...”
    • 还是不行。我按照你写的那样做了:“从订单 o 中选择不同的 o.company,其中 o.month=:m 和 o.year=:y”。它为在给定月份和年份中至少有一个订单的公司提供,而且每个公司的订单列表包含具有不同日期的其余订单。为什么会这样?
    • 确保您的过滤器定义正确。就我个人而言,我不太喜欢以这种方式使用过滤器(过滤集合)。此外,查询和过滤器对可嵌入集合的行为与实体集合的行为不同。
    • 就个人而言,我会在不使用过滤器的情况下解决这个问题。我会使用一个查询来获取公司,另一个查询来获取公司的订单(过滤)。这样我就不必处理任何大型集合,当我不希望它们懒加载时。
    猜你喜欢
    • 1970-01-01
    • 2014-06-28
    • 2020-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-16
    • 2021-08-30
    • 1970-01-01
    相关资源
    最近更新 更多