2015-10-27 57 views
0

我對Java EE相對來說比較新,對於如何從我的企業應用程序客戶端訪問無狀態Java Bean,我有點困惑。無狀態EJB拋出企業應用程序客戶端中的NullPointerException

我的意圖是爲我的企業bean CarReposityImpl處理名爲Car的實體類的數據庫訪問和實體管理。

我CarRepositoryImpl樣子:

@Stateless 
public class CarRepositoryImpl implements CarRepository 
{ 
    @PersistenceContext(unitName = "FIT5042AssignmentEJBPU") 
    private EntityManager entityManager; 

    @Override 
    public void addCar(Car car) 
    { 
     entityManager.persist(car); 
    } 

    @Override 
    public Car searchByVIN(String vin) throws Exception 
    { 
     Car car = entityManager.find(Car.class, vin); 
     return car; 
    } 

    @Override 
    public List<Car> getAllCars() throws Exception 
    {   
     return entityManager.createNamedQuery(Car.GET_ALL_QUERY_NAME).getResultList(); 
    } 

    @Override 
    public void removeCar(String vin) throws Exception 
    {   
     Car car = searchByVIN(vin); 

     if (car != null) 
     { 
      entityManager.remove(car); 
     } 
    }  

    @Override 
    public void editCar(Car car) throws Exception 
    {  
     entityManager.merge(car); 
    }  
} 

它實現了接口CarRepository,看起來像:

@Remote 
public interface CarRepository 
{ 
    public void addCar(Car car); 
    public Car searchByVIN(String vin) throws Exception; 
    public List<Car> getAllCars() throws Exception; 
    public void removeCar(String vin) throws Exception; 
    public void editCar(Car car) throws Exception; 
} 

實體類車的樣子:

@Entity 
@Table(name = "CAR") 
@NamedQueries({@NamedQuery(name = Car.GET_ALL_QUERY_NAME, query = "SELECT c FROM Car AS c")}) 
public class Car implements Serializable 
{ 
    public static final String GET_ALL_QUERY_NAME = "Car.getAll"; 
    //private Sale sale; 
    String modelNo, VIN, model, make, type, thumbnail, description, prevURL; 

    public Car() { 
    } 

    public Car(String varModelNo, String varVIN, String varModel, String varMake, String varType, String varThumb, String varDesc, String varPrevURL) 
    { 
     modelNo = varModelNo; 
     VIN = varVIN; 
     model = varModel; 
     make = varMake; 
     type = varType; 
     thumbnail = varThumb; 
     description = varDesc; 
     prevURL = varPrevURL; 
    } 

    public void setModelNo(String varModNo){modelNo = varModNo;} 
    public void setVIN(String varVIN){VIN = varVIN;} 
    public void setModel(String varMod){model = varMod;} 
    public void setMake(String varMake){make = varMake;} 
    public void setType(String varType){type = varType;} 
    public void setThumbnail(String varThumb){thumbnail = varThumb;} 
    public void setDesc(String varDesc){description = varDesc;} 
    public void setPrevURL(String varPrev){prevURL = varPrev;} 

    @Column(name = "modelNo") 
    public String getModelNo(){return modelNo;} 

    @Id 
    @Column(name = "VIN") 
    public String getVIN(){return VIN;} 

    @Column(name = "model") 
    public String getModel(){return model;} 

    @Column(name = "make") 
    public String getMake(){return make;} 

    @Column(name = "type") 
    public String getType(){return type;} 

    @Column(name = "thumbnail") 
    public String getThumbnail(){return thumbnail;} 

    @Column(name = "description") 
    public String getDesc(){return description;} 

    @Column(name = "prevURL") 
    public String getPrevURL(){return prevURL;} 
} 

從我的理解我應該可以加上這一行:

public class CarSales 
{ 
    @EJB 
    private static CarRepository carRepo; 

添加到我的企業應用程序客戶端中用於處理業務邏輯的類中,然後我應該可以調用CarRepositoyImpl bean中的方法來訪問我的數據庫。我非常肯定,我不應該像普通對象那樣實例化carRepo對象,因爲EJB容器應該處理該對象。

基本上我希望能夠用我的無狀態Bean在我的應用程序客戶端這樣的:

List<Car> cars = carRepo.getAllCars(); 

但是當我做它拋出一個空指針異常,我不知道爲什麼。

我的應用程序客戶端類,因爲它目前爲,它主要是不完整的:我的錯誤的

public class CarSales 
{ 
    @EJB 
    private static CarRepository carRepo; 

    private final MainScreen main; 

    public CarSales() 
    { 
     main = new MainScreen(); 
     addCarActionListeners(); 
    } 

    public void run() 
    { 
     displayAllCars(); 
    } 

    private void displayAllCars() 
    { 
     main.getCarScreen().clearTable(); 

     try 
     { 
      List<Car> cars = carRepo.getAllCars(); 

      for(Car car : cars) 
      {//"VIN", "Model Number", "Model Name", "Make", "Thumbnail", "Description", "URL" 
       String[] data = new String[7]; 
       data[0] = car.getVIN(); 
       data[1] = car.getModelNo(); 
       data[2] = car.getModel(); 
       data[3] = car.getMake(); 
       data[4] = car.getThumbnail(); 
       data[5] = car.getDesc(); 
       data[6] = car.getPrevURL(); 
       main.getCarScreen().getModel().addRow(data); 
      } 
     } 
     catch(Exception ex) 
     { 
      main.getCarScreen().outputAddError(ex.getMessage()); 
      System.out.println("failed"); 
      ex.printStackTrace(); 
     } 
    } 

    private void addCarActionListeners() 
    {//CLOSE 
     main.getCarScreen().getClose().addActionListener(new ActionListener() 
     { 
      @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       main.closeWindow(); 
      } 
     }); 

     main.getCarScreen().getAdd().addActionListener(new ActionListener() 
     { 
      @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       Car car = new Car(main.getCarScreen().getModelNo(), 
          main.getCarScreen().getVin(), 
          main.getCarScreen().getModelName(), 
          main.getCarScreen().gerMake(), 
          main.getCarScreen().getType(), 
          main.getCarScreen().getThumb(), 
          main.getCarScreen().getDesc(), 
          main.getCarScreen().getUrl()); 
       try 
       { 
        System.out.println("try"); 
        carRepo.addCar(car); 
        displayAllCars(); 
       } 
       catch(Exception ex) 
       { 
        System.out.println("catch"); 
        //main.getCarScreen().outputAddError(ex.getMessage()); 
        System.out.println(ex.getMessage()); 
       } 
      } 
     }); 
    } 
} 

堆棧跟蹤:45

java.lang.NullPointerException 
at CarSales.CarSales.displayAllCars(CarSales.java:45) 
at CarSales.CarSales.run(CarSales.java:36) 
at CarSales.Main.main(Main.java:18) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:606) 
at org.glassfish.appclient.client.acc.AppClientContainer.launch(AppClientContainer.java:446) 
at org.glassfish.appclient.client.AppClientFacade.main(AppClientFacade.java:166) 

線路是:

List<Car> cars = carRepo.getAllCars(); 

製造對我的CarSales類別的一些建議更改:

public class CarSales 
{ 
    @EJB 
    private CarRepository carRepo; 

    private final MainScreen main; 

    public CarSales() 
    { 
     main = new MainScreen(); 
    } 

    @PostConstruct 
    public void init() 
    { 
     addCarActionListeners(); 
    } 

    public void run() 
    { 
     displayAllCars(); 
    } 

我的主要功能是調用run:

public class Main 
{ 
    public static void main(String[] args) 
    { 
     CarSales sys = new CarSales(); 
     sys.run(); 
    } 
} 
+0

等一下。您是否試圖將您的企業應用程序作爲獨立應用程序運行?你必須將它部署到某個應用程序服務器上,並且不能像這樣運行'main'方法! – wawek

+0

我通過玻璃魚運行。 – user2787386

+0

這是你試圖做的某種教程嗎?我認爲你不能以這種方式調用'main'方法。你應該創建'Singleton',它將在啓動時調用你想要的。或者,也許你找到了可以在應用程序服務器上調用main方法的地方? – wawek

回答

1

如果您自己創建一個對象,那麼該容器就沒有機會執行注入。在客戶端容器中,實際上只有主類纔有資格注入。嘗試:

public class Main 
{ 
    @EJB 
    private static CarRepository carRepo; 

    public static void main(String[] args) 
    { 
     CarSales sys = new CarSales(carRepo); 
     sys.run(); 
    } 
} 

public class CarSales 
{ 
    private final CarRepository carRepo; 
    private final MainScreen main; 

    public CarSales(CarRepository carRepo) 
    { 
     this.carRepo = carRepo; 
     main = new MainScreen(); 
    } 

或者,你可以宣佈你的主類的引用,然後從任何地方查找EJB引用在客戶端應用程序:

@EJB(name="ejb/carRepo", beanInterface=CarRepository.clas) 
public class Main 
{ 
    public static void main(String[] args) 

... 
CarRepository carRepo = (CarRepository)new InitialContext().lookup("java:comp/env/ejb/carRepo"); 
0

從你寫什麼,我假設你正在試圖撥打carRepo.getAllCars()CarSales構造。你不能在那裏做到這一點。用PostConstruct註解的方法代替。

你應該這樣做,而不是:

public CarSales() { 
    main = new MainScreen(); 
} 

@PostConstruct 
public void init() { 
    addCarActionListeners(); 
} 

確定一個以上的編輯。 爲什麼你的注射豆標記爲static?不應該這樣做。

+0

建立依賴關係後立即發生PostConstruct。我也希望能夠在運行時訪問bean。假設我需要在數據庫中搜索特定的汽車或編輯汽車的價值。 – user2787386

+0

然後顯示更多的代碼,您可以從注入的bean中調用異常堆棧跟蹤的方法。 – wawek

+0

這就是我告訴你的。在構造函數中調用'addCarActionListeners'方法,並在那裏調用注入bean的方法。你不可以做這個。 – wawek

相關問題