I'm trying to retrieve a simple JSON list, convert this JSON array to Eclipselink objects and put them in postgres. Although i keep getting nullpointers from the EntityManager and i've lost track.
Im calling my controller from a test webservice:
@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();
}
}
In the controller im trying to persist these converted objects:
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);
}
}
}
Im calling this method from a webservice, only to test it out. Im planning to use seperate threads for pulling it in, in the background.
But what am i doing wrong? This persistance setup is very confusing?!?
The main issue is that the AppController
is not a managed object and so no dependency injection will be performed in it. You either need to inject the AppController
into the servlet as a managed bean or manually initialise the EntityManagerFactory
using the javax.persistence.Persistence
utility class. If the AppController
is fully stateless you could inject it as a CDI managed bean using the @Inject
annotation.
Another problem if you do inject the AppController is that the EntityManagerFactory
is only injected after the AppController
object has been constructed, but fields are initialised during object construction. When a new AppController object is created, the emf
field is initialised to null and so the attempt to initialise the em
field will lead to a null pointer exception.
EntityManagers are also not thread-safe, so if you do go the route of injecting it through CDI, you will need to create the EntityManager
from the factory in the updateAppList()
method. This has the drawback that transaction management and closing the entity manager will be your own responsibility.
An alternative is to convert the AppController
to an EJB stateless session bean and then injecting this in the servlet. In this case you don't need to inject the EntityManagerFactory, but can directly inject the EntityManager
using the @PersistenceContext
annotation.