как @FilterJoinTable с EntityManager в Hibernate JPA? - PullRequest
1 голос
/ 10 ноября 2011

Я хотел бы ограничить данные, поступающие из отношения OneToMany.В моей программе учетная запись босса может просматривать все компании, у которых есть заказы в данный месяц и год.Класс компании может рассчитывать доход от этих заказов.Я использовал @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 возвращает только ту компанию, у которой есть заказы в данный месяц и год.Список заказов в каждой компании содержит только заказы за данный месяц и год.Я знаю, что метод get не очень красивый, но он работал.Подскажите, пожалуйста, как я могу решить эту проблему?Я не в курсе.

РАЗРЕШЕНО благодаря Джошуа Дэвису

   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());
            }

1 Ответ

1 голос
/ 10 ноября 2011

Более простой способ сделать это будет:

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.

Если вам нужно изменить заказы в списке, это будет работать прозрачно, так как запрос будет возвращать постоянные экземпляры. Если вам нужно добавить или удалить заказы, вам может потребоваться доступ к коллекции в Фирме (компания).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...