2013-06-12 32 views
0

我有一個名爲產品在我的數據庫中的表,我使用JPA 2.0來訪問它。JPA屬性訪問給NullPointerException

我在Glassfish Server上使用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(); 
     } 
    } 

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。

而且在日誌中我看到:

在com.tugay.maythirty.model。 EJB31_Generated_ 用ProductsDao _Intf_ _.getAllProducts(未知來源) 在com.tugay.maythirty.model.ProductsBackingBean.getAllProducts(ProductsBackingBean.java:14)

如果刪除了子串(0, 20)一切都很好。

我有2個問題:

  1. 它是什麼,我做錯了什麼?
  2. 什麼是正確方式得到前20個字符顯示?它應該在ProductsTableBackingBean.java,ProductsDao.java中還是直接位於Entity類中?
+0

看來你有「產品描述」值作爲數據庫空。在做subString之前,做空檢查 – kosa

+0

@Nambari如果我刪除子字符串(0,20),一切都很好。 –

+0

是的,如果您對空引用執行任何操作,NPE會發生。所以,我的猜測是你正在將productdescription設爲null。 – kosa

回答

3

它可能在數據庫nullproductDescription,所以需要substring之前,檢查是否有null值它,如下面的例子:

@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) : ""; 
    } 
2

正確的方法是在ui層裁減你的價值。實體字段可能會在其完全初始化之前被訪問,這會導致您嘗試修剪空值。

+0

我認爲bean有問題,而不是值本身。是真的嗎? –