I'm currently migrating an JavaEE5 (WL 10.3.5) application to JavaEE 7 (WL 12.2.1) and I'm facing a strange issue.
The WebLogic 12c implemntation of method HttpSession.setAttribute(String, Object) does not replace the old object bound to the same string key by a new object if the objects are identical (identical according WL12c's implemntation).
After several tests, when you want to replace an object in session, WL12c compare hashCode if they are the same, it compare object whith equals(). If equals() return 'true' WL12c does NOT replace the object!
But there is no such information in the JavaEE 7 Api doc : setAttribute(String, Object)
Binds an object to this session, using the name specified. If an object of the same name is already bound to the session, the object is replaced.
No mention at all of " only if the object to replace is not identical according the hashCode and equals methods".
Example to test, suppose we have a class MyClass
import org.apache.commons.lang.builder.HashCodeBuilder;
class MyClass{
private Long id;
private String myProperty;
private static final int HASHCODE1 = -459751453;
private static final int HASHCODE2 = 981454267;
public MyClass(Long id, String myProperty) {
this.id = id;
this.myProperty = myProperty;
}
// Override equals based on the id only
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || this.getClass() != obj.getClass()) {
return false;
}
MyClass myClass = (MyClass) obj;
if (this.getId() != null) {
return this.getId().equals(myClass.getId());
}
return false;
}
// Override hashCode based only on id
@Override
public int hashCode() {
return new HashCodeBuilder(HASHCODE1, HASHCODE2).append(this.getId()).toHashCode();
}
/* Getters & Setters*/
}
And in a servlet we do
MyClass obj1 = new MyClass(1L, "prop1");
MyClass obj2 = new MyClass(1L, "prop2");
request.getSession().removeAttribute("key");
request.getSession().setAttribute("key", obj1);
request.getSession().setAttribute("key", obj2);
Two object with same id. In WL12c, the session will still contain obj1.
If I change the code (obj1.id = 2)
MyClass obj1 = new MyClass(1L, "prop1");
MyClass obj2 = new MyClass(2L, "prop2");
request.getSession().removeAttribute("key");
request.getSession().setAttribute("key", obj1);
request.getSession().setAttribute("key", obj2);
The session will contain obj2.
We didn't have this behaviour in WebLogic 10.3.5 which have the same doc. So, does WL12c not complying the Java EE 7 API ? If not why ?
Rem : by extension I think it's the same for the request and application attributes.
Edit 1: I tested this simple webapp (same war) in Tomcat 9 and in Wildfly 11. WebLogic 12.2.1 is the only one which don't replace the object in session.
Edit 2: I did not indicate it in my original post but I only found one topic about this problem and it was closed without any relevant answer: HttpSession setAttribute doesn't always insert new object