I have the following peace of code:
public class LazyProductDataModel<P extends Product> extends LazyDataModel<P> { 
    private List<P> data = new ArrayList<P>();
    private SearchProductsCriteria<P> criteria;
    public LazyProductDataModel(SearchProductsCriteria<P> criteria) {
        this.criteria = criteria;
    }
    public SearchProductsCriteria<P> getCriteria() {
        return criteria;
    }
    public void setCriteria(SearchProductsCriteria<P> criteria) {
        this.criteria = criteria;
    }
    @Override
    public List<P> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
        if (criteria == null) {
            return data;
        }
        int currentPage = first==0 ? 1 : first >= pageSize ? (first / pageSize) + 1 : 0;
        criteria.setPageNumber(currentPage);
        criteria.setPageSize(pageSize);
        try {
            if (criteria.getProductId() != null && criteria.getProductId() != 0) {
                P product = ServiceClientFactory.getInstance().
                        getProductRetrieveClient(criteria.getProductClass()).getProduct(criteria.getProductId());
                if (product != null) {
                    data.add(product);
                    this.setRowCount(1);
                }
            } else {
                LazyDataResponse<P> lazyResponse = ServiceClientFactory.getInstance().
                        getProductSearchClient(criteria.getProductClass()).searchProductsLazyResponse(criteria); 
                data = lazyResponse.getList();
                this.setRowCount(lazyResponse.getTotalRecordsCount());
            }
        } catch (Exception e) {
            LOGGER.error("Exception happened at LazyProductDataModel#load.", e);
            data = new ArrayList<P>();
            this.setRowCount(0);
        }
        return data;
    }
}
3rd line in the try block, getProductRetrieveClient(criteria.getProductClass()).getProduct(criteria.getProductId());
I am calling criteria.getProductClass(), this returns a Class<P>, and as you see in the class above, P extends Product, which means that I should be able to pass any class that extends Product, but in my class I am trying to use it but its not going as expected: 
Here is how I am trying to use it, please help I'm new to the generics topic.
@ManagedBean
@ViewScoped
public class ReportController implements Serializable {
    private ProductReportCriteria<? extends Product> criteria = new ProductReportCriteria<>();
    public ReportController() {
    }
    @PostConstruct
    public void init() {
        criteria.setLocale(userToolKit.getLocale());
        criteria.setProductClass(Movie.class);
    }
    public ProductReportCriteria<?> getCriteria() {
        return criteria;
    }
    public void setCriteria(ProductReportCriteria<? extends Product> criteria) {
        this.criteria = criteria;
    }
}
in the last method onFilter inside the if statement, I am getting a compilation error,
The method setProductClass(Class<capture#9-of ? extends Product>) in the type SearchProductsCriteria<capture#9-of ? extends Product> is not applicable for the arguments (Class<Movie>)
public class Movie extends Product implements Serializable {
}
public class Product implements Serializable {
}
Finally,
public class ProductReportCriteria<P extends Product> extends SearchProductsCriteria<P> implements Serializable {
}
public class SearchProductsCriteria<P> implements Serializable {
    private Class<P> productClass;
    public Class<P> getProductClass() {
        return productClass;
    }
    public void setProductClass(Class<P> productClass) {
        this.productClass = productClass;
    }
}
 
     
    
` at once.