The UserModelListener.onBeforeAddAssociation fetches all the resource permissions of a given roleId into a list. This is generally a very bad idea for a production database because the number of resource permissions for any given role could easily be in the millions. We should use an ActionableDynamicQuery instead so that we don't have to generate such a large list. Moreover, we should fix the filtering logic to make use of the viewActionId column that we added in Liferay 7. And we may be able to move the whole method to a Callable so that it runs in the background, rather than stalling the addAssociation process.
Steps to Reproduce
- Start up Liferay and log in as the admin user.
- Run the attached groovy script, which will create a new role called "Test Role", add 100,000 documents with a permissions on "Test Role", and add 2,000,000 "dummy" resource permissions for Test Role.
- Attempt to assign yourself the Test Role.
Expected Result: The Test Role would be assigned within 20 seconds.
Actual Result: Liferay stalls for several minutes trying to add the Test Role. Eventually, and OutOfMemoryError occurs and a "Portlet is temporarily unavailable message" appears in the UI (unless your heap size is really big).