Funny -- there was comment about this choice in the IlliniCloud repo, and I'm not sure why it didn't make it to the pull request.  (I Added it.)

JPA persistence is implemented in the DAO, but responsibility for invoking it is shouldered by a listener.  Originally it was in the TenantService itself, but we discovered that it's handy to be able to stage the persistence wherever we want in the listener chain.  IlliniCloud -- and I bet most future serious adopters of multi-tenancy -- have at least one listener impl that's not included with the Apereo contribution.  They have an IAM system called Trident that includes an IDP Proxy responsible for knowing about tenants and communicating with their directories for AuthN and attributes.

Chaining of multiple, open-ended listeners also works hand-in-hand with the failOnError thing -- we can arrange these things in such a way that listener C can depend on behavior from listeners A & B, and we can cancel persistence if there's an error in an important, earlier stage.