Reputation: 1118
I have an entity InwardInventory as below
@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 have fields like productId and 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
}
I want to write a specification to filter inwardinventory based product id. Example - If I pass productId as 100, it should return all inwardinventory list which has entry for product 100. Can someone help me how to write specification where we have to query list or set of entities.
Upvotes: 1
Views: 7268
Reputation: 1118
I was able to achieve this using joins. Below is the code
Code for stock specification
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;
}
and below is the code for implementation of generic method which can be used for any entity class having similar filter requirement
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;
Upvotes: 4