Session variables weird behavior

N

Nino

Hello,

I have a double array that I store in the session variable: finalList[]
[]

String[][] finalList = new String[8][25];
.... do some work to pull information into double array ...
session.setAttribute("array.fl", finalList);

All good so far. I can call the array from anywhere in my program
without having the pull the information and sort it again. Now, I am
building a piece that allows a user to edit the information, but if
they don't like the changes they can go back to how it was. Thus I
decided to build a new array with a similar structure to hold the
information temporarily. Once the final "Save" button has been
clicked, it will store the temporary array information into the
finalList... like this:

String[][] editFinalList = new String[8][25];
if (session.getAttribute("array.efl") == null) {
editFinalList = (String[][]) session.getAttribute("array.fl");
session.setAttribute("array.efl", editFinalList);
} else {
editFinalList = (String[][]) session.getAttribute("array.efl");
}

Here's the problem... Any changes I make to editFinalList are
automatically stored in the session variable for finalList!! I wrote
the following code (on a completely different Servlet) to see what was
in all my session variables:

String finalList[][] = (String[][]) session.getAttribute("array.fl");
for (int x=0; (x < finalList[0].length) && (finalList[0][x] != null); x
++) {
out.println(""+finalList[0][x]+" ... etc ... ");
}

Once I add the information to the editFinalList array, nowhere do I
make a reference to finalList. However, it still updates it and when I
run the above code, it shows that changes were made to the finalList
array. How is this possible? Is there something I'm missing or don't
understand completely? Should I try another approach to editing data
and storing it temporarily?

I'm pulling my hair out here and appreciate any help. Thanks,
Nino Skilj
 
T

Tom Hawtin

Nino said:
Once I add the information to the editFinalList array, nowhere do I
make a reference to finalList. However, it still updates it and when I
run the above code, it shows that changes were made to the finalList
array. How is this possible? Is there something I'm missing or don't
understand completely? Should I try another approach to editing data
and storing it temporarily?

You're not making a copy of the object, so you just end up with two
references to the same instance.

Consider:

char[] a = 'x';
char[] b = a;
b[0] = 'y';
System.out.println(a[0]);

What would you expect? You only have one char array, so /a/ is mutated.

The thing to do here is to change the second line to:

char[] b = a.clone();

In your example, you would need to copy all the element arrays as well
as the main array.

Tom Hawtin
 
N

Nino

Nino said:
Once I add the information to the editFinalList array, nowhere do I
make a reference to finalList. However, it still updates it and when I
run the above code, it shows that changes were made to the finalList
array. How is this possible? Is there something I'm missing or don't
understand completely? Should I try another approach to editing data
and storing it temporarily?

You're not making a copy of the object, so you just end up with two
references to the same instance.

Consider:

char[] a = 'x';
char[] b = a;
b[0] = 'y';
System.out.println(a[0]);

What would you expect? You only have one char array, so /a/ is mutated.

The thing to do here is to change the second line to:

char[] b = a.clone();

In your example, you would need to copy all the element arrays as well
as the main array.

Tom Hawtin

In the process, I copied a session evaluation servlet someone had
written and noticed that the session variable to the array was just a
pointer to it. Much like you helped me realize (Tom... thank you!),
all I was doing was making a call to the same reference... I simply
copied all the data into a completely new array and stored that as the
new editFinalList variable.

One other question arises from all this... If I were to store a
session variable as a string like this:
String name = (String) session.getAttribute("name");

I could manipulate and use that string as much as I want, but the
session variable won't change. Why is it then, that when I make a
similar call to a string array like this:
String finalList[][] = (String[][]) session.getAttribute("array.fl");

.... it actually changes the data stored in the session? Once I make a
change to finalList in the code, it automatically changes the stored
session variable without me having to do a setAttribute call. However,
that doesn't happen with the "name" string. If I make changes to name,
I have to do a setAttribute again to "save" the information.

I think it's because the session variable just stores a reference to
the actual array, but where is that array stored? Isn't this
inconsistent, or is that how it's supposed to work?

Thanks again for your help Tom!

Nino
 
T

Tom Hawtin

Nino said:
I could manipulate and use that string as much as I want, but the
session variable won't change. Why is it then, that when I make a
similar call to a string array like this:
String finalList[][] = (String[][]) session.getAttribute("array.fl");

... it actually changes the data stored in the session? Once I make a
change to finalList in the code, it automatically changes the stored
session variable without me having to do a setAttribute call. However,
that doesn't happen with the "name" string. If I make changes to name,
I have to do a setAttribute again to "save" the information.

You can't actually change the String. Once you create a String you are
stuck with its value. So you cannot be doing the same thing to a String
that you are doing to an array.

If you mutate an object saved in the session, you should do a
setAttribute anyway (I think - I haven't done much Servlet stuff over
the last few years). Servlet containers vary implementation, so what
appears to work for you might not work on a different version. It might
sometimes work on a particular container, and sometimes not. The problem
is, the container might copy the data using serialisation, to persist a
session, reduce memory or transfer within a cluster. If you just use
getAttibute, it might not consider the value changed, and so not update.

Tom Hawtin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top