Main entity is Article
having list of PriceInfo
which holds amount, currency and Provider
entity.
Each Provider
has a parent and list of children, but only one of those is filled giving me exactly two levels of parent-child relation.
Parent Provider
is used for generic prices, for example large brands having many stores around the country. Child Provider
is used for specific store in case when article is, for example, on discount in that particular store and not in all stores.
In order to display all Article
entries under parent Provider
including also those under child Provider
I generated a bridge that creates parentId
field inside Provider
.
During creation of SearchPredicate childProvidersByParentId
(line 9, code snippet is below) exception is thrown:
HSEARCH600050: Unable to convert DSL argument: Cannot cast java.lang.Integer to
com.thevegcat.app.entities.provider.Provider
Is it possible to create Integer
value and only Integer
value instead of whole parent Provider
because all other content from parent Provider
is not relevant for search? What am I doing wrong?
Java Version: 18.0.2.1
Spring Boot version: 3.0.4
Hibernate version: 6.2.0.CR3
Hibernate Search version: 6.1.8.Final (afraid to put 6.2.0.Alpha2 into production)
Article.java
class Article {
@IndexedEmbedded
private Set<PriceInfo> priceInfos;
}
PriceInfo.java:
class PriceInfo {
private BigDecimal amount;
private CustomCurrency currency;
@IndexedEmbedded
private Provider provider;
}
Provider.java
class Provider {
@GenericField(
projectable = Projectable.NO,
searchable = Searchable.YES,
sortable = Sortable.NO
)
private Integer id;
@GenericField(
name = "parentId",
projectable = Projectable.NO,
searchable = Searchable.YES,
sortable = Sortable.NO,
valueBridge = @ValueBridgeRef(type = ProviderIdBridge.class)
)
private Provider parent;
}
ProviderIdBridge.java
class ProviderIdBridge implements ValueBridge<Provider, Integer> {
@Override
public Integer toIndexedValue(
Provider provider,
ValueBridgeToIndexedValueContext context
) {
if (provider == null) {
return null;
}
return provider.getId();
}
}
Code snippet to generate SearchPredicate
:
01 SearchPredicateFactory pf = searchSession.scope(Article.class).predicate();
02
03 SearchPredicate mainProviderById =
04 pf.match()
05 .field("priceInfos.provider.id")
06 .matching(providerId)
07 .toPredicate();
08
09 SearchPredicate childProvidersByParentId =
10 pf.match()
11 .field("priceInfos.provider.parentId")
12 .matching(providerId)
13 .toPredicate();
14
15 SearchPredicate all =
16 pf.bool()
17 .should(mainProviderById)
18 .should(childProvidersByParentId)
19 .minimumShouldMatchNumber(1)
20 .toPredicate();