Move that PlayerProfile up another level!
Prefetch profile information from the database.

Note that this implementation may open us to a denial-of-service attack by a banned user - AsyncPlayerPreLoginEvent is called before the ban lists are checked.

Look into the consequences of recieving an InterruptedException in the middle of loadPlayerProfile on the integrity of the database. If possible, we would prefer to interrupt the profile fetching task when the player stops logging in, to mitigate any possible denial-of-service attacks.
Use PlayerLoginEvent instead to alleviate ban concerns

Research indicates that there is still enough time from login to join for this to be a good idea.