-1

我正在尝试检索一个简单的 JSON 列表,将此 JSON 数组转换为 Eclipselink 对象并将它们放入 postgres。尽管我不断从 EntityManager 获取空指针,但我已经迷失了方向。

我从测试网络服务调用我的控制器:

@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();
        }
    }

在控制器中,我试图保留这些转换后的对象:

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);
        }
    }
}

我从 web 服务调用这个方法,只是为了测试它。我计划在后台使用单独的线程将其拉入。

但我做错了什么?这种持久性设置非常混乱?!?

4

1 回答 1

2

主要问题是它AppController不是托管对象,因此不会在其中执行依赖注入。您要么需要将AppControllerservlet 作为托管 bean注入,要么EntityManagerFactory使用javax.persistence.Persistence实用程序类手动初始化。如果它是完全无状态的,您可以使用注释AppController将其作为 CDI 托管 bean 注入。@Inject

如果您确实注入 AppController 的另一个问题是,仅在构造对象EntityManagerFactory后才注入AppController,但在对象构造期间初始化字段。当创建一个新的 AppController 对象时,该emf字段被初始化为 null,因此尝试初始化该em字段将导致空指针异常。

EntityManagers 也不是线程安全的,所以如果你确实通过 CDI 注入它,你将需要EntityManager在方法中从工厂创建updateAppList()。这样做的缺点是事务管理和关闭实体管理器将是您自己的责任。

另一种方法是将 bean 转换AppController为 EJB 无状态会话 bean,然后将其注入 servlet。在这种情况下,您不需要注入 EntityManagerFactory,而是可以直接EntityManager使用@PersistenceContext注解注入。

于 2012-12-30T22:16:49.020 回答