“空转换器"的转换错误设置值“52" [英] Conversion Error setting value '52' for 'null Converter'

查看:15
本文介绍了“空转换器"的转换错误设置值“52"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 JSF 的新手,我一直在尝试从使用 h:selectOneMenu 获取产品类别的表单中存储数据.h:selectOneMenu 是从 DB 填充的,但是,当尝试在 DB 中存储产品时,我收到一个错误:Conversion Error setting value '52' for 'null Converter'.我已经在 StackOverflow 和在线教程中查看了类似的问题,但仍然出现错误.

I'm new to JSF and I have been trying to store data from a form that uses a h:selectOneMenu to get the category of a product. The h:selectOneMenu is being populated from the DB, however, when trying to store a product in the DB, I am getting an error: Conversion Error setting value '52' for 'null Converter'. I have reviewed similar problems in StackOverflow and tutorials online but I am still getting the error.

这是 xhtml:

<h:selectOneMenu id="category_fk" value="#{productController.product.category_fk}" 
                                 converter="#{categoryConverter}" title="Category_fk" >
                    <!-- DONE: update below reference to list of available items-->
                    <f:selectItems value="#{productController.categoryList}" var="prodCat"
                                   itemValue="#{prodCat}" itemLabel="#{prodCat.name}"/>
                </h:selectOneMenu>

这是产品控制器:

@Named
@RequestScoped
public class ProductController {

    @EJB
    private ProductEJB productEjb;
    @EJB
    private CategoryEJB categoryEjb;

    private Product product = new Product();
    private List<Product> productList = new ArrayList<Product>();

    private Category category;
    private List<Category> categoryList = new ArrayList<Category>();

    public String doCreateProduct()
    {
        product = productEjb.createProduct(product);
        productList = productEjb.findAllProducts();
        return "listProduct";
    }

    @PostConstruct
    public void init()
    {
        categoryList = categoryEjb.findAllCategory();
        productList = productEjb.findAllProducts();
    }        

    // Getters/Setters and other methods omitted for simplicity

这是为简单起见而简化的 EJB:

This is the EJB simplified for simplicity:

   @Stateless
    public class ProductEJB{

        @PersistenceContext(unitName = "luavipuPU")
        private EntityManager em;

        public List<Product> findAllProducts()
        {
            TypedQuery<Product> query = em.createNamedQuery("findAllProducts", Product.class);
            return query.getResultList();
        }

        public Product createProduct(Product product)
        {
            em.persist(product);
            return product;
        }    

    }

这是为简单起见而简化的产品实体:

This is the product Entity simplified for simplicity:

@Entity
@NamedQueries({
    @NamedQuery(name="findAllProducts", query = "SELECT p from Product p")
})
public class Product implements Serializable
{
    private static final long serialVersionUID = 1L;

    @Id @GeneratedValue(strategy= GenerationType.AUTO)
    private int product_id;
    private String name;
    private String description;
    protected byte[] imageFile;
    private Float price;
    @Temporal(TemporalType.TIMESTAMP)
    private Date dateAdded;
    @ManyToOne    
    private Category category_fk;
    @ManyToOne
    private SaleDetails saleDetails_fk;

这是我正在使用的更新后的转换器:

This is the updated converter I am using:

@ManagedBean
@FacesConverter(value="categoryConverter")
public class CategoryConverter implements Converter{

    @PersistenceContext
    private transient EntityManager em;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        return em.find(Category.class, new Integer(value));
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {

        Category category;
        category = (Category) value;
        return String.valueOf(category.getCategory_id());

    }

}

代码已从原始问题中更新,代码现在完美运行.

The code has been updated from the Orignal problem, the code perfectly works now.

推荐答案

您不能在 组件(或任何 <h:selectXXXX/>) 而不创建 JSF 转换器.JSF 中存在转换器以帮助将基本上自定义或服务器端的项目/结构转换为网页友好/人类可读的格式,并且还能够将来自客户端的选择保存回服务器端.因此,错误消息本质上告诉您的是,从客户端提交的值 52 不足以将其作为 Category 保存到服务器端对象/类型

You can't use a custom type on the <h:selectOneMenu/> component (or any of the <h:selectXXXX/>) without creating a JSF Converter. Converters exist in JSF to assist with translating essentially custom or sever-side items/constructs into web page friendly/human readable formats and also to be able to save selections from the client side back to the server side. So what the error message is essentially telling you there is that it cannot make sense enough of the value 52 submitted from the client side to save it to the server side as a Category object/type

所以你需要做的是创建一个 JSF converter 的实现,它本质上帮助 JSF 理解你的 Category 对象.

So what you're required to do is to create an implementation of a JSF converter that essentially helps JSF make sense of your Category object.

以下是对您需要执行的操作的粗略估计:

Here's a rough estimation of what you need to do:

  1. 为您的 Category 类型实现转换器:

// You must annotate the converter as a managed bean, if you want to inject
// anything into it, like your persistence unit for example.
@ManagedBean(name = "categoryConverterBean") 
@FacesConverter(value = "categoryConverter")
public class CategoryConverter implements Converter {

    @PersistenceContext(unitName = "luavipuPU")
    // I include this because you will need to 
    // lookup  your entities based on submitted values
    private transient EntityManager em;  

    @Override
    public Object getAsObject(FacesContext ctx, UIComponent component,
            String value) {
      // This will return the actual object representation
      // of your Category using the value (in your case 52) 
      // returned from the client side
      return em.find(Category.class, new BigInteger(value)); 
    }

    @Override
    public String getAsString(FacesContext fc, UIComponent uic, Object o) {
        //This will return view-friendly output for the dropdown menu
        return ((Category) o).getId().toString(); 
    }
}

  • <h:selectOneMenu id="category_fk" 
      converter="#{categoryConverterBean}"
      value="#productController.product.category_fk}" 
      title="Category_fk" >
    <!-- DONE: update below reference to list of available items-->
        <f:selectItems value="#{productController.categoryList}" 
          var="prodCat" itemValue="#{prodCat.category_id}" 
          itemLabel="#{prodCat.name}"/>
    </h:selectOneMenu>
    

  • 我们使用名称 categoryConverterBean 是因为我们想利用您在转换器中引入的实体管理器技巧.在任何其他情况下,您将使用在转换器注释上设置的名称.

    We're using the name categoryConverterBean because we want to take advantage of the entity manager trick you pulled in the converter. Any other case, you would've used the name you set on the converter annotation.

    这篇关于“空转换器"的转换错误设置值“52"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆