KEYCLOAK-4593: Moved NamedQuery to entity attribute to improve performance
This commit is contained in:
parent
ace64c1f0c
commit
ec61c45da5
5 changed files with 31 additions and 44 deletions
|
@ -675,12 +675,12 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
|
|||
public Set<RoleModel> getRoles() {
|
||||
return session.realms().getClientRoles(realm, this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getRoles(Integer first, Integer max) {
|
||||
return session.realms().getClientRoles(realm, this, first, max);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> searchForRoles(String search, Integer first, Integer max) {
|
||||
return session.realms().searchForClientRoles(realm, this, search, first, max);
|
||||
|
|
|
@ -26,20 +26,18 @@ import org.keycloak.models.RoleContainerModel;
|
|||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.jpa.entities.ClientScopeAttributeEntity;
|
||||
import org.keycloak.models.jpa.entities.ClientScopeEntity;
|
||||
import org.keycloak.models.jpa.entities.ClientScopeRoleMappingEntity;
|
||||
import org.keycloak.models.jpa.entities.ProtocolMapperEntity;
|
||||
import org.keycloak.models.jpa.entities.RoleEntity;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import javax.persistence.LockModeType;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -230,47 +228,22 @@ public class ClientScopeAdapter implements ClientScopeModel, JpaModel<ClientScop
|
|||
|
||||
@Override
|
||||
public Set<RoleModel> getScopeMappings() {
|
||||
TypedQuery<String> query = em.createNamedQuery("clientScopeRoleMappingIds", String.class);
|
||||
query.setParameter("clientScope", getEntity());
|
||||
List<String> ids = query.getResultList();
|
||||
Set<RoleModel> roles = new HashSet<RoleModel>();
|
||||
for (String roleId : ids) {
|
||||
RoleModel role = realm.getRoleById(roleId);
|
||||
if (role == null) continue;
|
||||
roles.add(role);
|
||||
}
|
||||
return roles;
|
||||
return getEntity().getScopeMapping().stream()
|
||||
.map(RoleEntity::getId)
|
||||
.map(realm::getRoleById)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addScopeMapping(RoleModel role) {
|
||||
if (hasScope(role)) return;
|
||||
ClientScopeRoleMappingEntity entity = new ClientScopeRoleMappingEntity();
|
||||
entity.setClientScope(getEntity());
|
||||
RoleEntity roleEntity = RoleAdapter.toRoleEntity(role, em);
|
||||
entity.setRole(roleEntity);
|
||||
em.persist(entity);
|
||||
em.flush();
|
||||
em.detach(entity);
|
||||
getEntity().getScopeMapping().add(roleEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteScopeMapping(RoleModel role) {
|
||||
TypedQuery<ClientScopeRoleMappingEntity> query = getRealmScopeMappingQuery(role);
|
||||
query.setLockMode(LockModeType.PESSIMISTIC_WRITE);
|
||||
List<ClientScopeRoleMappingEntity> results = query.getResultList();
|
||||
if (results.size() == 0) return;
|
||||
for (ClientScopeRoleMappingEntity entity : results) {
|
||||
em.remove(entity);
|
||||
}
|
||||
}
|
||||
|
||||
protected TypedQuery<ClientScopeRoleMappingEntity> getRealmScopeMappingQuery(RoleModel role) {
|
||||
TypedQuery<ClientScopeRoleMappingEntity> query = em.createNamedQuery("clientScopeHasRole", ClientScopeRoleMappingEntity.class);
|
||||
query.setParameter("clientScope", getEntity());
|
||||
RoleEntity roleEntity = RoleAdapter.toRoleEntity(role, em);
|
||||
query.setParameter("role", roleEntity);
|
||||
return query;
|
||||
getEntity().getScopeMapping().remove(RoleAdapter.toRoleEntity(role, em));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -120,7 +120,6 @@ public class JpaRealmProvider implements RealmProvider {
|
|||
for (String id : entities) {
|
||||
RealmModel realm = session.realms().getRealm(id);
|
||||
if (realm != null) realms.add(realm);
|
||||
em.flush();
|
||||
}
|
||||
return realms;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,11 @@
|
|||
|
||||
package org.keycloak.models.jpa.entities;
|
||||
|
||||
import org.hibernate.annotations.Nationalized;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.persistence.Access;
|
||||
import javax.persistence.AccessType;
|
||||
|
@ -27,12 +31,13 @@ import javax.persistence.Entity;
|
|||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import org.hibernate.annotations.Nationalized;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -64,6 +69,10 @@ public class ClientScopeEntity {
|
|||
@OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "clientScope")
|
||||
protected Collection<ClientScopeAttributeEntity> attributes;
|
||||
|
||||
@OneToMany(fetch = FetchType.LAZY)
|
||||
@JoinTable(name="CLIENT_SCOPE_ROLE_MAPPING", joinColumns = { @JoinColumn(name="SCOPE_ID")}, inverseJoinColumns = { @JoinColumn(name="ROLE_ID")})
|
||||
protected Set<RoleEntity> scopeMapping = new HashSet<>();
|
||||
|
||||
public RealmEntity getRealm() {
|
||||
return realm;
|
||||
}
|
||||
|
@ -126,6 +135,14 @@ public class ClientScopeEntity {
|
|||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public Set<RoleEntity> getScopeMapping() {
|
||||
return scopeMapping;
|
||||
}
|
||||
|
||||
public void setScopeMapping(Set<RoleEntity> scopeMapping) {
|
||||
this.scopeMapping = scopeMapping;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
|
|
@ -33,8 +33,6 @@ import java.io.Serializable;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
@NamedQueries({
|
||||
@NamedQuery(name="clientScopeHasRole", query="select m from ClientScopeRoleMappingEntity m where m.clientScope = :clientScope and m.role = :role"),
|
||||
@NamedQuery(name="clientScopeRoleMappingIds", query="select m.role.id from ClientScopeRoleMappingEntity m where m.clientScope = :clientScope"),
|
||||
@NamedQuery(name="deleteClientScopeRoleMappingByRole", query="delete from ClientScopeRoleMappingEntity where role = :role"),
|
||||
@NamedQuery(name="deleteClientScopeRoleMappingByClientScope", query="delete from ClientScopeRoleMappingEntity where clientScope = :clientScope")
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue