0

我的数据库中有一个名为 Products 的表,我正在使用 JPA 2.0 来访问它。

我在 Glassfish 服务器上使用 JSF 2.0。

我有这样的图层:

products.xhtml -> ProductsBackingBean.java -> ProductsDao.java -> Produtcs.Java

这是 products.xhtml :

<h:form>
    <p:dataTable var="product" value="#{productsBackingBean.allProducts}">
        <p:column headerText="Product Code">
            <h:outputText value="#{product.productCode}"/>
        </p:column>
        <p:column headerText="Product Description">
            <h:outputText value="#{product.productDescription}"/>
        </p:column>
    </p:dataTable>
</h:form>

这是 ProductsBackinBean.java:

package com.tugay.maythirty.model;

import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

    @Named
    @SessionScoped
    public class ProductsBackingBean implements Serializable {
        @EJB private ProductsDao productsDao;
        public List<Products> getAllProducts(){
           return productsDao.getAllProducts();
        }
    }

和 ProductsDao.Java:

package com.tugay.maythirty.model;

import javax.annotation.PostConstruct;
import javax.ejb.Stateful;
import javax.persistence.*;
import java.util.List;

@Stateful
public class ProductsDao {

    @PostConstruct
    public void init() {
        System.out.println("Init");
    }

    public List<Products> allProducts;

    public List<Products> getAllProducts() {

        EntityManagerFactory emf = Persistence.createEntityManagerFactory("Persistence");
        EntityManager em = emf.createEntityManager();
        if (allProducts == null) {
            TypedQuery<Products> typedQuery = em.createQuery("Select p from Products p", Products.class);
            allProducts = typedQuery.getResultList();
        }
        return allProducts;
    }
}

这是 Products.Java:

@Entity
public class Products {

    private String productCode;
    private String productDescription;

    @javax.persistence.Column(name = "productCode")
    @Id
    public String getProductCode() {
        return productCode;
    }

    public void setProductCode(String productCode) {
        this.productCode = productCode;
    }

    @javax.persistence.Column(name = "productDescription")
    @Basic
    public String getProductDescription() {
        return productDescription.substring(0,20);
    }

    public void setProductDescription(String productDescription) {
        this.productDescription = productDescription;
    }

    @Override
    public int hashCode() {
        // some hashcode here. not relevant. 
    }
}

所以重要的部分是:

返回 productDescription.substring(0,20);

在我的表格中,我只想显示产品描述的前 20 个字符。但是我得到一个例外:

异常 javax.servlet.ServletException 根本原因 javax.ejb.NoSuchEJBException 根本原因 javax.ejb.NoSuchObjectLocalException:EJB 不存在。会话密钥:3890c00100a81f-3a922970-0

我必须注意,当我在 ProductDao 的 init() 方法中设置断点时,我看到它被调用了。但是,当 ProductBackingBean 调用 productDao.getAllProducts 时,productDao 似乎为空。

同样在日志中我看到:

在 com.tugay.maythirty.model。EJB31_Generated_ ProductsDao _Intf_ Bean _.getAllProducts(Unknown Source) at com.tugay.maythirty.model.ProductsBackingBean.getAllProducts(ProductsBackingBean.java:14)

如果我删除 substring(0,20) 一切都很好。

我有两个问题:

  1. 我做错了什么?
  2. 显示前 20 个字符的正确方法是什么?它应该在 ProductsTableBackingBean.java、ProductsDao.java 中还是直接在 Entity 类中,如此处所示?
4

2 回答 2

3

它可能null productDescription在数据库中,因此有必要在它null之前检查一个值substring,如下例所示:

@javax.persistence.Column(name = "productDescription")
@Basic
public String getProductDescription() {
        return productDescription !=null ? productDescription.substring(0,20) : "";
}

但我建议您保持getProductDescription()原样并创建一个新的以返回简短描述,它将是:

    @javax.persistence.Column(name = "productDescription")
    @Basic
    public String getProductDescription() {
            return productDescription;
        }

    public String getShortDescription() {
        return productDescription !=null ? productDescription.substring(0,20) : "";
    }
于 2013-06-12T22:18:39.893 回答
2

正确的方法是在 ui 层修剪你的价值。实体字段可能会在其完全初始化之前被访问,这会导致您尝试修剪空值。

于 2013-06-12T20:22:49.473 回答