【问题标题】:Hibernate criteria many to manyHibernate 标准多对多
【发布时间】:2014-01-28 15:44:04
【问题描述】:

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

@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 类中编写函数,该函数返回将集合的所有元素作为参数给出的项目列表。在下面的示例中,我使用 Restrictions.in,因此结果甚至包含那些仅包含 List 中作为参数给出的一个 FilterCriterion 的项目。我只需要在结果中包含那些包含参数列表中所有元素的项目。

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

【问题讨论】:

    标签: java hibernate many-to-many criteria


    【解决方案1】:

    首先,您必须修复映射。这里没有双向的多对多关联,而是两个不相关的单向多对多关联。通过使用 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 而不是列表,以确保它不包含重复项(这会使结果不正确)。

    【讨论】:

    • 感谢您的帮助,我修复了映射,但在我的问题中,我描述的情况比实际情况更简单。函数 getItems 确实需要更多参数,并且不仅包含 FilterCriterion 的条件限制。所有其他限制都很好。我不知道如何为所有这些编写 HQL 查询。你能帮我创建一个限制吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 2010-12-06
    • 1970-01-01
    • 1970-01-01
    • 2014-08-14
    • 1970-01-01
    相关资源
    最近更新 更多