Keesun Baik 2015-02-12
Issue: enhanced view request performance
Problem: There was so many queries occured to handle the request.

Solution: Changed to reuse user collection on the view and prevented n+1 select by fetching.
@93cb0221539d176f3f391785ca5496958d5ddf61
app/models/ProjectUser.java
--- app/models/ProjectUser.java
+++ app/models/ProjectUser.java
@@ -20,9 +20,7 @@
  */
 package models;
 
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 import javax.persistence.Entity;
 import javax.persistence.Id;
@@ -93,7 +91,7 @@
     }
 
     public static List<ProjectUser> findMemberListByProject(Long projectId) {
-        return find.fetch("user", "loginId").fetch("role", "name").where()
+        return find.fetch("user").fetch("role", "name").where()
                 .eq("project.id", projectId).ne("role.id", RoleType.SITEMANAGER.roleType())
                 .orderBy("user.name ASC")
                 .findList();
app/models/User.java
--- app/models/User.java
+++ app/models/User.java
@@ -338,31 +338,36 @@
     }
 
     public static List<User> findUsersByProjectAndOrganization(Project project) {
-        Set<User> users = new HashSet<>();
-
         // member of this project.
+        Set<Long> userIds = new HashSet<>();
+
         List<ProjectUser> pus = project.members();
         for(ProjectUser pu : pus) {
-            users.add(pu.user);
+            userIds.add(pu.user.id);
         }
 
         // member of the group
         if(project.hasGroup()) {
-            List<OrganizationUser> ous = (project.isPublic() || project.isProtected()) ? project.organization.users : project.organization.getAdmins();
+            List<OrganizationUser> ous = null;
+            if(project.isPrivate()) {
+                ous = project.organization.getAdmins();
+            } else {
+                ous = OrganizationUser.find.fetch("user")
+                        .where().eq("organization", project.organization).findList();
+            }
+
             for(OrganizationUser ou : ous) {
-                users.add(ou.user);
+                userIds.add(ou.user.id);
             }
         }
 
-        // sorting
-        List<User> result = new ArrayList<>(users);
-        Collections.sort(result, USER_NAME_COMPARATOR);
-
         if (UserApp.currentUser().isSiteManager()) {
-            result.add(UserApp.currentUser());
+            userIds.add(UserApp.currentUser().id);
         }
 
-        return result;
+        List<User> users = find.where().in("id", userIds).orderBy().asc("name").findList();
+
+        return users;
     }
 
     @Transient
app/views/issue/partial_assignee.scala.html
--- app/views/issue/partial_assignee.scala.html
+++ app/views/issue/partial_assignee.scala.html
@@ -22,11 +22,11 @@
 
 @import utils.AccessControl._
 
-@makeOptionTagWithFlag(user:User, flag:String) = {
+@makeOptionTagWithFlag(user:User, users:List[User], flag:String) = {
     <option value="@user.id"
-            data-avatar-url="@User.findByLoginId(user.loginId).avatarUrl"
+            data-avatar-url="@user.avatarUrl"
             data-login-id="@user.loginId"
-            @if(!project.isAssignableUser(user)) { data-non-member="true" }
+            @if(!users.contains(user)) { data-non-member="true" }
             @flag>
         @user.name
     </option>
@@ -46,15 +46,18 @@
             }
         }
     }
-    @for(user <- project.getAssignableUsersAndAssignee(issue)){
-        @if(issue != null && issue.assignee != null && issue.assignee.user.loginId == user.loginId) {
-            @makeOptionTagWithFlag(user, "selected")
-        } else {
-            @makeOptionTagWithFlag(user,"")
+    @defining(project.getAssignableUsersAndAssignee(issue)) { users =>
+        @for(user <- users){
+            @if(issue != null && issue.assignee != null && issue.assignee.user.loginId == user.loginId) {
+                @makeOptionTagWithFlag(user, users, "selected")
+            } else {
+                @makeOptionTagWithFlag(user, users, "")
+            }
+        }
+
+        @if(issue != null && issue.assignee != null && issue.assignee.user.isSiteManager() && !UserApp.currentUser().isSiteManager()) {
+            @makeOptionTagWithFlag(issue.assignee.user, users, "selected")
         }
     }
 
-    @if(issue != null && issue.assignee != null && issue.assignee.user.isSiteManager() && !UserApp.currentUser().isSiteManager()) {
-        @makeOptionTagWithFlag(issue.assignee.user, "selected")
-    }
 </select>
Add a comment
List