0

I am working on sorting feature for a data table. I have JSF Web Controller:

@Named
@ViewScoped
public class SearchPlayerController implements Serializable {

    private List<Player> playerList;

    @EJB
    PlayerFacade playerFacade;

    @PostConstruct
    public void init() {
        if (playerList == null) {
            playerList = playerFacade.findAll();
        }
    }

    // getters and setters
    *
    *
    *
}

In this Controller I have a sorting method:

public String sortDataByClubName(final String dir) {
    Collections.sort(playerList, (Player a, Player b) -> {
        if(a.getClubId().getClubName()
            .equals(b.getClubId().getClubName())) {
            return 0;
        } else if(a.getClubId().getClubName() == null) {
            return -1;
        } else if(b.getClubId().getClubName() == null) {
            return 1;
        } else {
            if(dir.equals("asc")) {
                return a.getClubId().getClubName()
                    .compareTo(b.getClubId().getClubName());
            } else {
                return b.getClubId().getClubName()
                    .compareTo(a.getClubId().getClubName());
            }
        }
    });
    return null;
}

After invoking the sort on page view, it throws NullPointerException. I think the main reason is that inside the Comparator it can't read the value of clubName that should be accessible after getting Club object. Is there any possibility to compare values of nested properties?

Stewart
  • 17,616
  • 8
  • 52
  • 80
veritimus
  • 57
  • 1
  • 8
  • This is in no way jsf related. Try in a plain java class with just a main method. And mentioning where the NOW occurs its the least you could do – Kukeltje Feb 10 '18 at 22:35

1 Answers1

0

You seem to be sorting only on Player.getClubId().getClubName(). It seems like both getClubId() and getClubName() should be checked for null. This is how I would do it:

public class PlayerComparator implements Comparator<Player> {
    private String dir; // Populate with constructor
    public int compare(Player a, Player b) {
        int result = nullCheck(a.getClubId(), b.getClubId());
        if(result != 0) {
            return result;
        }
        String aname = a.getClubId().getClubName();
        String bname = b.getClubId().getClubName();
        result = nullCheck(aname, bname);
        if(result != 0) {
            return result;
        }
        result = aname.compareTo(bname);
        if("asc".equals(dir)) {   // No NPE thrown if `dir` is null
            result = -1 * result;
        }
        return result;
    }

    private int nullCheck(Object a, Object b) {
        if(a == null) { return -1; }
        if(b == null) { return 1; }
        return 0;
    }
}
Stewart
  • 17,616
  • 8
  • 52
  • 80
  • 1
    Och, yes, you’re right! I have completely forgotten that player.getClubId() can also return null! Thank you very much, sir! – veritimus Feb 10 '18 at 23:02