Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Predicate returns wrong data #9798

Closed
carlo-activia opened this issue Feb 3, 2017 · 3 comments

Comments

Projects
None yet
3 participants
@carlo-activia
Copy link

commented Feb 3, 2017

When using EntryProcessor and index on a field the EntryProcessor uses I get wrong data when executing a Predicate. Here is the code:

@test
public void issue() throws Exception {
Config config = new Config();
MapConfig testMapConfig = config.getMapConfig("testMap");
testMapConfig.setInMemoryFormat(InMemoryFormat.OBJECT);
testMapConfig.getMapIndexConfigs().add(new MapIndexConfig("lastValue", true));
HazelcastInstance instance = Hazelcast.newHazelcastInstance(config);

try {
  IMap<Object, Object> testMap = instance.getMap("testMap");

  testMap.set(1L, new MyData(10));

  testMap.executeOnKey(1L, new MyProcessor(15));

  Predicate betweenPredicate = Predicates.between("lastValue", 0, 11);
  Collection<Object> values = testMap.values(betweenPredicate);
  Assert.assertEquals(0, values.size());
} finally {
  instance.shutdown();
}

}

Here is the EntryProcessor:

static class MyProcessor extends AbstractEntryProcessor<Long, MyData> {
private long newValue;

public MyProcessor(long newValue) {
  this.newValue = newValue;
}

@Override
public Object process(Map.Entry<Long, MyData> entry) {
  MyData data = entry.getValue();
  data.setLastValue(newValue);
  entry.setValue(data);
  return null;
}

}

I expect the assertion to work, but it fails I get 1 record. If I change OBJECT to BINARY or if I comment the line "testMapConfig.getMapIndexConfigs().add(new MapIndexConfig("lastValue", true));" then it works.

Any ideas? I am using Hazelcast 3.7.5.

Thanks in advance.

@jerrinot jerrinot added this to the 3.8 milestone Feb 3, 2017

@tombujok tombujok self-assigned this Feb 3, 2017

@tombujok

This comment has been minimized.

Copy link
Contributor

commented Feb 3, 2017

Thx for reporting this.
Everything will work if you change your EntryProcessor to create a new entry with the new value.

static class MyProcessor extends AbstractEntryProcessor<Long, MyData> {
        private long newValue;

        public MyProcessor(long newValue) {
            this.newValue = newValue;
        }

        @Override
        public Object process(Map.Entry<Long, MyData> entry) {
            MyData newData = new MyData(newValue);
            entry.setValue(newData);
            return newValue;
        }
    }

In order to modify the index we need the old entry.getValue(). If you modify it the index won't find the old value in the Object since it has been modified.
With BINARY the object is deserialised so the oldValue is preserved.

With OBJECT and without indexing you don't experience it, since the old value is not required to update the index.

I need to investigate tomorrow if this is intended behaviour - but it looks like a bug or at least not well enough documented feature.

@carlo-activia

This comment has been minimized.

Copy link
Author

commented Feb 6, 2017

@tombujok :
Thanks for the clarification and the suggested code. I tried it and my test passes now :)
BTW, let me know whether it is a bug or an intended behavior.

@tombujok

This comment has been minimized.

Copy link
Contributor

commented Feb 8, 2017

It was a bug. Fixed via #9818

@tombujok tombujok closed this Feb 8, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.