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

Query engine cannot handle enums with constants that have overridden methods #21800

Closed
silvaran opened this issue Jul 19, 2022 · 3 comments · May be fixed by #22281
Closed

Query engine cannot handle enums with constants that have overridden methods #21800

silvaran opened this issue Jul 19, 2022 · 3 comments · May be fixed by #22281
Labels
Milestone

Comments

@silvaran
Copy link

If I have an enum class such as the following:

public enum MyEnum {
  VAL0,
  VAL1 {
    @Override
    public boolean isTest() { return false; }
  },
  ;
  public boolean isTest() { return true; }
}

Hazelcast will fail if I query against an attribute of this enum on any cache entry that has a value of VAL1 (with the overridden method):

Unknown attribute type: MyEnum$2 for attribute: myAttribute: com.hazelcast.query.QueryException: Unknown attribute type: MyEnum$2 for attribute: myAttribute
com.hazelcast.query.impl.predicates.AbstractPredicate.convert(AbstractPredicate.java:148)
 	at com.hazelcast.query.impl.predicates.AbstractPredicate.convert(AbstractPredicate.java:132)
 	at com.hazelcast.query.impl.predicates.InPredicate.applyForSingleAttributeValue(InPredicate.java:100)

For an enum constant with an overridden method, the compiler creates an anonymous class that extends the enum's class and this anonymous class returns false for Class.isEnum().

com.hazelcast.query.impl.getters.ReflectionHelper.getAttributeType( Class klass ) makes use of isEnum. Maybe it should use Enum.isAssignableFrom( klass ).

@AyberkSorgun AyberkSorgun added this to the 5.2 Backlog milestone Jul 19, 2022
@AyberkSorgun AyberkSorgun added Team: Core Source: Community PR or issue was opened by a community user labels Jul 19, 2022
@AyberkSorgun AyberkSorgun modified the milestones: 5.2 Backlog, 5.3 Backlog Oct 27, 2022
@AyberkSorgun AyberkSorgun modified the milestones: 5.3 Backlog, 5.3.0 Nov 8, 2022
@AyberkSorgun AyberkSorgun modified the milestones: 5.3.0, 5.4.0 May 15, 2023
@orcunc
Copy link
Contributor

orcunc commented Aug 16, 2023

You need to use SqlPredicate. Here is an example
Assume that you have these objects

public enum MyState {
  STATE1 {
    @Override
    public boolean isTest() { return false; }
  },
  STATE2 {
    @Override
    public boolean isTest() { return true; }
  };

  public abstract boolean isTest();
}

public static class MyEmployee implements Serializable {
   MyState state;

   public MyEmployee(MyState state) {
     this.state = state;
   }

   @Override
   public boolean equals(Object o) {
     if (this == o) return true;
     if (o == null || getClass() != o.getClass()) return false;
     MyEmployee that = (MyEmployee) o;
     return state == that.state;
   }

   @Override
   public int hashCode() {
     return Objects.hash(state);
   }
}

Then execute the SQL predicate

HazelcastInstance instance = ...;
IMap<Integer, MyEmployee> map = instance.getMap("map");

MyEmployee employee1 = new MyEmployee(State.STATE1);
map.put(1, employee1);


MyEmployee employee2 = new MyEmployee(State.STATE2);
map.put(2, employee2);


Collection<MyEmployee> values = map.values(Predicates.sql("state.test = true"));
assertThat(values).containsExactly(employee2);

You will see that you can query by Enum's value

@orcunc orcunc closed this as completed Aug 17, 2023
@mwashburn
Copy link

Why did you close this? Can we just fix it rather than having to write our own custom predicates. Just merge the pull request.

@vbekiaris
Copy link
Contributor

@mwashburn are you able to reproduce the issue with latest stable Hazelcast 5.3.2? If so, can you share your reproducer?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants