JPA Property Access提供NullPointerException

时间:2013-06-12 20:20:50

标签: java jpa

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

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

我有这样的图层:

products.xhtml - > ProductsBackingBean.java - >产品Dao.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();
        }
    }

And 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不存在。 session-key:3890c00100a81f-3a922970-0

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

同样在日志中我看到:

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

如果我删除子字符串(0,20),一切都很好。

我有两个问题:

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

2 个答案:

答案 0 :(得分: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) : "";
    }

答案 1 :(得分:2)

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