Spring JPA Спецификация для фильтрации отношения один-ко-многим с дочерним объектом - PullRequest
0 голосов
/ 27 апреля 2020

У меня есть сущность 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 и amount.

@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
}

Я хочу написать спецификацию для фильтрации идентификатора продукта на основе inwardinventory. Пример - если я передам productId как 100, он должен вернуть весь внутренний список инвентаря, в котором есть запись для продукта 100. Может кто-нибудь помочь мне, как написать спецификацию, где мы должны запросить список или набор объектов.

1 Ответ

1 голос
/ 27 апреля 2020

Мне удалось добиться этого с помощью объединений. Ниже приведен код

Код спецификации запаса


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

, а ниже приведен код для реализации метода generi c, который можно использовать для любого класса сущностей, имеющих аналогичное требование фильтрации


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;

...