I'm learning Quarkus Reactive with Mongo Panache and when i try to add a Metadata and Pagination object i get the error: "ERROR [io.qu.re.re.ja.ru.ma.NativeInvalidDefinitionExceptionMapper] (executor-thread-0) com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class io.smallrye.mutiny.operators.uni.builders.UniCreateFromPublisher and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.Entites.BrandResponse["data"])". Controller:
@Path("/brand/")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@RegisterForReflection
public class brand {
private static Logger LOG = LoggerFactory.getLogger(brand.class);
@Inject BrandRepository br;
@GET
public Response list(
@DefaultValue("0") @QueryParam("page") Integer page,
@DefaultValue("10") @QueryParam("page_size") Integer page_size) throws JsonProcessingException {
if (page != null && page >= 1) {
page--;
} else {
page = 0;
}
Uni<List<ReactivePanacheMongoEntityBase>> brands = br.listBrands(page,page_size);
return Response.ok((new BrandResponse(new Metadata("ok",200,"ok"),brands,new Pagination(3,page,page_size)))).build();
}
}
Repository
@ApplicationScoped
@RegisterForReflection
public class BrandRepository implements ReactivePanacheMongoRepositoryBase<Brands, Integer> {
public Uni<List<ReactivePanacheMongoEntityBase>> listBrands(Integer page, Integer page_size) {
return Brands.findAll(Sort.by("name").ascending()).page(Page.of(page, page_size)).list();
}
}
Entity
@Data
@RegisterForReflection
@MongoEntity(collection = "brand")
public class Brands extends ReactivePanacheMongoEntityBase {
@BsonId
public ObjectId id;
@JsonProperty("name")
@BsonProperty("name")
public String name;
}
Entity
@RegisterForReflection
@Data
public class BrandResponse {
@JsonProperty("metadata")
public Metadata metadata;
@JsonProperty("data")
public Uni<List<ReactivePanacheMongoEntityBase>> data;
@JsonProperty("pagination")
public Pagination pagination;
public BrandResponse(Metadata metadata, Uni<List<ReactivePanacheMongoEntityBase>> data, Pagination pagination) {
this.metadata = metadata;
this.data = data;
this.pagination = pagination;
}
}
Entity
@RegisterForReflection
@Data
public class Metadata {
@JsonProperty("status")
public String status;
@JsonProperty("http_code")
public Integer httpCode;
@JsonProperty("date_time")
public Date dateTime;
@JsonProperty("message")
public String message;
public Metadata(String status, Integer httpCode, String message) {
this.status = status;
this.httpCode = httpCode;
this.dateTime = new Date();
this.message = message;
}
}
Entity
@RegisterForReflection
@Data
public class Pagination{
@JsonProperty("total_count")
public Integer totalCount;
@JsonProperty("page")
public Integer page;
@JsonProperty("page_size")
public Integer pageSize;
public Pagination(Integer totalCount, Integer page, Integer pageSize) {
this.totalCount = totalCount;
this.page = page;
this.pageSize = pageSize;
}
}
Thank You For Your Help
When returning some asynchronous data, you can't have any of the fields being an asynchronous type (Uni
in this case).
So essentially you need to convert Uni<X>
to Uni<Y>
and return that.
In your case you would need to make field data
of BrandResponse
be List<ReactivePanacheMongoEntityBase>
instead of Uni<List<ReactivePanacheMongoEntityBase>>
.
Once that is done you can create a BrandResponse
using something like:
Uni<List<ReactivePanacheMongoEntityBase>> brands = br.listBrands(page,page_size);
Uni<BrandResponse> brandResponse = brands.onItem().transform(b -> new BrandResponse(new Metadata("ok",200,"ok"),b,new Pagination(3,page,page_size)))
Now that you have a Uni you should convert your list
JAX-RS Resource Method to either return the Uni<BrandResponse>
directly, or replace the return type of javax.ws.rs.core.Response
to org.jboss.resteasy.reactive.RestResponse
.