2014-01-09 4 views
0

У меня есть два объекта отношения многие ко многим:критерии Hibernate многие ко многим

@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, поэтому результат содержит даже те элементы, которые содержат, например, только один 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(); 
} 

ответ

0

Прежде всего, вам необходимо исправить свое сопоставление. У вас нет двунаправленной ассоциации ManyToMany, но две несвязанные однонаправленные ассоциации ManyToMany. Одна сторона должна быть обратная сторона, используя атрибут mappedBy:

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

Теперь на ваш вопрос, один из способов сделать это состоит в использовании такого запроса. Я позволю вам перевести его на Критерии, если вы действительно этого захотите. Я хотел бы использовать 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) 

Вы должны использовать набор для хранения ваших идентификаторов критериев, а не список, хотя, чтобы убедиться, что он не содержит дубликатов (которые были бы сделать результат неверным).

+0

Спасибо за помощь, я исправил отображение, но в своем вопросе я описал более простую ситуацию, чем это действительно так. Функция getItems действительно принимает больше аргументов и содержит критерии ограничений не только для FilterCriterion. Все остальные ограничения работают хорошо. Я не знаю, как написать HQL-запрос для всего этого. Можете ли вы помочь мне создать ограничение? – bramblehorse

Смежные вопросы