Hibernate标准很多很多

时间:2014-01-09 21:13:32

标签: java hibernate many-to-many criteria

我有两个有多对多关系的实体:

@Entity
@Table(name = "items")
public class Item implements Comparable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "item_id")
private Integer itemId;

@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinTable(name = "items_criteria",
        joinColumns = @JoinColumn(name = "item_id"),
        inverseJoinColumns = @JoinColumn(name = "filter_criterion_id"))
private List<FilterCriterion> filterCriteria;

}

@Entity
@Table(name = "filter_criteria")
public class FilterCriterion {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "filter_criterion_id")
private Integer filterCriterionId;

@ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinTable(name = "items_criteria",
        joinColumns = @JoinColumn(name = "filter_criterion_id"),
        inverseJoinColumns = @JoinColumn(name = "item_id"))
private List<Item> items;
}

我需要在ItemDao类中编写函数,该类返回Item的List,其中包含作为参数给出的集合的所有元素。在下面的示例中,我使用Restrictions.in,因此结果甚至包含那些仅包含作为参数给出的List中的一个FilterCriterion的项目。我需要在结果中只包含那些包含参数List中所有元素的Items。

public List<Item> getItems(List<FilterCriterion> currentFilterCriteria) {

    Criteria criteria = ht.getSessionFactory().getCurrentSession().createCriteria(Item.class);
    List<Integer>currentFilterCriteriaId = new ArrayList<Integer>();
    for(FilterCriterion criterion : currentFilterCriteria){
        currentFilterCriteriaId.add(criterion.getFilterCriterionId());
    }
    if(!currentFilterCriteriaId.isEmpty()){
        criteria.createAlias("filterCriteria", "f");
        criteria.add(Restrictions.in("f.filterCriterionId", currentFilterCriteriaId));
    }
    return criteria.list();
}

1 个答案:

答案 0 :(得分:0)

首先,您必须修复映射。这里没有双向ManyToMany关联,而是两个不相关的单向ManyToMany关联。通过使用mappedBy属性,一边必须是反面:

@ManyToMany(mappedBy = "filterCriteria")
private List<Item> items;

现在问题,一种方法是使用这样的查询。如果你真的想,我会让你把它翻译成Criteria。我会使用HQL,因为它更容易和可维护:

select i from Item i
where :criteriaIdSetSize = (select count(c.id) from Item i2
                             inner join i2.filterCriteria c
                             where c.id in :criteriaIdSet
                             and i2 = i)

您应该使用Set来保存条件ID而不是列表,以确保它不包含重复项(这会导致结果不正确)。