diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java index e0b01ca4ea..0481ea2725 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java @@ -675,12 +675,12 @@ public class ClientAdapter implements ClientModel, JpaModel { public Set getRoles() { return session.realms().getClientRoles(realm, this); } - + @Override public Set getRoles(Integer first, Integer max) { return session.realms().getClientRoles(realm, this, first, max); } - + @Override public Set searchForRoles(String search, Integer first, Integer max) { return session.realms().searchForClientRoles(realm, this, search, first, max); diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientScopeAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientScopeAdapter.java index 00e80f720c..acbc33a7cd 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientScopeAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientScopeAdapter.java @@ -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 Bill Burke @@ -230,47 +228,22 @@ public class ClientScopeAdapter implements ClientScopeModel, JpaModel getScopeMappings() { - TypedQuery query = em.createNamedQuery("clientScopeRoleMappingIds", String.class); - query.setParameter("clientScope", getEntity()); - List ids = query.getResultList(); - Set roles = new HashSet(); - 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 query = getRealmScopeMappingQuery(role); - query.setLockMode(LockModeType.PESSIMISTIC_WRITE); - List results = query.getResultList(); - if (results.size() == 0) return; - for (ClientScopeRoleMappingEntity entity : results) { - em.remove(entity); - } - } - - protected TypedQuery getRealmScopeMappingQuery(RoleModel role) { - TypedQuery 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 diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java index ad17a4571c..b05f8ea043 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaRealmProvider.java @@ -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; } diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientScopeEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientScopeEntity.java index a2a502995f..728e75b917 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientScopeEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientScopeEntity.java @@ -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 Bill Burke @@ -64,6 +69,10 @@ public class ClientScopeEntity { @OneToMany(cascade ={CascadeType.REMOVE}, orphanRemoval = true, mappedBy = "clientScope") protected Collection attributes; + @OneToMany(fetch = FetchType.LAZY) + @JoinTable(name="CLIENT_SCOPE_ROLE_MAPPING", joinColumns = { @JoinColumn(name="SCOPE_ID")}, inverseJoinColumns = { @JoinColumn(name="ROLE_ID")}) + protected Set scopeMapping = new HashSet<>(); + public RealmEntity getRealm() { return realm; } @@ -126,6 +135,14 @@ public class ClientScopeEntity { this.attributes = attributes; } + public Set getScopeMapping() { + return scopeMapping; + } + + public void setScopeMapping(Set scopeMapping) { + this.scopeMapping = scopeMapping; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientScopeRoleMappingEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientScopeRoleMappingEntity.java index c567f73687..cf5e95d66d 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientScopeRoleMappingEntity.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientScopeRoleMappingEntity.java @@ -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") })