我正在尝试检索一个简单的JSON列表,将此JSON数组转换为Eclipselink对象并将它们放在postgres中。虽然我不断从EntityManager获取nullpointers,但我已经失去了轨道。
我从测试网络服务调用我的控制器:
@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服务调用此方法,只是为了测试它。我计划在后台使用单独的线程将其拉入。
但是我做错了什么?这种持久性设置非常混乱?!?
答案 0 :(得分:2)
主要问题是AppController
不是托管对象,因此不会在其中执行依赖注入。您需要将AppController
作为托管bean注入servlet,或者使用EntityManagerFactory
实用程序类手动初始化javax.persistence.Persistence
。如果AppController
完全无状态,您可以使用@Inject
注释将其作为CDI托管bean注入。
如果您注入AppController,另一个问题是EntityManagerFactory
仅在构造AppController
对象后注入,但在对象构造期间初始化字段。创建新的AppController对象时,emf
字段初始化为null,因此初始化em
字段的尝试将导致空指针异常。
EntityManagers也不是线程安全的,所以如果你确实通过CDI注入它,你需要在EntityManager
方法中从工厂创建updateAppList()
。这样做的缺点是事务管理和关闭实体管理器将是您自己的责任。
另一种方法是将AppController
转换为EJB无状态会话bean,然后将其注入servlet中。在这种情况下,您不需要注入EntityManagerFactory,但可以使用EntityManager
注释直接注入@PersistenceContext
。