Reference to session attrribute not getting null despite explicitly setting it to null

StackOverflow https://stackoverflow.com/questions/17800902

  •  03-06-2022
  •  | 
  •  

Pregunta

I have an object stored in session. In my controller, when a user sends a request, it concurrently executes the following code :

MyObject obj = (MyObject) req.getSession().getAttribute("myObject");
while(!obj.isNewResultAvailable()){
    //will loop until new result is available.
}

As I noted, it executes concurrently, so while the controll is still inside the loop, the user can do some other things, such as, when the user presses another button, a request will be sent to a controller that does the following :

MyObject obj = (MyObject) req.getSession().getAttribute("myObject");
obj = null;

My expectation is that, the code that loops until a new result is available will throw a NullPointerException. Only to find our that its not.

So, why is the object pulled from the session in another controller is not null despite setting that object to another controller as null?

Edit :

In my current code, I actually tried doing

req.getSession().setAttribute("myObject", null);

and

req.getSession().removeAttribute("myObject");

still, that did not solve my problem, the object in the while loop is still not nulled.

Realization

For those who will get to this kind of confusion, the root of my problem is I got confused how objects are passed in Java. My problem is as simple as, obj = null is just setting the reference of obj to null and NOT the object itself.

As pointed by morgano, the object in the session has been referenced locally by the thread that executes the while loop, so, req.getSession().setAttribute("myObject", null); and req.getSession().removeAttribute("myObject"); will not result to the object getting nulled. These are just basically removing the references of to the object from the session (thus ideally making it a candidate for gc, which will not happen in my situation since the object is referenced localy by a long running http request [the while loop thing]).

¿Fue útil?

Solución

Don't do that, do this:

req.getSession().setAttribute("myObject", null);

or much better:

req.getSession().removeAttribute("myObject");

what you are doing is set to null a reference to an object, you are not modifying the session attributes at all.

UPDATE AFTER QUESTION'S EDITION:

Once the "iterating" thread has a reference to your object, it is futile for the "deleting" thread to remove it from the session, your object has been referenced by a local variable in the first thread.

Otros consejos

Consider this example:

MyObject a = new MyObject();
MyObject b = a;
b = null;

What you seem to be expecting is:

MyObject a = new MyObject(); // a is the new object
MyObject b = a; // b is the same object
b = null; // set the object referenced by both a and b to null

What really happens:

MyObject a = new MyObject(); // a is the new object
MyObject b = a; // b points to the same object as a
b = null; // b doesn't point to anything

So in short: instead of setting the referenced value to null (i.e. the session in your example), you're actually setting the reference itself to null (i.e. obj in your example).

Do something like this. Session is a key value map. You have to set null explicitly against particular key value.

req.getSession().setAttribute("myObject", null);

or remove the key at all.

req.getSession().removeAttribute("myObject");
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top