Search code examples
hazelcasthazelcast-imap

Not able to retrieve element from Hazelcast's Map if using custom object as a key


I am using Hazelast Map and trying to store Objects against key which is object of my custom class i.e. HMapKey. Here is snippet of HMapKey class.

public class HMapKey implements Serializable{
    private String keyCode;
    private long time;

    public HMapKey(String keyCode, long time) {
      this.keyCode = keyCode;
      this.time = time;
    }
    public String getKeyCode() {
        return keyCode;
    }
    public void setKeyCode(String keyCode) {
        this.keyCode = keyCode;
    }
    public long getTime() {
        return time;
    }
    public void setTime(long time) {
        this.time = time;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((keyCode == null) ? 0 : keyCode.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        HMapKey other = (HMapKey) obj;
        if (keyCode == null) {
            if (other.keyCode != null)
                return false;
        } else if (!keyCode.equals(other.keyCode))
            return false;
        return true;
    }
}

As you can see in above code, I have used only keyCode in equals() method to compare two objects. So no matter what value is there for time variable. But when I use this object as key in Hazelcast's Map, and try to retrieve it, I think Hazelcast checking each and every variable of key class, because of this, even if I have same keyCode variable value and different time variable, Hazelcast returning me as NULL. Is there any configuration to tell Hazelcast not to go for all variable checking and use existing equals() method only?

Here is code how I am trying to retrieve data from map

HazelcastInstance instance = Hazelcast.newHazelcastInstance();
private static ConcurrentMap<HMapKey, String>   testMap = instance.getMap("TEST_MAP");
testMap.put(new HMapKey("code1",123), "This is Code 1");
System.out.println(testMap.get(new HMapKey("code1",0)));

Means, while insertion, I have created key object like new HMapKey("code1",123) but while retrieving it, I am creating new object as new HMapKey("code1",0) and this is returning me as null value. Whereas if I try with new HMapKey("code1",123) it's working fine.


Solution

  • You can achieve that by declaring variable time as transient. But note that it will lead to collisions and give random results. Your put operation would overwrite the previous value even though it's properties are different.

    HazelcastInstance instance = Hazelcast.newHazelcastInstance();
    IMap<HMapKey, String> testMap = instance.getMap("TEST_MAP");
    
    testMap.put(new HMapKey("code1",123), "This is Code 1");
    
    System.out.println("HMapKey with time=0: " + testMap.get(new HMapKey("code1",0)));
    System.out.println("HMapKey with time=123: " + testMap.get(new HMapKey("code1",123)));
    
    
    testMap.put(new HMapKey("code1",456), "This is Code 2");
    System.out.println("HMapKey with time=123: " + testMap.get(new HMapKey("code1",123)));
    

    Output would be:

    HMapKey with time=0: This is Code 1
    HMapKey with time=123: This is Code 1
    HMapKey with time=123: This is Code 2