fix #616 automatically implement equals()/hash