better fetch for role mappings

This commit is contained in:
Bill Burke 2014-06-16 10:15:53 -04:00
parent b649dd39d9
commit f50177996d
6 changed files with 22 additions and 14 deletions

View file

@ -198,13 +198,14 @@ public abstract class ClientAdapter implements ClientModel {
@Override @Override
public Set<RoleModel> getScopeMappings() { public Set<RoleModel> getScopeMappings() {
TypedQuery<ScopeMappingEntity> query = em.createNamedQuery("clientScopeMappings", ScopeMappingEntity.class); TypedQuery<String> query = em.createNamedQuery("clientScopeMappingIds", String.class);
query.setParameter("client", getEntity()); query.setParameter("client", getEntity());
List<ScopeMappingEntity> entities = query.getResultList(); List<String> ids = query.getResultList();
Set<RoleModel> roles = new HashSet<RoleModel>(); Set<RoleModel> roles = new HashSet<RoleModel>();
for (ScopeMappingEntity entity : entities) { for (String roleId : ids) {
roles.add(new RoleAdapter(realm, em, entity.getRole())); RoleModel role = realm.getRoleById(roleId);
em.detach(entity); if (role == null) continue;
roles.add(role);
} }
return roles; return roles;
} }

View file

@ -2,6 +2,7 @@ package org.keycloak.models.jpa;
import org.keycloak.models.ApplicationModel; import org.keycloak.models.ApplicationModel;
import org.keycloak.models.AuthenticationLinkModel; import org.keycloak.models.AuthenticationLinkModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel; import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
@ -302,13 +303,16 @@ public class UserAdapter implements UserModel {
@Override @Override
public Set<RoleModel> getRoleMappings() { public Set<RoleModel> getRoleMappings() {
TypedQuery<UserRoleMappingEntity> query = em.createNamedQuery("userRoleMappings", UserRoleMappingEntity.class); // we query ids only as the role might be cached and following the @ManyToOne will result in a load
// even if we're getting just the id.
TypedQuery<String> query = em.createNamedQuery("userRoleMappingIds", String.class);
query.setParameter("user", getUser()); query.setParameter("user", getUser());
List<UserRoleMappingEntity> entities = query.getResultList(); List<String> ids = query.getResultList();
Set<RoleModel> roles = new HashSet<RoleModel>(); Set<RoleModel> roles = new HashSet<RoleModel>();
for (UserRoleMappingEntity entity : entities) { for (String roleId : ids) {
roles.add(realm.getRoleById(entity.getRole().getId())); RoleModel roleById = realm.getRoleById(roleId);
em.detach(entity); if (roleById == null) continue;
roles.add(roleById);
} }
return roles; return roles;
} }

View file

@ -16,7 +16,8 @@ import javax.persistence.NamedQuery;
*/ */
@NamedQueries({ @NamedQueries({
@NamedQuery(name="hasScope", query="select m from ScopeMappingEntity m where m.client = :client and m.role = :role"), @NamedQuery(name="hasScope", query="select m from ScopeMappingEntity m where m.client = :client and m.role = :role"),
@NamedQuery(name="clientScopeMappings", query="select m from ScopeMappingEntity m where m.client = :client") @NamedQuery(name="clientScopeMappings", query="select m from ScopeMappingEntity m where m.client = :client"),
@NamedQuery(name="clientScopeMappingIds", query="select m.role.id from ScopeMappingEntity m where m.client = :client")
}) })
@Entity @Entity
public class ScopeMappingEntity { public class ScopeMappingEntity {

View file

@ -10,7 +10,8 @@ import javax.persistence.NamedQuery;
*/ */
@NamedQueries({ @NamedQueries({
@NamedQuery(name="userHasRole", query="select m from UserRoleMappingEntity m where m.user = :user and m.role = :role"), @NamedQuery(name="userHasRole", query="select m from UserRoleMappingEntity m where m.user = :user and m.role = :role"),
@NamedQuery(name="userRoleMappings", query="select m from UserRoleMappingEntity m where m.user = :user") @NamedQuery(name="userRoleMappings", query="select m from UserRoleMappingEntity m where m.user = :user"),
@NamedQuery(name="userRoleMappingIds", query="select m.role.id from UserRoleMappingEntity m where m.user = :user")
}) })
@Entity @Entity
public class UserRoleMappingEntity extends AbstractRoleMappingEntity { public class UserRoleMappingEntity extends AbstractRoleMappingEntity {

View file

@ -29,7 +29,7 @@
<property name="hibernate.connection.username" value="sa"/> <property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/> <property name="hibernate.connection.password" value=""/>
<property name="hibernate.hbm2ddl.auto" value="create-drop" /> <property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="hibernate.show_sql" value="false" /> <property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" /> <property name="hibernate.format_sql" value="true" />
</properties> </properties>
</persistence-unit> </persistence-unit>

View file

@ -234,7 +234,7 @@ public class AccessTokenPerfTest {
@Test @Test
public void perfJaxrsClientLogin() public void perfJaxrsClientLogin()
{ {
long ITERATIONS = 100; long ITERATIONS = 3;
JaxrsClientLogin login = new JaxrsClientLogin(); JaxrsClientLogin login = new JaxrsClientLogin();
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
for (int i = 0; i < ITERATIONS; i++) { for (int i = 0; i < ITERATIONS; i++) {
@ -252,6 +252,7 @@ public class AccessTokenPerfTest {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
BrowserLogin login = new BrowserLogin(); BrowserLogin login = new BrowserLogin();
for (int i = 0; i < ITERATIONS; i++) { for (int i = 0; i < ITERATIONS; i++) {
//System.out.println("----------------------------------");
login.run(); login.run();
} }
long end = System.currentTimeMillis() - start; long end = System.currentTimeMillis() - start;