I have a Page
of Farmers
coming from a JPA repository call to a findAll
method. Each Farmer consists of a Set
of Farms
which are also coming in the repository call like so:
public class Farmer {
private String name;
@ManyToMany
@JoinTable(name = "farmer_asset", joinColumns = @JoinColumn(name = "farmer_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "asset_id", referencedColumnName = "id"))
private Set<Asset> assets;
}
Asset
has a property called isActive
which indicates that the asset is active or not.
In my Page
of Farmers
I want to select only farmers' Assets which are active.
I tried with
@WhereJoinTable(clause = "is_active ='true'")
However, I learned that the is_active
property is supposed to be in the intermediate many-to-many relation on table farmer_asset
.
Now I am not in a position to change the entity structure, and use @WhereJoinTable(clause = "is_active ='true'")
.
So, I thought of trying to filter the values after making the JPA call.
However, iterating through each Farmer
, then removing the inActive Assets
and then adding it back to the Page
and maintaining Page
elements seemed too performance heavy operation.
I tried with normal Java code which looks something like this:
Page<Farmer> farmers = farmerRepository.findAll(pageable);
List<Farmer> farmersList = new LinkedList<>();
for (FarmerDto eachFarmer : farmers.getContent()) {
Set<Asset> eachFarmerAssets =
eachFarmer.getAssets();
eachFarmerAssets.removeIf(e ->
!e.getIsActive());
eachFarmer.setAssets(eachFarmerAssets);
farmersList.add(eachFarmer);
}
return new PageImpl<FarmerDto>(farmersList, pageable, farmers.getTotalElements());
I would like to do this is Java 8 using streams but I am not able to iterate a list and change its element which is in turn a Set<Asset>
.
Came here looking for some suggestions.
You have to follow these steps:
List<Farmer> farmers = farmerRepository.findAll(pageable).getContent(); //1
List<FarmerDto> farmersList = farmers.stream() // 2
.map(farmer -> { // 3
FarmerDto farmerDto = new FarmerDto();
// fill farmerDto 3.1
farmerDto.setAssets(farmer.getAssets().stream().filter(Farmer::getIsActive()).toList()); //3.2
return farmerDto;
}).toList();
return new PageImpl<FarmerDto>(farmersList, pageable, farmers.getTotalElements());