【问题标题】:Spring JPA Specification to filter one to many relation with child entitySpring JPA 规范过滤与子实体的一对多关系
【发布时间】:2020-08-10 14:00:27
【问题描述】:

我有一个如下的实体 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
}

Entity InwardOutwardList 具有 productId 和 quantity 等字段。

@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 条目的 inwardinventory 列表。有人可以帮助我如何编写规范,我们必须查询列表或实体集。

【问题讨论】:

  • 你自己试过了吗?如果没有,您可以使用所需的自定义规范编写 jpa 查询并执行查询,即参考此baeldung.com/…
  • @TeJas 谢谢。但我已经尝试过此链接中提供的信息。我可以使用那里提到的逻辑查询多对一实体。但在这种情况下,关系是一对多的。我的意思是嵌入式实体是一个集合。所以,我不确定如何编写必须迭代集合并将每次迭代中的字段与值进行比较的逻辑

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


【解决方案1】:

我能够使用连接来实现这一点。下面是代码

库存规格代码


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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-19
    • 2017-01-09
    • 2021-05-25
    • 2015-10-28
    • 2019-04-07
    • 2021-11-15
    • 2017-01-31
    • 1970-01-01
    相关资源
    最近更新 更多