title: How to create own Custom Predicate to compare composite id in hazelcast
body: <p>I want to create my own custome predicate to compare composite id's inside object. The need is to because i have to write specific date comparison logic on object inside object (composite id).  <em>I don't want to compare individual attributes.i want to use composite id because it comes from invoker</em> and I can't get result using Predicate.in and Predicate.equals</p>
  
  <p>My Object structure is like below</p>
  
  <pre><code>Birth{id=BirthId{name='b3', dob=Wed Jan 01 10:53:20 IST 1902}, name='b3', dob=Wed Jan 01 10:53:20 IST 1902, description='MNP'}
  </code></pre>
  
  <p>and inside IMap it is stored like below</p>
  
  <pre><code>key   : BirthId{name='b3', dob=Wed Jan 01 10:53:20 IST 1902}
  
  value : Birth{id=BirthId{name='b3', dob=Wed Jan 01 10:53:20 IST 1902}, name='b3', dob=Wed Jan 01 10:53:20 IST 1902, description='MNP'}
  </code></pre>
  
  <p>My Java Classes(Birth and Birthid) Structure is below</p>
  
  <pre><code>    public class Birth implements Serializable, Portable {
  
          private static final long serialVersionUID = 1L;
  
          private BirthId id;
          private String name;
          private Date dob;
          private String description;
  
          public BirthId getId() {
              return id;
          }
  
          public void setId(BirthId id) {
              this.id = id;
          }
  
          public String getDescription() {
              return description;
          }
  
          public void setDescription(String description) {
              this.description = description;
          }
  
          public String getName() {
              return name;
          }
  
          public void setName(String name) {
              this.name = name;
          }
  
          public Date getDob() {
              return dob;
          }
  
          public void setDob(Date dob) {
              this.dob = dob;
          }
  
          public int hashCode() {
              return (new HashCodeBuilder()).append(this.id).append(this.name).append(this.dob).toHashCode();
          }
  
          public boolean equals(Object other) {
              if (other == this) {
                  return true;
              } else if (!(other instanceof Birth)) {
                  return false;
              } else {
                  Birth rhs = (Birth) other;
                  return (new EqualsBuilder()).append(this.id, rhs.id).append(this.name, rhs.name).append(this.dob, rhs.dob).isEquals();
              }
          }
  
          @Override public String toString() {
              return "Birth{" + "id=" + id + ", name='" + name + '\'' + ", dob=" + dob + ", description='" + description + '\'' + '}';
          }
  
          public int getFactoryId() {
              return 1;
          }
  
          public int getClassId() {
              return 1;
          }
  
          public void writePortable(PortableWriter portableWriter) throws IOException {
              portableWriter.writePortable("idComposite", getId());
              portableWriter.writeUTF("id", getId().toString());
              portableWriter.writeUTF("name", getName());
              portableWriter.writeUTF("description", getDescription());
              Date date = getDob();
              portableWriter.writeLong("dob", ((date == null) ? -1 : date.getTime()));
          }
  
          public void readPortable(PortableReader portableReader) throws IOException {
              setId((BirthId) portableReader.readPortable("idComposite"));
              setName(portableReader.readUTF("name"));
              setDescription(portableReader.readUTF("description"));
              long date = portableReader.readLong("dob");
              setDob(((date == -1) ? null : new Date(date)));
          }
  
      }
  
  public class BirthId implements Comparable&lt;BirthId&gt;, Serializable, Portable {
  
      private static final long serialVersionUID = 1L;
  
      private String name;
      private Date dob;
  
      public String getName() {
          return name;
      }
  
      public void setName(String name) {
          this.name = name;
      }
  
      public Date getDob() {
          return dob;
      }
  
      public void setDob(Date dob) {
          this.dob = dob;
      }
  
      public int hashCode() {
          return (new HashCodeBuilder()).append(this.name).append(this.dob).toHashCode();
      }
  
      public boolean equals(Object other) {
          if (other == this) {
              return true;
          } else if (!(other instanceof BirthId)) {
              return false;
          } else {
              BirthId rhs = (BirthId) other;
              return (new EqualsBuilder()).append(this.name, rhs.name).append(this.dob, rhs.dob).isEquals();
          }
      }
  
      public int compareTo(BirthId rhs) {
          return this == rhs ? 0 : (null == rhs ? -1 : (new CompareToBuilder()).append(this.name, rhs.name).append(this.dob, rhs.dob).toComparison());
      }
  
      @Override public String toString() {
          return "BirthId{" + "name='" + name + '\'' + ", dob=" + dob + '}';
      }
  
      public int getFactoryId() {
          return 1;
      }
  
      public int getClassId() {
          return 2;
      }
  
      public void writePortable(PortableWriter portableWriter) throws IOException {
          portableWriter.writeUTF("name", getName());
          Date date = getDob();
          portableWriter.writeLong("dob", ((date == null) ? -1 : date.getTime()));
      }
  
      public void readPortable(PortableReader portableReader) throws IOException {
          setName(portableReader.readUTF("name"));
          long date = portableReader.readLong("dob");
          setDob(((date == -1) ? null : new Date(date)));
      }
  
      public static ClassDefinition getClassDefinition(int portableVersion) {
          ClassDefinitionBuilder result = new ClassDefinitionBuilder(1, 2, portableVersion);
          result.addUTFField("name");
          result.addLongField("dob");
          return result.build();
      }
  
  }
  </code></pre>
  
  <p>I have created own custom Predicate to compare dates like below</p>
  
  <pre><code>public class DatePredicate extends AbstractPredicate&lt;Comparable, BirthId&gt; {
  
      Comparable[] values;
      private volatile Set&lt;Comparable&gt; convertedInValues;
  
      public DatePredicate() {
      }
  
      public DatePredicate(String attribute, Comparable... values) {
          if (values == null) {
              throw new NullPointerException("Array can't be null");
          } else {
              this.values = values;
          }
      }
  
      protected boolean applyForSingleAttributeValue(Map.Entry entry, Comparable attributeValue) {
  
          //My own date comparison logic
          return true;
      }
  
      public int getId() {
          return 99;
      }
  }
  </code></pre>
  
  <p>Caller code is</p>
  
  <pre><code>Predicate p = new DatePredicate("id", new BirthId("12345",passSpecifiedDate()));
  Result res = imap.values(p);
  </code></pre>
  
  <p>I am getting below error </p>
  
  <pre><code>Exception in thread "main" com.hazelcast.nio.serialization.HazelcastSerializationException: com.hazelcast.internal.serialization.impl.ArrayDataSerializableFactory@5f007be3 is not be able to create an instance for id: 99 on factoryId: -32
  </code></pre>
  
  <p>I do not know the best way to create own custom predicate and hazelcast doc does not specify the also.</p>
  
  <p>Could any please guide me how to do this?</p>