Converter called multiple times evaluating aggregation operation query methods
MrWangGang opened this issue · comments
my Converter
@WritingConverter
public class EnumWriteConverter implements Converter<ConverterEnum, String> {
public EnumWriteConverter() {
}
public String convert(ConverterEnum source) {
return source.getValue();
}
}
Pass the enumeration as a parameter,my enum impl -> ConverterEnum
@Aggregation({
"{$addFields: { '_idString': { $toString: '$_id' } }}",
"{$match: { userId: ?0 }}",
"{$lookup: { from: 't_sku_skill', localField: '_idString', foreignField: 'itemId', as: 'skuDetails' }}",
"{$unwind: { path: '$skuDetails', preserveNullAndEmptyArrays: true }}",
"{$match: { deletedEnum: ?1 }}",
"{$sort: { availableEnum: 1 }}", // ASC
"{$addFields: { quantity: '$skuDetails.quantity' }}",
"{$project: { _idString: 0, skuDetails: 0 }}"
})
Flux<ItemSkillPO.AggregationSku> findBy(String userId, EnumCommerceItemDeletedEnum deleted , Pageable pageable);
"I found that the Converter was called multiple times, and the source was always the same enumeration, ENUM_COMMERCE_ITEM_DELETED_UNDELETE, because I called this query method in the business logic."
@Override
public Flux<ItemSkillPO.AggregationSku> page(String userId, Pageable pageable) {
return repository.findBy(userId,ENUM_COMMERCE_ITEM_DELETED_UNDELETE,pageable);
}
I only called the query method once, but the Converter was called multiple times. Why?
Thank you for reaching out - If you'd like us to spend some time investigating, please take the time to provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem.
I find it difficult to provide samples involving databases; it's very troublesome. Perhaps you could simply set up a project.
Define your converter:
@WritingConverter
public class EnumWriteConverter implements Converter<ConverterEnum, String> {
public EnumWriteConverter() {
}
public String convert(ConverterEnum source) {
return source.getValue();
}
}
Define the interface:
public interface ConverterEnum {
String getDescription();
@JsonValue
String getValue();
}
Define the enumeration:
public enum EnumCommerceItemDeletedEnum implements ConverterEnum {
ENUM_COMMERCE_ITEM_DELETED_DELETE("Delete", "DELETE"),
ENUM_COMMERCE_ITEM_DELETED_UNDELETE("Undelete", "UNDELETE");
EnumCommerceItemDeletedEnum(String description, String value) {
this.description = description;
this.value = value;
}
private final String value;
private final String description;
}
Then create a Spring Data interface:
@Aggregation({
"{$addFields: { '_idString': { $toString: '$_id' } }}",
"{$match: { userId: ?0 }}",
"{$match: { deletedEnum: ?1 }}",
"{$count: 'totalCount' }"
})
Mono<Long> count(String userId, EnumCommerceItemDeletedEnum deleted);
You can test two scenarios: one based on @Aggregation and one based on a named method. However, I have tested it before, and using repository.find(Example) does not cause such issues. Only when using @query or @Aggregation to execute queries with native SQL, the converter gets called multiple times.
thanks for the feedback - I see the invocations now. there's multiple things contributing to this. we'll look into those.