views:

305

answers:

5

Hello everybody.

I am writing a website using JSP, JSTL, Servlets and JavaBeans.

At one point of my code, I am trying to use an ArrayList of objects, and a strange thing is happening: when I add the first object it is fine, and when I add a second object it adds it in the second place, but the object at index(0) gets the same values as the object at index(1).

Maybe a problem is in the

ArrayList<Article> articleList = new ArrayList<Article>();
Article newArticle = new Article();

Since articleList is ArrayList of Article class.

Can somebody point me to what I am doing wrong?

Below is my code:

public ArrayList<Article> getArticles()
{
    baseIO mySql = new baseIO();
    ArrayList<Article> articleList = new ArrayList<Article>();
    int articleId = 0;

    try
    {
        String sql =
            "select * from jsp_blog_article order by article_id Desc Limit 3";
        con = (Connection)mySql.getConnection();
        pstmt = (PreparedStatement) con.prepareStatement(sql);
        ResultSet rs = pstmt.executeQuery();
        while (rs.next()) {
            Article newArticle = new Article();
            newArticle.setArticleAuthor(rs.getString("article_name"));
            newArticle.setArticleBody(rs.getString("article_body"));
            newArticle.setArticleAuthor(rs.getString("article_author"));
            newArticle.setArticleDate(rs.getString("article_date"));
            articleId = Integer.parseInt(rs.getString("article_id"));
            newArticle.setArticleId(String.valueOf(articleId));
            newArticle.setArticleComments(this.getCommentsNum(articleId));
            articleList.add(newArticle);
        }
        con.close();
        pstmt.close();
    }
    catch(Exception e)
    {
        return null;
    }

    return articleList;
}

And the Article class

package objects;

import java.io.Serializable;

public class Article implements Serializable{
    private String articleName;
    private String articleBody;
    private String articleAuthor;
    private String articleComments;
    private String articleDate;
    private String articleId;

    public Article()
    {

    }

    // all the getters and setters in place, but it is too long
    // so i am not going to post them in forum

}
+1  A: 

You are calling newArticle.setArticleAuthor twice...I know that's not part of your list problem, but that is an observation.

Aaron
That one i fixed. Thanks for pointing out
Dmitris
+1  A: 

I would try it this way and see what this does.

int x = 0;
while (rs.next()) {
    articleList.add(new Article());
    articleList.get(x).setArticleName(rs.getString("article_name"));
    articleList.get(x).setArticleBody(rs.getString("article_body"));
    articleList.get(x).setArticleAuthor(rs.getString("article_author"));
    articleList.get(x).setArticleDate(rs.getString("article_date"));
    articleList.get(x).setArticleId(rs.getString("article_id"));
    articleList.get(x).setArticleComments(this.getCommentsNum(articleId));
    x++;
}
Soldier.moth
It is worked!!!But i don't get why. I would really appreciate if you can explain why.
Dmitris
When you do it this way you are working on a distinct Article object each time whereas the way you were doing it you were referring to the same object so when you changed it the second time you were also changing the first one.
Soldier.moth
Uh, no. This way should be identical to the first way, except for the added overhead of retrieving the article from the list on every setXXX method.
Michael Myers
that was my first thought too, i thought that might be the reason just because he said that it worked. Thanks for the clarification, thanks for the indenting fix too.
Soldier.moth
Thanks a lot of explanation. I understand now why, but must admit would never figure it out on my own.
Dmitris
so what did it turn out to be? your first one should have worked...
John Gardner
It was just as Soldier.moth said. I guess when i was fist setting class Article and then adding it to the ArrayList<Article> it was overriding the previous data as they all was referenced to each other. But when i was adding class first to the array list then the reference would go to the specific index(x).At list that's how I understood his explanation.
Dmitris
I would be curious, if you changed it back, whether it would work now.
Bert F
This explanation makes no sense. There are several sloppy aspects of the code - but not something that would cause the behavior described. Retrieving the object from the list over and over again is an interesting test, but isn't a real solution.
Kevin Day
I don't know, but when i spotted the problem I started to debug and it showed that when i put Article object into list first time it goes well, but as soon as I start read new Article object for the next add to the list, it would change the properties of the object that already in the list.
Dmitris
Sorry, but this cannot be the answer - Java passes by value, so when newArticle is passed to the list's add method it is the reference value (pointer) to article that is passed, not reference itself.The only way the described behaviour could be happening is if newArticle was being assigned outside the result set loop.
Nick Holt
A: 

Code looks fine, how are you displaying the list that makes you think the same value is at both indexes? Perhaps your problem is with that code.

objects
I debugged it and saw with my own eyes how it changes in run time.
Dmitris
A: 

Are you adding articles to the database concurrently while reading them? I think that it is possible, depending on your storage engine, that you'd have problems reading while updating is going on.

Adam Goode
I am using mysql. No i am not updating while reading it.I just read it and display
Dmitris
+1  A: 

The code should be cleaned up per the other comments, but functionally, it should work.

Here's what I think is happening.

Your code has the following two lines in it:

newArticle.setArticleAuthor(rs.getString("article_name"));
newArticle.setArticleAuthor(rs.getString("article_author"));

and there is no corresponding call to:

newArticle.setArticleName(rs.getString("article_name"));

this means that your object has no article name specified (even though the author is specified). I'll bet that you are then doing some sort of processing before you display the list that somehow merges articles with the same name.

As a general approach to debugging, I recommend that you mock up your code so you can run it in a debugger and see what's actually going on (right now, your system has so many moving parts that it's going to be difficult for you to hone in on the actual problem).

In the current case, this would be as simple as running the one method outside of your web container, and using a debugger to take a look at the objects in the list that gets returned. You will find that the objects in the list are, indeed, separate objects - just having the same articleName property.

Kevin Day
The setArticleName I already fixed almost immediately after i posted code here.The application is a blog website and i was just trying to read data from database and then display it with jstl foreach on the main page.
Dmitris
And if you do a stop point in the debugger, what do the records in the list look like? soldier.moth's solution should not be any different than yours (other than being less efficient and the code being bit unpretty). It's probably pretty important to really understand the issue you are experiencing.
Kevin Day