Can someone please show me how to fix the code below so that it does not throw an error?
The following line of code is giving me a null pointer exception:
return dataSource.getConnection();
Note that dataSource is an instance of javax.sql.DataSource which is specified in web.xml, and which works fine when called by other code.
Here is the actual method in DataAccessObject.java where the null pointer is occurring:
protected static Connection getConnection(){
try {
return dataSource.getConnection(); //
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
The preceding method is being called by this line of code:
connection = getConnection();
Which is located in the following method in a class called CourseSummaryDAO as follows:
public List<CourseSummary> findAll(Long sid) {
LinkedList<CourseSummary> coursesummaries = new LinkedList<CourseSummary>();
ResultSet rs = null;
PreparedStatement statement = null;
Connection connection = null;
try {
connection = getConnection(); //
String sql = "select * from coursetotals where spid=?";
statement = connection.prepareStatement(sql);
statement.setLong(1, sid);
rs = statement.executeQuery();
//for every row, call read method to extract column
//values and place them in a coursesummary instance
while (rs.next()) {
CourseSummary coursesummary = read("findAll", rs);
coursesummaries.add(coursesummary);
}
return coursesummaries;
}catch (SQLException e) {
throw new RuntimeException(e);
}
finally {
close(rs, statement, connection);
}
}
To recreate this simply, I created the following TestCourseSummaries class:
public class TestCourseSummaries {
public static void main(String[] args) {
Long id = new Long(1002);
CourseSummaryDAO myCSDAO = new CourseSummaryDAO();
List<CourseSummary> coursesummaries = myCSDAO.findAll(id);
for(int i = 0;i<coursesummaries.size();i++){
System.out.println("type, numunits are: "+coursesummaries.get(i).getCourseType()+","+coursesummaries.get(i).getNumUnits());
}
}
}
EDIT:
To address JustDanyul's question, I am enclosing the code that calls in my application, and the underlying DataAccessObject code which is extended by the two DAO objects in the calling code:
Here is the code in my application which triggers the error. See there are two classes that each extended DataAccessObject. Perhaps they are conflicting with each other, causing the second one not to get the database connection?
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String idString = req.getParameter("id");
Long id = new Long(idString);
ThisObj thisobj = new ThisDAO().find(id);
req.setAttribute("thisobj", thisobj);
ThoseObjDAO myThoseDAO = new ThoseObjDAO();
List<ThoseObj> thoseobjects = myThoseObjDAO.findAll(id);
req.setAttribute("thoseobjects", thoseobjects);
jsp.forward(req, resp);
}
And here is the code for the DataAccessObject class which is extended by the two DAO classes in the calling code:
public class DataAccessObject {
private static DataSource dataSource;
private static Object idLock = new Object();
public static void setDataSource(DataSource dataSource) {
DataAccessObject.dataSource = dataSource;
}
protected static Connection getConnection() {
try {return dataSource.getConnection();}
catch (SQLException e) {throw new RuntimeException(e);}
}
protected static void close(Statement statement, Connection connection) {
close(null, statement, connection);
}
protected static void close(ResultSet rs, Statement statement, Connection connection) {
try {
if (rs != null) rs.close();
if (statement != null) statement.close();
if (connection != null) connection.close();
} catch (SQLException e) {throw new RuntimeException(e);}
}
protected static Long getUniqueId() {
ResultSet rs = null;
PreparedStatement statement = null;
Connection connection = null;
try {
connection = getConnection();
synchronized (idLock) {
statement = connection.prepareStatement("select next_value from sequence");
rs = statement.executeQuery();
rs.first();
long id = rs.getLong(1);
statement.close();
statement = connection.prepareStatement("update sequence set next_value = ?");
statement.setLong(1, id + 1);
statement.executeUpdate();
statement.close();
return new Long(id);
}
}
catch (SQLException e) {throw new RuntimeException(e);}
finally{close(rs, statement, connection);}
}
}
The data source is created in web.xml, as follows:
<resource-ref>
<description>dataSource</description>
<res-ref-name>datasource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
I suspect that the code where it "runs fine" in, is code actually running in an application server. The example you are posting, which just runs a static void main() method, wont get any resources which has been defined in web.xml.
I am guessing that you use JDNI to setup the initial datasource. And then using something like
#Resource(name="jdbc/mydb")
private DataSource dataSource;
to set up your connection. Right?
EDIT:
After seeing your code, it seems like your data source is newer initialised at all. Just putting a element into your web.xml will not do it alone. You will also need to actually configure the dataSource, you know, specify the driver, username, password, uri etc etc etc.
I'm guessing the find() method of the DAO that works, isn't actually using the dataSource. What you have shown so far, doesn't insigunate that your have a initialised dataSource at all.
Just to give you an idea, I liked a tutorial on how you would do this with Tomcat and JDNI. (Or even better, use spring-jdbc).
http://www.mkyong.com/tomcat/how-to-configure-mysql-datasource-in-tomcat-6/
Use dataSource as <javax.sql.DataSource> instance, rather than an instance of <javax.activation.DataSource>.
In short, you should replace the statement <import javax.activation.DataSource;> by this other <import javax.sql.DataSource;>.
Use dataSource as javax.sql.DataSource instance, rather than an instance of javax.activation.DataSource. In short, you should replace the statement:
import javax.activation.DataSource;
by this other:
import javax.sql.DataSource;
Related
i have been using this JDBC conection in all of my class that had to run query but i created a new class which i dont want the constructor with a parameter of the DConnection from JDBC Class(main Database Class).
but i keep on getting NullPointExceptions. Can anyway figur out what that problem may be.
Thanks.
public class UsersDao {
// associating the Database Connection objekt
private DConnector connector;
private final Connection myConn;
// Constructor
public UsersDao() throws CZeitExceptionHand,SQLException {
myConn = connector.getConnenction();
}
public boolean updateUsers(String mitarb, int mid) throws SQLException{
// PreparedStatement myStmt = null;
Statement stmt = myConn.createStatement();
try {
String myStmt = "SELECT Bly "
+ "" + mid + ";";
return stmt.execute(myStmt);
} finally {
close(stmt);
}
}
Example like this Method which is working but in different class
String[][] getAllTheWorkers(DConnector connector) throws CZeitExceptionHand {
try {
Connection connect = connector.getConnenction();
Statement stmt = connect.createStatement();
ResultSet result = stmt.executeQuery("SELECT ");
result.last();
int nt = result.getRow();
result.beforeFirst();
}
return results;
} catch (SQLException e) {
throw new CZeitExceptionHand("Error: " + e);
}
}
The object does not seem to be initialized.
Can you please post which method is not working and from where it is invoked ?
P.S : Unable to add a comment - that is why have answered !
I'm getting the following execption when executing sql statements
SQLServerException: The server failed to resume the transaction.
Desc:69d00000016.
I know that the following DAO implementation is not correct. I want to know what is the correct implementation for the following code and if the fact that my connFactory is declared as static can cause the above error.
private static DbConnectionFactory connFactory;
protected myDAO() {
myDAO.connFactory = DbConnectionFactoryHome.getHome().lookupFactory("facName");
}
public myReturn myAccessMethod(final int cod) throws BaseException {
Connection conn = null;
CallableStatement stmt = null;
ResultSet resSet = null;
myReturn ret= null;
try {
conn = myDAO.connFactory.getConnection();
stmt = conn.prepareCall("{call name (2)}");
stmt.setInt(1, cod);
resSet = stmt.executeQuery();
if (resSet.next()) {
ret = new myReturn(resSet.getInt("someValue"));
}
}
catch (SQLException sqle) {
throw new myException(sqle.getMessage(), (Throwable)sqle);
}
finally {
try {
if (resSet != null) {
resSet.close();
}
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
}
}
return ret;
}
Should I remove the static modifier from the connFactory or implement a singleton, so when the constructor is called again the factory is not recreated?
I would make your DBConnectionFactory a singleton. A good example of how to do this can be found here: Singleton DB Connectionfactory.
However, I am not sure that the your issue is with the db connection factory being static. It may actually be with the way you are extracting results with the result set. Make sure you process all your results. You should include a more complete stack trace. You may want to look into why you are getting: "The server failed to resume the transaction." There is an article about how what causes this error and how to fix it here: Failed to resume transaction
Try doing something like this:
CallableStatement stmt = connection.prepareCall("{call name (2)}");
stmt.setInt(1, cod);
stmt.execute();
ResultSet rs = (ResultSet)stmt.getObject(index);
//Loop results
while (rs.next()) {
ret = new myReturn(resSet.getInt("someValue")
}
I am implementing an abstract class for connection pools. The goal is inherit this class to manage a connection pool for each database used in the program and encapsulate the common queries. I have serveral doubts:
Is efficient to get a connection from the pool and close it after do the query or is better implement it in another level to keep open the connection? (method selecSimple). I did a test with 100000 queries:
Took 86440 milliseconds getting and closing a connection from the pool for each query.
And 81107 milliseconds getting only one connection from the pool and using it to do all the queries, so I think there is not such a big difference.
I pass the ResultSet data to another container to release the connection as soon as posible, even if I have to go over the data twice, one to put the data into the new container and another later when it will be used. Do you think, it is a good practice or should be better to implement the queries in another level?
public abstract class ConnectionPool implements IConnectionPool {
/** Connection Pool dataSource */
private DataSource datasource;
#Override
public Connection getConnection() throws SQLException {
return datasource.getConnection();
}
#Override
public void closeConnectionPool() {
datasource.close();
}
#Override
public void setConnectionPool (String url, String driver, String user, String pass) throws SQLException {
// Using tomcat connection pool but it could be other
PoolProperties pool = new PoolProperties();
pool.setUrl(url);
// Set pool configuration
...
datasource = new DataSource();
datasource.setPoolProperties(pool);
}
// QUERIES
#Override
public List<Map<String, Object>> selectSimple (String query, String [] params) throws SQLException {
PreparedStatement ps = null;
ResultSet rs = null;
Connection con = null;
List<Map<String, Object>> results = null;
// Set the preparedstatement
...
try {
con = getConnection();
ps = con.prepareStatement(selectString);
rs = ps.executeQuery(selectString);
results = resultSetToArrayList(rs);
rs.close();
ps.close();
con.close();
} catch (SQLException e) {
throw new SQLException ();
} finally {
if (rs != null) rs.close();
if (ps != null) ps.close();
if (con != null) ps.close();
}
return results;
}
/** Transforms ResultSet into a List of Maps */
private List<Map<String, Object>> resultSetToArrayList(ResultSet rs) throws SQLException {
...
return list;
}
So, When the app finishes, will be enough closing the datasource to release the resources?(closeConnectionPool method).
I would greatly appreciate any help. Thanks in advance.
In the following code, I execute a query on a SQLite JDBC connection via the executeRestitutionalQuery(String query) method:
public static ArrayList<Metadata> findMetadata(String name, String text, String after, String before, String repPath)
throws SQLException, ClassNotFoundException {
ArrayList<Metadata> data = new ArrayList<Metadata>();
boolean needADD = false;
String query = "SELECT * from " + TABLE_NAME_METADATA;
...
query += " ORDER BY timestamp DESC;";
ResultBundle bundle = executeRestitutionalQuery(query);
ResultSet result = bundle.getResultSet();
while(result.next()){
Metadata metadata = new Metadata(result.getLong("id"), result.getString("name"), Timestamp.valueOf(result.getString("timestamp")),
result.getInt("filesNo"), result.getLong("size"), result.getString("description"), -1);
data.add(metadata);
}
closeStatementAndResultSet(bundle.getStatement(), bundle.getResultSet());
return data;
}
private static ResultBundle executeRestitutionalQuery(String query) throws SQLException, ClassNotFoundException{
Connection connection = null;
Statement statement = null;
ResultSet result = null;
ResultBundle bundle = null;
try{
connection = getConnection();
statement = connection.createStatement();
statement.executeUpdate(query);
connection.commit();
result = statement.executeQuery(query);
bundle = new ResultBundle(statement, result);
}finally{
if(connection != null){
try{
connection.close();
}catch (Exception e){
/* ignored */
}
}
}
return bundle;
}
private static void closeStatementAndResultSet(Statement statement, ResultSet result){
if(result != null){
try{
result.close();
}catch (Exception e){
// ignored
}
}
if(statement != null){
try{
statement.close();
}catch (Exception e){
// ignored
}
}
}
The ResultBundle class is just used to summarize the resultset and the statement. It looks like this:
public class ResultBundle {
private final Statement statement;
private final ResultSet result;
public ResultBundle(Statement statement, ResultSet result){
this.result = result;
this.statement = statement;
}
public Statement getStatement(){
return statement;
}
public ResultSet getResultSet(){
return result;
}
}
The problem is, that every call to result.getLong(), result.getString() etc. returns null resp. 0. I can't understand why. The queries should all be okay, as the code was running fine before I had to do some refactoring. Could the problem arise from the ResultBundle-class? What am I not seeing here?
Statements and ResultSets are "live" objects, living only as long as their connection. The executeRestitutionalQuery returns a ResultBundle, whose result and statement members are implicitly closed on return when the connection is closed in the finally block.
try {
...
}finally{
if(connection != null){
try{
connection.close(); // <---- here's the problem
}catch (Exception e){
/* ignored */
}
}
}
By the time, the caller of executeRestitutionalQuery can lay its hand on the resource bundle, the connection has been closed, and the result set is "dead".
I would say this is a bad design.
A better one would keep the SQL objects in tight scope, map results into a collection or object and immediately close all those scarce resources. Not only will the data be available to clients, but you'll avoid nasty problems with connection and cursors exhausted. It'll scale better, too.
I wrote a singleton class for obtaining a database connection.
Now my question is this: assume that there are 100 users accessing the application. If one user closes the connection, for the other 99 users will the connection be closed or not?
This is my sample program which uses a singleton class for getting a database connection:
public class GetConnection {
private GetConnection() { }
public Connection getConnection() {
Context ctx = new InitialContext();
DataSource ds = ctx.lookup("jndifordbconc");
Connection con = ds.getConnection();
return con;
}
public static GetConnection getInstancetoGetConnection () {
// which gives GetConnection class instance to call getConnection() on this .
}
}
Please guide me.
As long as you don't return the same Connection instance on getConnection() call, then there's nothing to worry about. Every caller will then get its own instance. As far now you're creating a brand new connection on every getConnection() call and thus not returning some static or instance variable. So it's safe.
However, this approach is clumsy. It doesn't need to be a singleton. A helper/utility class is also perfectly fine. Or if you want a bit more abstraction, a connection manager returned by an abstract factory. I'd only change it to obtain the datasource just once during class initialization instead of everytime in getConnection(). It's the same instance everytime anyway. Keep it cheap. Here's a basic kickoff example:
public class Database {
private static DataSource dataSource;
static {
try {
dataSource = new InitialContext().lookup("jndifordbconc");
}
catch (NamingException e) {
throw new ExceptionInInitializerError("'jndifordbconc' not found in JNDI", e);
}
}
public static Connection getConnection() {
return dataSource.getConnection();
}
}
which is to be used as follows according the normal JDBC idiom.
public List<Entity> list() throws SQLException {
List<Entity> entities = new ArrayList<Entity>();
try (
Connection connection = Database.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT id, foo, bar FROM entity");
ResultSet resultSet = statement.executeQuery();
) {
while (resultSet.next()) {
Entity entity = new Entity();
entity.setId(resultSet.getLong("id"));
entity.setFoo(resultSet.getString("foo"));
entity.setBar(resultSet.getString("bar"));
entities.add(entity);
}
}
return entities;
}
See also:
Is it safe to use a static java.sql.Connection instance in a multithreaded system?
Below code is a working and tested Singleton Pattern for Java.
public class Database {
private static Database dbIsntance;
private static Connection con ;
private static Statement stmt;
private Database() {
// private constructor //
}
public static Database getInstance(){
if(dbIsntance==null){
dbIsntance= new Database();
}
return dbIsntance;
}
public Connection getConnection(){
if(con==null){
try {
String host = "jdbc:derby://localhost:1527/yourdatabasename";
String username = "yourusername";
String password = "yourpassword";
con = DriverManager.getConnection( host, username, password );
} catch (SQLException ex) {
Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
}
}
return con;
}
While getting Connection in any Class simply use below line
Connection con = Database.getInstance().getConnection();
Hope it may help :)
package es.sm2.conexion;
import java.sql.Connection;
import java.sql.DriverManager;
public class ConexionTest {
private static Connection conn = null;
static Connection getConnection() throws Exception {
if (conn == null) {
String url = "jdbc:mysql://localhost:3306/";
String dbName = "test";
String driver = "com.mysql.jdbc.Driver";
String userName = "userparatest";
String password = "userparatest";
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url + dbName, userName, password);
}
return conn;
}
}
To close Connection
public static void closeConnection(Connection conn) {
try {
conn.close();
} catch (SQLException e) {
}
}
To call to the connection:
package conexion.uno;
import java.sql.*;
import es.sm2.conexion.ConexionTest;
public class LLamadorConexion {
public void llamada() {
Connection conn = null;
PreparedStatement statement = null;
ResultSet resultado = null;
String query = "SELECT * FROM empleados";
try {
conn = ConexionTest.getConnection();
statement = conn.prepareStatement(query);
resultado = statement.executeQuery();
while (resultado.next()) {
System.out.println(resultado.getString(1) + "\t" + resultado.getString(2) + "\t" + resultado.getString(3) + "\t" );
}
}
catch (Exception e) {
System.err.println("El porque del cascar: " + e.getMessage());
}
finally {
ConexionTest.closeConnection(conn);
}
}
}
Great post, farhangdon! I, however, found it a little troublesome because once you close the connection, you have no other way to start a new one. A little trick will solve it though:
Replace if(con==null) with if(con==null || con.isClosed())
import java.sql.Connection;
import java.sql.DriverManager;
public class sql11 {
static Connection getConnection() throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/ics", "root", "077");
return c;
}
}