0

我正在尝试使用 JPA 2.0 Criteria API(使用 Hibernate 实现)来选择那些拥有由一组模式定义的配件的汽车。

请看我的代码,我想你会明白我在做什么。

实体:

@Entity
@Table(name = "CARS")    
public class Car implements Serializable {

   // .. Other fields
    // {{ accessories
    @ElementCollection(fetch = FetchType.LAZY)
    @CollectionTable(name = "CARS_ACCESSORIES", joinColumns = @JoinColumn(name = "CARID"))
    @Column(name = "ACCESSORY", length = 25)
    private Set<String> accessories;

Car 类的存储库/服务方法,用于查找拥有具有模式的配件的所有汽车:

public List<Car> findByAccessoryCriteria(Set<String> accessoriesCriteria) {

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Car> cq = cb.createQuery(Car.class);
    Root<Car> car = cq.from(Car.class);

    List<Predicate> criteria = new ArrayList<Predicate>();

    if(accessoriesCriteria != null) {
       for(String accessory : accessoriesCriteria) {
           if(accessory.contains("%") {
               // TODO: Select all Cars that contains an accessory which match
               // accessory pattern.
           } else {
               // TODO: Select all Cars that contains an accessory which is 
               // equal to accessory pattern.
           }
           // TODO: Note that if a Car NOT owns an accessory which match or is equal to a
           // the pattern, the Car shall NOT be selected.
       } 
    }
    cq.select(car).where(criteria.toArray(new Predicate[criteria.size()]));
    TypedQuery<Car> query = em.createQuery(cq);
    List <Car> cars= query.getResultList();
    return cars;
}

因此,如果 A 车拥有以下附件:“附件 XYZ”、“附件 AAA”,而 B 车拥有以下“附件 XYZ”,并且条件设置为“附件%”,则 A 车和 B 车都应为选择,但如果标准是 Set = "Accessory XYZ", "Accessory AAA" 只有汽车 A 应该被选择。

你能帮我完成这个选择声明吗?请注意,我被迫使用标准 API 和 Hibernate 框架。

最好的祝福

4

1 回答 1

2

强制使用 Hibernate 与此处无关,因为这是 JPA 条件查询。反正...

if (accessoriesCriteria != null) {
   // we have accessory restrictions...

   // now apply each incoming restriction
   for (String accessoryCriteria : accessoriesCriteria) {
       // define a path to the accessories association that we can use to apply
       // the restrictions
       final Join<Car,String> accessoryJoin = (Join<Car,String>) car.join( "accessories" );
       // or, if using generated metamodel:
       // Join<Car,String> accessoryJoin = car.join( Car_.accessories );

       if (accessoryCriteria.contains("%") {
           criteria.add( cb.like( accessoryJoin, accessoryCriteria ) );
       } 
       else {
           criteria.add( cb.equal( accessoryJoin, accessoryCriteria ) );
       }
   } 
}
于 2013-03-16T16:36:30.370 回答