簡體   English   中英

Java EntityManager空指針

[英]Java EntityManager nullpointer

我正在嘗試檢索一個簡單的JSON列表,將此JSON數組轉換為Eclipselink對象,並將它們放在postgres中。 雖然我一直從EntityManager獲取nullpointers,但我已經迷路了。

我從測試Web服務調用我的控制器:

@WebServlet(name = "Test", urlPatterns = {"/Test"})
public class Test extends HttpServlet {


    /**
     * Processes requests for both HTTP
     * <code>GET</code> and
     * <code>POST</code> methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            // HERE I CALL CUSTOM METHODS
            AppController appConn = new AppController();
            appConn.updateAppList();
        } finally {            
            out.close();
        }
    }

在控制器中,im試圖保留這些轉換后的對象:

public class AppController {
    @PersistenceUnit(unitName="UserPU")
    EntityManagerFactory emf;
    EntityManager em = emf.createEntityManager();


    public AppController() {

    }

    public void updateAppList() {
        try {
            URLController urlConn = new URLController(Config.allAppsURL);
            JsonElement jelement = new JsonParser().parse(urlConn.toString());
            JsonObject  jobject = jelement.getAsJsonObject();
            jobject = jobject.getAsJsonObject("applist");
            JsonArray jarray = jobject.getAsJsonArray("apps");

            ArrayList<SteamApp> apps = new ArrayList<App>(){};
            for(int i = 0; i < jarray.size(); i++) {
                JsonObject jsteamObject = jarray.get(i).getAsJsonObject();
                App app = new SteamApp(jsteamObject.get("appid").getAsLong(), jsteamObject.get("name").toString());
                apps.add(app);
                //System.out.println("App[" + app.getAppid() + ", " + app.getName() + "] \n\r");
            }

            em.persist(apps);
            em.flush();

        } catch (Exception ex) {
            Logger.getLogger(AppController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

我從網絡服務中調用此方法,只是為了對其進行測試。 我打算在后台使用單獨的線程將其拉入。

但是我在做什么錯呢? 這種持久性設置非常令人困惑?!?

主要問題是AppController不是托管對象,因此不會在其中執行依賴項注入。 您要么需要將AppController作為托管bean注入到servlet中,要么需要使用javax.persistence.Persistence實用程序類手動初始化EntityManagerFactory 如果AppController完全是無狀態的,則可以使用@Inject批注將其作為CDI托管bean注入。

如果要注入AppController的另一個問題是,僅在構造AppController對象之后才注入EntityManagerFactory ,但是在對象構建過程中初始化字段。 創建新的AppController對象時, emf字段將初始化為null,因此嘗試初始化em字段將導致null指針異常。

EntityManager也不是線程安全的,因此如果您通過CDI注入它,則需要從工廠在updateAppList()方法中創建EntityManager 這樣做的缺點是事務管理和關閉實體經理將由您自己負責。

一種替代方法是將AppController轉換為EJB無狀態會話bean,然后將其注入到servlet中。 在這種情況下,您不需要注入EntityManagerFactory,但是可以使用@PersistenceContext批注直接注入EntityManager

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM