Spring JPA规范,用于过滤与子实体的一对多关系

时间:2020-04-27 04:23:40

标签: hibernate spring-boot spring-data-jpa hibernate-criteria

我有一个如下的InwardInventory实体

@Entity
@Table(name = "inward_inventory")
public class InwardInventory extends ReusableFields
{

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

    @ManyToMany(fetch=FetchType.EAGER,cascade = CascadeType.ALL)
    @JoinTable(name = "inventory_entry", joinColumns = {
            @JoinColumn(name = "in_inventoryId", referencedColumnName = "in_inventoryId") }, inverseJoinColumns = {
                    @JoinColumn(name = "entryId", referencedColumnName = "entryId") })
    Set<InwardOutwardList> inwardOutwardList = new HashSet<>();;

//many other fields
}

实体InwardOutwardList具有诸如productId和数量之类的字段。

@Entity
@Table(name = "inward_outward_entries")
@Audited
@Where(clause = ReusableFields.SOFT_DELETED_CLAUSE)
public class InwardOutwardList extends ReusableFields
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long entryid;

    @ManyToOne(fetch=FetchType.LAZY,cascade = CascadeType.ALL)
    @JoinColumn(name="productId",nullable=false)
    @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
    Product product;
    Float quantity;
//other fields and getter setters
}

我想写一个规范来过滤基于库存的产品ID。示例-如果我将productId传递为100,它将返回所有包含产品100条目的内向库存清单。有人可以帮助我如何在需要查询列表或实体集的地方编写规范。

1 个答案:

答案 0 :(得分:2)

我能够使用联接实现这一目标。下面是代码

库存规格代码


public static Specification<InwardInventory> getSpecification(FilterDataList filterDataList) throws ParseException
    {
        List<String> productNames = SpecificationsBuilder.fetchValueFromFilterList(filterDataList,"productNames");

        Specification<InwardInventory> finalSpec = null;

        if(productNames != null && productNames.size()>0)
            finalSpec = specbldr.specAndCondition(finalSpec,specbldr.whereChildFieldListContains(
                    InwardInventory_.INWARD_OUTWARD_LIST,InwardOutwardList_.PRODUCT,Product_.PRODUCT_NAME,productNames));
return finalSpec;
    }

及以下是用于实现通用方法的代码,该方法可用于具有类似过滤条件的任何实体类


public Specification<T> whereChildFieldListContains(String childTableName, String gcTable,String fieldName, List<String> names) 
    {
        Specification<T> finalSpec = null;
        for(String name:names)
        {
            Specification<T> finalSpec = (Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb)
                -> cb.like(root.join(childTableName).join(gcTable).get(fieldName), "%"+name+"%" );

        }
        return finalSpec;