0

Well, sadly I do not even know how to describe this error lol :(

I want to display an image which I have stored it's path in the database. And my code works perfectly for the first time it accesses into the database. However, my code retrieves null for the second time it goes to the database and so on. I stared at my code for couple hours but couldnt find the bug lol :(

getimage.jsp

<form action="getimage" method="get">
    <input type="text">
    <input type="submit" name="getimage">
</form>

<c:forEach var="image" items="${image_path}">
    <img src="${image}"/>
</c:forEach>

servlet:

    HttpSession session = request.getSession();
    session.removeAttribute("image_path");
    List<String> list_image_path = new ArrayList<String>();

    ImagePath img = ImageDao.getInstance().getPath(8);
    list_image_path.add(img.getImagePath());

    session.setAttribute("image_path", list_image_path);

    System.out.println(img);

    request.getRequestDispatcher("getimage.jsp").forward(request, response);

ImageDao.java

private ImageDao() {
    try {
        conn = MyDatabase.getConnection();
    } catch (SQLException e) {
        System.out.println( e.getClass() + " - Can not connect to the databse");
        e.printStackTrace();
    }
}

public static ImageDao getInstance() {
    if(instance == null) {
        synchronized( UsersDao.class) {
            if( instance == null ){
                instance = new ImageDao();
            }
        }
    }
    return instance;
}
public static ImagePath getPath( long id) {
    ImagePath path = new ImagePath();
    String sql = "SELECT * FROM item_image WHERE id=?";

    try {
        System.out.println(id + ": " + conn);
        PreparedStatement pstmt = conn.prepareStatement( sql );

        pstmt.setLong(1, id);
        ResultSet rs = pstmt.executeQuery();             // Fail right here

        if( rs.next() ) {
            System.out.println( rs.getLong("id") + ": " + rs.getString("path") + " " + id);
            path.setId( rs.getLong( "id" ));
            path.setImagePath( rs.getString("path"));
        }

        pstmt.close();
        rs.close();
        conn.close();
        return path;
    } catch( SQLException e ) {
        System.out.println("Cant get it");
    } finally {
        if( conn != null ) { try { conn.close(); } catch( SQLException e) {}};
    }
    return path;
}

So this is the message display on the console which I embedded inside ImageDao.java : first access:

8: org.postgresql.jdbc4.Jdbc4Connection@3d3cdc3b
8: upload/download.jpg 8
Id: 8 path: upload/download.jpg

second access:

8: org.postgresql.jdbc4.Jdbc4Connection@3d3cdc3b
Cant get it
Id: 0 path: null
user3819470
  • 133
  • 2
  • 2
  • 10
  • 1
    isn't because you create the connection in the singleton creation, then after the query you close it and never create it again? – Leo Aug 06 '14 at 03:22
  • Do you know where I can learn more about concurrency and threadsafe technique? – user3819470 Aug 06 '14 at 03:34
  • There are good books about it (this one is kind of a reference - http://stackoverflow.com/questions/10202768/is-java-concurrency-in-practice-still-valid) , some of them are really cheap when you buy used. But specifically in this case, I suggest you to use a connection pool to get and reuse the database connections, and then your code will run just fine. – Leo Aug 06 '14 at 03:38
  • if you are using a singleton database connection dont close it after transaction. close it when the server is closed or terminated. you can you servletcontext to achieve that – Ker p pag Aug 06 '14 at 03:54

1 Answers1

1

You're creating the connection only once, in the singleton constructor, and closing it in the end of the first query.

Then, in the second query, the connection is closed and you can't perform your query.

Create the connection before the query instead.

Leo
  • 6,480
  • 4
  • 37
  • 52