春天Hibernate的JPA规范

春天Hibernate的JPA规范

问题描述:

我有以下实体:春天Hibernate的JPA规范

@Entity 
public class Transaction implements java.io.Serializable { 
    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    protected Long id; 

    @ElementCollection(fetch = FetchType.EAGER) 
    @CollectionTable(name="TRANSACTION_CONFIG", [email protected](name="TRANSACTION_ID")) 
    @MapKeyColumn(name = "PROPERTY_KEY") 
    @Column(name = "PROPERTY_VALUE") 
    protected Map<String, String> properties = new HashMap<String, String>(); 



    public Transaction() { 
    super(); 
    } 

    public Long getId() { 
    return id; 
    } 

    public void setId(Long id) { 
    this.id = id; 
    } 


    public Map<String, String> getProperties() { 
    return properties; 
    } 

    public void setProperties(Map<String, String> properties) { 
    this.properties = properties; 
    } 
} 

我想通过它的“属性”,找到了交易。出于这个原因,我编写了以下Spring规范类来通过其属性过滤事务。

public static Specification<Transaction> matches(final Map<String, String> criteria) { 
return new Specification<Transaction>() { 
    @Override 
    public Predicate toPredicate(Root<Transaction> root, CriteriaQuery<?> query, 
     CriteriaBuilder builder) { 
    List<Predicate> predicates = new ArrayList<Predicate>(); 
    Path<Map<String, String>> propertiesRoot = root.join("properties"); 
    for (String key : criteria.keySet()) { 
     Predicate p = builder.and(propertiesRoot.in(key), propertiesRoot.in(criteria.get(key))); 
     predicates.add(p); 
    } 
    return builder.isTrue(propertiesRoot.in(criteria)); 
    } 
}; 

}

但这似乎并不返回任何东西。任何关于我在做什么错的想法?

+0

想过看着你的JPA标准查询生成的SQL? –

您正在构建正确的predicates列表,但是您没有在要返回的谓词中使用它。相反,你正在返回builder.isTrue(propertiesRoot.in(criteria))这是没有意义的。相反,你应该

return builder.and(predicates.toArray(new Predicates[predicates.size()])) 

请尝试以下

public static Specification<Transaction> matches(final Map<String, String> criteria) { 
    return new Specification<Transaction>() { 
     @Override 
     public Predicate toPredicate(Root<Transaction> root, CriteriaQuery<?> query, CriteriaBuilder builder) { 

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

      //you can define RIGHT or INNER join if you want 
      MapJoin<Transaction, String, String> propertiesRoot = root.joinMap("properties", JoinType.LEFT); 

      for (Map.Entry entry : criteria.entrySet()) { 
       Predicate predicate = builder.and(
        builder.equal(propertiesRoot.key(), entry.getKey()), 
        builder.equal(propertiesRoot.value(), entry.getValue()) 
       ); 
       predicates.add(predicate); 
      } 

      Predicate[] predicatesArray = predicates.toArray(new Predicate[predicates.size()]); 
      return builder.and(predicatesArray); 
     } 
    }; 
} 

或者,如果你正在使用Java8

public static Specification<Transaction> matches(final Map<String, String> criteria) { 
    return (root, query, builder) -> { 
     //you can define RIGHT or INNER join if you want 
     MapJoin<Transaction, String, String> propertiesRoot = root.joinMap("properties", JoinType.LEFT); 

     List<Predicate> predicates = criteria.entrySet().stream() 
      .map(entry -> 
       builder.and(
        builder.equal(propertiesRoot.key(), entry.getKey()), 
        builder.equal(propertiesRoot.value(), entry.getValue()) 
       )) 
      .collect(Collectors.toList()); 

     Predicate[] predicatesArray = predicates.toArray(new Predicate[predicates.size()]); 
     return builder.and(predicatesArray); 
    }; 
}