How do I actually instantiate the JPA controller below?
I'm fuzzy on how a Netbeans created JPA controller is actually used. I certainly appreciate the Netbeans wizard in this case, it's interesting -- I'm trying to understand how it works and why it works this way.
The ejb module can just inject from Glassfish along these lines:
#PersistenceUnit(unitName="JSFPU") //inject from your application server
EntityManagerFactory emf;
#Resource //inject from your application server
UserTransaction utx;
and then, to instantiate the controller, something like this:
PersonEntityJpaController pejc = new PersonEntityJpaController(utx, emf); //create an instance of your jpa controller and pass in the injected emf and utx
try {
pejc.create(pe); //persist the entity
Where can I find more information about how to inject the PU from, in this case, Glassfish, as well as how #Resource works? I don't at all mind reading Glassfish for JavaEE docs from Oracle, or other reference material.
The controller Netbeans generated:
package db;
import db.exceptions.NonexistentEntityException;
import db.exceptions.RollbackFailureException;
import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.transaction.UserTransaction;
public class ClientsJpaController implements Serializable {
public ClientsJpaController(UserTransaction utx, EntityManagerFactory emf) {
this.utx = utx;
this.emf = emf;
}
private UserTransaction utx = null;
private EntityManagerFactory emf = null;
public EntityManager getEntityManager() {
return emf.createEntityManager();
}
public void create(Clients clients) throws RollbackFailureException, Exception {
EntityManager em = null;
try {
utx.begin();
em = getEntityManager();
em.persist(clients);
utx.commit();
} catch (Exception ex) {
try {
utx.rollback();
} catch (Exception re) {
throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
}
throw ex;
} finally {
if (em != null) {
em.close();
}
}
}
public void edit(Clients clients) throws NonexistentEntityException, RollbackFailureException, Exception {
EntityManager em = null;
try {
utx.begin();
em = getEntityManager();
clients = em.merge(clients);
utx.commit();
} catch (Exception ex) {
try {
utx.rollback();
} catch (Exception re) {
throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
}
String msg = ex.getLocalizedMessage();
if (msg == null || msg.length() == 0) {
Integer id = clients.getId();
if (findClients(id) == null) {
throw new NonexistentEntityException("The clients with id " + id + " no longer exists.");
}
}
throw ex;
} finally {
if (em != null) {
em.close();
}
}
}
public void destroy(Integer id) throws NonexistentEntityException, RollbackFailureException, Exception {
EntityManager em = null;
try {
utx.begin();
em = getEntityManager();
Clients clients;
try {
clients = em.getReference(Clients.class, id);
clients.getId();
} catch (EntityNotFoundException enfe) {
throw new NonexistentEntityException("The clients with id " + id + " no longer exists.", enfe);
}
em.remove(clients);
utx.commit();
} catch (Exception ex) {
try {
utx.rollback();
} catch (Exception re) {
throw new RollbackFailureException("An error occurred attempting to roll back the transaction.", re);
}
throw ex;
} finally {
if (em != null) {
em.close();
}
}
}
public List<Clients> findClientsEntities() {
return findClientsEntities(true, -1, -1);
}
public List<Clients> findClientsEntities(int maxResults, int firstResult) {
return findClientsEntities(false, maxResults, firstResult);
}
private List<Clients> findClientsEntities(boolean all, int maxResults, int firstResult) {
EntityManager em = getEntityManager();
try {
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
cq.select(cq.from(Clients.class));
Query q = em.createQuery(cq);
if (!all) {
q.setMaxResults(maxResults);
q.setFirstResult(firstResult);
}
return q.getResultList();
} finally {
em.close();
}
}
public Clients findClients(Integer id) {
EntityManager em = getEntityManager();
try {
return em.find(Clients.class, id);
} finally {
em.close();
}
}
public int getClientsCount() {
EntityManager em = getEntityManager();
try {
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
Root<Clients> rt = cq.from(Clients.class);
cq.select(em.getCriteriaBuilder().count(rt));
Query q = em.createQuery(cq);
return ((Long) q.getSingleResult()).intValue();
} finally {
em.close();
}
}
}
the class which will create and call methods on the controller; it is intended to provide a single queue for the web module to pop elements (in this, int's) from:
package db;
import javax.ejb.Singleton;
#Singleton
public class MySingletonQueue implements RemoteQueue {
private int next = 3; //dummy
private ClientsJpaController cjc; //instantiate how?
#Override
public int getNext() {
return next; //get next int from perhaps another class or method...
}
}
for context, the bean which the web page instantiates with EL:
package dur;
import db.RemoteQueue;
import java.io.Serializable;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
#Named
#SessionScoped
public class MySessionBean implements Serializable {
#EJB
private RemoteQueue mySingletonQueue;
private static final long serialVersionUID = 1L;
private static final Logger log = Logger.getLogger(MySessionBean.class.getName());
public MySessionBean() {
}
public int getNext() {
log.info("getting next int from remote EJB");
return mySingletonQueue.getNext();
}
}
http://forums.netbeans.org/viewtopic.php?t=47442&highlight=jpa+controller+constructor
Answer is simple:
package db;
import javax.ejb.Singleton;
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
#Singleton
public class MySingletonQueue implements RemoteQueue {
private int next = 3;
private ClientsJpaController cjc;
#PersistenceUnit
private EntityManagerFactory emf;
#Resource
private UserTransaction utx;
#PostConstruct
public void initBean() {
// Instantiate your controller here
cjc = new ClientsJpaController(utx, emf);
}
// rest of the class ...
}
But keep in mind that although it will work, what you are doing is extremely messy and unmaintainable and is considered a bad practice.
Update
Some advice:
You should inject an entity manager to your ClientsJpaController (also consider renaming it to ClientDAO)
Do not manage transactions in a server environment, lets server do that. Your code would be simplified to just a few lines.
Your entity Clients is in plural form, it should be singular because it represents single client, doesn't it?
You definitely should not do something like: catch (Exception ex) {, because it is a root of all exceptions. Catch only the most specific exception instead.
So, for example, your edit function can be shortened to:
public Client edit(Client client) {
return em.merge(client);
}
You should definitely take a look at some EJB/ JPA book or read some decent guide.
Related
Good afternoon, I am experiencing an issue where my spring application is not autowiring a Datasource to a DAO. The database is a postgresql db being ran on my local machine. I'm getting a null pointer exception in my userDAO where we try to execute datasource.getConnection, which is the error being caused when a certain endpoint of the api is requested. In the DatabaseConfig class method postgresDatasource, there is a commented out try catch block where I see if we still get thrown a null pointer exception if we attempt ds.getConnection. It does not throw an exception in there, event though that code is being ran at server build. Like I said, the error gets thrown when I assume that the autowiring is being execute corrected and we try datasource.getConnection. All relevant code will be pasted below. first is the DatabaseConfig class. It may be worth noting that my DatabaseConfig is in com.example.config, and the DAO is in com.example.dao
#Configuration
#ComponentScan(basePackages="com.example")
public class DatabaseConfig {
#Bean
public DataSource postgresDataSource() {
final DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("org.postgresql.Driver");
ds.setUrl("jdbc:postgresql://localhost:5432/postgres");
ds.setUsername("username");
ds.setPassword("password");
// System.out.println("Returning ds object after setting parameters");
// System.out.println(ds.toString());
// try {
// System.out.println("Attempting connection at server build.");
// ds.getConnection();
// } catch (SQLException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
System.out.println("DataSource postgresDataSource() is being ran");
return ds;
}
}
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import com.fmn.config.DatabaseConfig;
import com.fmn.dto.UserDTO;
#Repository
public class UserDAO {
// #Autowired
private DataSource datasource;
// #Autowired
// public void setDataSource(DataSource datasource) {
// this.datasource = datasource;
// }
//
#Autowired
public UserDAO(DataSource datasource){
System.out.println("Setting datasource in constructor");
this.datasource = datasource;
}
//
public UserDAO() {};
public boolean addUser(UserDTO user) {
//TODO: implement
return false;
}
public boolean updateUser(UserDTO user) {
//TODO: implement
return false;
}
public UserDTO getUserInfo(UserDTO user)/*throws UserNotFoundException*/ {
//TODO: implement
if(user.getUserId() != null) {
return getUserInfoWithUserID(user);
} else if (user.getEmail() != null) {
return getUserInfoWithEmail(user);
} else if (user.getPhoneNum() != null) {
return getUserInfoWithPhone(user);
}
//else throw new UserNotFoundException();
return null;
}
private UserDTO getUserInfoWithEmail(UserDTO user) {
//TODO: implement
return null;
}
private UserDTO getUserInfoWithPhone(UserDTO user) {
//TODO: implement
return null;
}
public UserDTO getUserInfoWithUserID(UserDTO user) {
UserDTO outUser = null;
ResultSet result = null;
Connection conn = null;
try {
// DatabaseConfig dbc = new DatabaseConfig();
// System.out.println("Setting datasource");
// datasource = dbc.postgresDataSource();
System.out.println("Calling datasource.getConnection()");
conn = datasource.getConnection();
CallableStatement caller = conn.prepareCall("{?= call get_user_info_with_userid(?)}");
caller.registerOutParameter(1, Types.REF_CURSOR);
caller.setString(2, user.getUserId());
caller.execute();
result = caller.getResultSet();
result.next();
outUser = setUserDTOFromResultSet(result);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return outUser;
}
private UserDTO setUserDTOFromResultSet(ResultSet result) throws SQLException {
UserDTO outUser = new UserDTO();
outUser.setDOB(result.getDate("DOB"));
outUser.setUserId(result.getString("USER_ID"));
outUser.setfName(result.getString("F_NAME"));
outUser.setlName(result.getString("L_NAME"));
outUser.setEmail(result.getString("EMAIL"));
outUser.setAliveFlg(result.getString("ALIVE_FLG"));
return outUser;
}
}
#SpringBootApplication
#EnableAutoConfiguration
#ComponentScan(basePackageClasses = {DatabaseConfig.class, InteractiveController.class, UserDAO.class})
public class Application {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(DatabaseConfig.class);
ctx.refresh();
SpringApplication.run(Application.class, args);
}
}
Your feedback and input is appreciated. Thank you!
I don't know if I need more coffee, or my head is tired, but, I feel like an idiot :)
what am I doing wrong???
I want to call the methods within the class but I get complile errors.
Compilation failure: Compilation failure:
java:[35,1] error: illegal start of type
java:[35,21] error: <identifier> expected
java:[35,22] error: ';' expected
I can't execute this block in the class
//this is what doesn't work
if (custkey.contains(",")) {
String[] ck = custkey.split(",");
for ( String k : ck) {
this.loadRefDb(k);
} else {
this.loadRefDb(custkey);
}
}
my class
package com.ge.digital.fleet.dataservice.impl.processor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.*;
import javax.naming.*;
import javax.sql.*;
import java.sql.*;
import com.ge.digital.fleet.dataservice.impl.db.RefDatabase;
public class RefReplicatedDataProcessor {
private static final Logger log = LoggerFactory.getLogger(RefReplicatedDataProcessor.class);
private RefDatabase refDb = null;
private DataSource dataSource;
private String custkey;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setCustkey(String custkey) {
this.custkey = custkey;
}
public void setRefDatabase(RefDatabase refDb) {
this.refDb = refDb;
}
//this is what doesn't work
if (custkey.contains(",")) {
String[] ck = custkey.split(",");
for ( String k : ck) {
this.loadRefDb(k);
} else {
this.loadRefDb(custkey);
}
}
public void loadRefDb(String custkey) throws SQLException {
log.info("Reference Replicated Data Processor :: start");
refDb.dropDb();
setAssociations(custkey);
refDb.replicationComplete();
log.info("Reference Replicated Data Processor :: Finish");
}
/***
* name: setAssociations(custkey)
* Loads/Builds the cache database with values found in mysql database
*
* returns a List of associations
* G1.DWATT,112-A-001_Gas_Turbine
* G1.ATID,112-A-001_Gas_Turbine
* G1.dvar, 112-A-001_Gas_Turbine
* ...
*/
public void setAssociations(String custkey) throws SQLException {
String reference = "";
String asset = "";
String dbname = "iprcmt1.fleet_associations"; //from old impl database - TODO new database impl
String query = "select reference, asset from " + dbname + " where custkey = ?";
try (Connection conn = dataSource.getConnection();
PreparedStatement stmt = conn.prepareStatement(query)) {
stmt.setString(1, custkey);
try (ResultSet rs = stmt.executeQuery()) {
if (! rs.next() ) {
log.info("SQL Warning ! No associations for key: " + custkey);
} else {
do {
reference = rs.getString(1);
asset = rs.getString(2);
log.info("SQL Associations reference: " + reference + " and asset: " + asset);
refDb.addRow(reference, asset);
} while (rs.next());
}
} catch (Exception ex) {
log.error("SQL Cannot Execute ResultSet Query!");
log.error(ex.getMessage());
}
} catch (Exception e) {
log.error("SQL Cannot Create DataSource Connection! Cannot Create Prepared Statement!");
log.error(e.getMessage());
}
}
}
maybe this ? :)
if (custkey.contains(",")) {
String[] ck = custkey.split(",");
for ( String k : ck) {
this.loadRefDb(k);
}
}else {
this.loadRefDb(custkey);
}
Your code is simply out of place. The code at "//this is what doesn't work" needs to be inside a method or constructor.
public RefReplicatedDataProcessor(){
//this is what didn't work
if (custkey.contains(",")) {
String[] ck = custkey.split(",");
for ( String k : ck) {
this.loadRefDb(k);
}
} else {
this.loadRefDb(custkey);
}
}
Perhaps you should run the split within a method
public void filter(){
if (custkey.contains(",")) {
String[] ck = custkey.split(",");
for ( String k : ck) {
this.loadRefDb(k);
} else {
this.loadRefDb(custkey);
}
}
}
I am building a collection program in Java that collects data from websites using their apis. I am encountering this problem where it will hang on an http call. I tried to work around it by executing an http call over an executor service with a timeout. That doesn't seem to work as it would keep timing out and retrying. I figured it might be something to do with the API so after a retry I would reinitialize a whole new object per website API. Still no solution. I am trying to identify the root cause of this but can't seem to put my finger on it.
Here is a look at my flickr manager class that handles the calls to flickr.
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.scribe.exceptions.OAuthConnectionException;
import com.flickr4java.flickr.Flickr;
import com.flickr4java.flickr.FlickrException;
import com.flickr4java.flickr.FlickrRuntimeException;
import com.flickr4java.flickr.REST;
import com.flickr4java.flickr.RequestContext;
import com.flickr4java.flickr.auth.Auth;
import com.flickr4java.flickr.auth.Permission;
import com.flickr4java.flickr.people.User;
import com.flickr4java.flickr.photos.Exif;
import com.flickr4java.flickr.photos.Extras;
import com.flickr4java.flickr.photos.Photo;
import com.flickr4java.flickr.photos.PhotoList;
import com.flickr4java.flickr.photos.SearchParameters;
import com.flickr4java.flickr.photos.Size;
import com.google.common.util.concurrent.RateLimiter;
public class FlickrManager {
private final static Logger LOG = Logger.getLogger(FlickrManager.class.getName());
private final static ExecutorService executorService = Executors.newSingleThreadExecutor();
private Flickr flickr;
private final int MAX_PER_PAGE = 500;
private final RateLimiter rateLimiter;
private String ApiKey;
private String ApiSecret;
private String authToken;
private String authTokenSecret;
private Integer hostPort;
private String hostAddress;
private String httpScheme;
public FlickrManager(Flickr flickr, double apiCallsPerSecond) throws FlickrException {
this.flickr = flickr;
flickr.getTestInterface().echo(Collections.emptyMap());
//get flickr info to reinitialize flickr object if necessary
this.ApiKey = flickr.getApiKey();
this.ApiSecret = flickr.getSharedSecret();
this.hostPort = flickr.getTransport().getPort();
this.hostAddress = flickr.getTransport().getHost();
this.httpScheme = flickr.getTransport().getScheme();
if(flickr.getAuth() != null){
this.authToken = flickr.getAuth().getToken();
this.authTokenSecret = flickr.getAuth().getTokenSecret();
}
this.rateLimiter = RateLimiter.create(apiCallsPerSecond);
}
private void initialize(){
this.flickr = null;
REST rest = new REST(this.hostAddress,this.hostPort);
rest.setScheme(this.httpScheme);
this.flickr = new Flickr(this.ApiKey, this.ApiSecret,rest);
if(this.authToken != null && this.authTokenSecret != null){
RequestContext requestContext = RequestContext.getRequestContext();
Auth auth = new Auth();
auth.setPermission(Permission.READ);
auth.setToken(this.authToken);
auth.setTokenSecret(this.authTokenSecret);
requestContext.setAuth(auth);
flickr.setAuth(auth);
}
}
public User getUserInfo(String flickrProfileId) throws FlickrException{
return doFlickrAction(new CallableFlickrTask<User>(){
#Override
public User execute() throws FlickrException {
return flickr.getPeopleInterface().getInfo(flickrProfileId);
}
});
}
public PhotoList<Photo> search(SearchParameters params, int page) throws FlickrException{
return doFlickrAction(new CallableFlickrTask<PhotoList<Photo>>(){
#Override
public PhotoList<Photo> execute() throws FlickrException {
return flickr.getPhotosInterface().search(params, MAX_PER_PAGE, page);
}
});
}
public PhotoList<Photo> getUserPhotos(String userNSID, int page) throws FlickrException{
return doFlickrAction(new CallableFlickrTask<PhotoList<Photo>>(){
#Override
public PhotoList<Photo> execute() throws FlickrException {
return flickr.getPeopleInterface().getPhotos(
userNSID,
null, null, null, null, null,
Flickr.CONTENTTYPE_PHOTO, null,
Extras.ALL_EXTRAS, 100, page);
}
});
}
//Catch the execption inside the function for failure to get exif
public Collection<Exif> getPhotoExif(Photo photo) throws FlickrException, FlickrRuntimeException {
return doFlickrAction(new CallableFlickrTask<Collection<Exif>>(){
#Override
public Collection<Exif> execute() throws FlickrException {
return flickr.getPhotosInterface().getExif(photo.getId(),photo.getSecret());
}
});
}
public Collection<Size> getAvailablePhotoSizes(Photo photo) throws FlickrException{
return doFlickrAction(new CallableFlickrTask<Collection<Size>>(){
#Override
public Collection<Size> execute() throws FlickrException {
return flickr.getPhotosInterface().getSizes(photo.getId());
}
});
}
private abstract class CallableFlickrTask<T> {
public abstract T execute() throws FlickrException, FlickrRuntimeException;
}
private <T> T doFlickrAction(CallableFlickrTask<T> callable) throws FlickrException {
while(true){
rateLimiter.acquire();
Future<T> future = executorService.submit(new Callable<T>() {
#Override
public T call() throws Exception {
return callable.execute();
}});
try {
return future.get(5, TimeUnit.MINUTES);
} catch (InterruptedException e) {
LOG.log(Level.INFO,"Interrupted exception: {0}",e.getMessage());
initialize(); //initialize if it's been interupted
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if( cause instanceof UnknownHostException ||
cause instanceof SocketException ||
cause instanceof OAuthConnectionException ){
//sleep and retry
LOG.log(Level.INFO,"Unknown Host or Socket exception. Retry: {0}",e.getMessage());
try {
Thread.sleep(10000);
initialize();
} catch (InterruptedException ex) {
LOG.log(Level.INFO, "Thread sleep was interrupted exception: {0}", ex.getMessage());
}
}
//if it's not of the above exceptions, then rethrow
else if (cause instanceof FlickrException) {
throw (FlickrException) cause;
}
else {
throw new IllegalStateException(e);
}
} catch (TimeoutException e) {
LOG.log(Level.INFO,"Timeout Exception: {0}",e.getMessage());
initialize(); //initialize again after timeout
}
}
}
}
I also used jvisualvm to get a look at what the collection is doing while it's hanging. The thread dump is here: Thread dump
I've recently starting working on a java webapp (JSP / Servlet) that was developed by the internal developer of a company.
This app randomly doesn't return data, and inspecting the log I found some NullPointerExceptions related to the classes' member variable which holds the database connection. Following the stack trace it seems that a second thread closes the connection after it ended its task leaving the first thread without a connection.
By the needs of the company the app uses different databases, one which rules appdata, and others which contain data the app has to retrieve. So every class attached to the main servlet may connect to one or more databases depending on the task it has to accomplish.
I'm not familiar with JavaEE but giving a look at the database connection class, I see nothing which protect threads from conflicting each other.
Which is the correct way to handle such connections?
This is the code of the Database handler:
package it.metmi.mmasgis.utils;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class DBManager
{
private String szDatabase;
private String szUsername;
private String szPassword;
private String szError;
private Connection db;
private boolean bConnected;
private Logger logger;
public DBManager(String szDBName)
{
this(szDBName, "", "");
}
public DBManager(String szDBName, String szName, String szPass)
{
szDatabase = szDBName;
szUsername = szName;
szPassword = szPass;
bConnected = false;
szError = "";
logger = LogManager.getFormatterLogger(DBManager.class.getName());
}
public boolean connect()
{
logger.entry();
try {
Class.forName("com.mysql.jdbc.Driver");
if(!szDatabase.isEmpty())
{
String szCon = "jdbc:mysql://localhost/" + szDatabase;
if(!szUsername.isEmpty())
{
szCon += "?user=" + szUsername;
if(!szPassword.isEmpty())
szCon += "&password=" + szPassword;
}
db = DriverManager.getConnection(szCon);
bConnected = true;
} else {
logger.error("No database name!!");
System.exit(0);
}
} catch(SQLException | ClassNotFoundException e) {
szError = e.getMessage();
e.printStackTrace();
logger.error("Can't connect: %s", e);
}
return logger.exit(bConnected);
}
public void disconnect()
{
logger.entry();
try {
db.close();
bConnected = false;
} catch(SQLException e) {
e.printStackTrace();
logger.error("Can't disconnect: %s", e);
}
logger.exit();
}
public boolean isConnected()
{
return bConnected;
}
public String getError()
{
return szError;
}
public ArrayList<HashMap<String,String>> query(String szQuery)
{
logger.entry(szQuery);
ArrayList<HashMap<String,String>> aResults = new ArrayList<HashMap<String,String>>();
int iCols = 0;
try {
Statement stmt = db.createStatement();
logger.info("Query: %s", szQuery);
ResultSet rs = stmt.executeQuery(szQuery);
ResultSetMetaData rsmd = rs.getMetaData();
iCols = rsmd.getColumnCount();
while(rs.next())
{
HashMap<String,String> pv = new HashMap<String,String>();
for(int i = 0; i < iCols; i++)
{
String szCol = rsmd.getColumnLabel(i + 1);
String szVal = rs.getString(i + 1);
pv.put(szCol, szVal);
}
aResults.add(pv);
}
rs.close();
stmt.close();
} catch(SQLException e) {
e.printStackTrace();
szError = e.getMessage();
logger.error("Error executing query: %s", e);
}
return logger.exit(aResults);
}
public boolean update(String szQuery)
{
logger.entry(szQuery);
boolean bResult = false;
try {
Statement stmt = db.createStatement();
logger.info("Query: %s", szQuery);
stmt.executeUpdate(szQuery);
bResult = true;
stmt.close();
} catch(SQLException e) {
e.printStackTrace();
szError = e.getMessage();
bResult = false;
logger.error("Error executing query: %s", e);
}
return logger.exit(bResult);
}
}
The class Task which all the servlet classes are based on, is a simple abstract class:
package it.metmi.mmasgis.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public abstract class Task
{
public abstract void doTask(HttpServletRequest request, HttpServletResponse response);
}
The class which throws NullPointerExceptions it this one, during the invocation of db.disconnect(). This class is called rapidly via AJAX 4 or 5 times from the interface written in JS.
package it.metmi.mmasgis.servlet.params;
import it.metmi.mmasgis.servlet.Task;
import it.metmi.mmasgis.utils.Const;
import it.metmi.mmasgis.utils.DBManager;
import it.metmi.mmasgis.utils.Query;
import it.metmi.mmasgis.utils.Utility;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ClassType extends Task
{
private DBManager db = null;
private Logger logger = LogManager.getFormatterLogger(ClassType.class.getName());
#Override
public void doTask(HttpServletRequest request, HttpServletResponse response)
{
logger.entry(request, response);
String szCensimento = Utility.getParameter(request, "censimento");
String szCategoria = Utility.getParameter(request, "category");
ArrayList<HashMap<String,String>> aClasses = new ArrayList<HashMap<String,String>>();
PrintWriter out = null;
logger.debug("Census: %s", szCensimento);
logger.debug("Category: %s", szCategoria);
db = new DBManager(szCensimento, Const.DB_USER, Const.DB_PASS);
if(db.connect())
{
String szQuery = String.format(Query.classes, szCategoria, szCategoria);
aClasses = db.query(szQuery);
db.disconnect();
}
try {
out = response.getWriter();
jsonEncode(aClasses, out);
} catch(IOException e) {
e.printStackTrace();
logger.error("Failed to encode JSON: %s", e);
}
logger.exit();
}
private void jsonEncode(ArrayList<HashMap<String,String>> aData, PrintWriter out)
{
HashMap<String,Object> result = new HashMap<String,Object>();
result.put("results", aData);
result.put("success", true);
Gson gson = new GsonBuilder().create();
gson.toJson(result, out);
}
}
If the webapp would use only one database, it could be rewritten as a Singleton, but in this way I have no idea on how to handle different connections for different databases.
How can avoid these exceptions?
The problem was that the connection object was declared as member.
Moving the variable inside the methods resolved.
I have created a RESTFUL webservice, witch returns a json, but at this time i only consult and show a simple select * , i need to create a complete CRUD solution, if anyone have some samples to share, i'll appreciate.
Best Regards to all
My code until now are:
DAO - Access.java
package dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import dto.Usuarios;
public class Access
{
public ArrayList<Usuarios> getUsuarios(Connection con) throws SQLException
{
ArrayList<Usuarios> usuariosList = new ArrayList<Usuarios>();
PreparedStatement stmt = con.prepareStatement("SELECT * FROM usuarios");
ResultSet rs = stmt.executeQuery();
try
{
while(rs.next())
{
Usuarios usuariosObj = new Usuarios();
usuariosObj.setUsr_id(rs.getInt("usr_id"));
usuariosObj.setUsr_login(rs.getString("usr_login"));
usuariosObj.setUsr_pwd(rs.getString("usr_pwd"));
usuariosList.add(usuariosObj);
}
} catch (SQLException e)
{
e.printStackTrace();
}
return usuariosList;
}
}
DTO - Usuarios.java
package dto;
public class Usuarios
{
private int usr_id;
private String usr_login;
private String usr_pwd;
public Usuarios()
{
}
public Usuarios(int usr_id, String usr_login, String usr_pwd)
{
super();
this.usr_id = usr_id;
this.usr_login = usr_login;
this.usr_pwd = usr_pwd;
}
public int getUsr_id()
{
return usr_id;
}
public void setUsr_id(int usr_id)
{
this.usr_id = usr_id;
}
public String getUsr_login()
{
return usr_login;
}
public void setUsr_login(String usr_login)
{
this.usr_login = usr_login;
}
public String getUsr_pwd()
{
return usr_pwd;
}
public void setUsr_pwd(String usr_pwd)
{
this.usr_pwd = usr_pwd;
}
#Override
public String toString()
{
return "[ {usr_id=" + usr_id + ", usr_login=" + usr_login + ", usr_pwd=" + usr_pwd + "} ]";
}
}
Model - AccessManager.java
package model;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import dao.Access;
import dao.Database;
import dto.Usuarios;
public class AccessManager
{
public ArrayList<Usuarios> getUsuarios() throws Exception
{
ArrayList<Usuarios> usuariosList = new ArrayList<Usuarios>();
Database db = new Database();
Connection con = db.getConnection();
Access access = new Access();
usuariosList = access.getUsuarios(con);
return usuariosList;
}
}
WebService - UsuariosService.java
package webService;
import java.util.ArrayList;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import com.google.gson.Gson;
import model.AccessManager;
import dto.Usuarios;
#Path("/UsuariosService")
public class UsuariosService
{
#GET
#Path("/usuarios")
#Produces("application/json")
public String usuarios()
{
String usuarios = null;
ArrayList<Usuarios> usuariosList = new ArrayList<Usuarios>();
try
{
usuariosList = new AccessManager().getUsuarios();
Gson gson = new Gson();
//usuarios = gson.toJson(usuariosList);
usuarios = "{\"usuarios\" :" + gson.toJson(usuariosList) + "}";
} catch (Exception e)
{
e.printStackTrace();
}
return usuarios;
}
}
Usually you should ask a specific trouble you have instead of ask for samples. It looks like you have a structured code and all you need is implement all operations exposing as a service.
In case you need a sample, there quite a lot of resources on the web. Something like this: https://code.google.com/p/javaee6-crud-example/
I'll try give you some quick tips below:
WebService - UsuariosService.java
#POST
#Path("/usuarios")
public Response save(Usuario user) {
try {
manager= new AccessManager();
manager.save(user);
return Response.ok("User has been created.").build();
} catch (Exception e) {
e.printStackTrace();
}
return usuarios;
}
#DELETE
#Path("/usuarios/{id}")
public Response delete(#PathParam("id") String id) {
try {
manager= new AccessManager();
manager.delete(id);
return Response.ok("User has been deleted.").build();
} catch (Exception e) {
e.printStackTrace();
}
return usuarios;
}
#PUT
#Path("/usuarios/{id}")
public Response delete(#PathParam("id") String id, Usuario user) {
try {
manager= new AccessManager();
manager.update(id, user);
return Response.ok("User has been updated.").build();
} catch (Exception e) {
e.printStackTrace();
}
return usuarios;
}
If you donĀ“t understand the usage of PUT, DELETE, POST and so on, I recommend you to read HTTP Method Tutorial. There is several discussion regarding this but you might skip it for a while.
I think you might get an idea from here. Your DAO needs to implement methods to perform CRUD interface as well. The link I've added has a very simple sample that might help as well. You might also check this JPA link.
Not sure whether info above helped but I think it is a start since you have to code it in order to understand more about it :)