mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-10 15:32:05 -03:30
Avoid inefficient SQL when deleting a role (#39238)
Closes #39237 Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
This commit is contained in:
parent
4e95bde179
commit
660217dc41
@ -458,18 +458,15 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, ClientSc
|
||||
// So in any case, native query is not an option. This is not optimal as it executes additional queries but
|
||||
// the alternative of clearing the persistence context is not either as we don't know if something currently present
|
||||
// in the context is not needed later.
|
||||
Stream<RoleEntity> parentRoles = em.createNamedQuery("getParentRolesOfACompositeRole", RoleEntity.class).setParameter("compositeRole", roleEntity).getResultStream();
|
||||
parentRoles.forEach(parentRole -> parentRole.getCompositeRoles().remove(roleEntity));
|
||||
parentRoles.close();
|
||||
|
||||
roleEntity.getParentRoles().forEach(roleEntity1 -> roleEntity1.getCompositeRoles().remove(roleEntity));
|
||||
|
||||
em.createNamedQuery("deleteClientScopeRoleMappingByRole").setParameter("role", roleEntity).executeUpdate();
|
||||
|
||||
em.flush();
|
||||
em.remove(roleEntity);
|
||||
|
||||
session.getKeycloakSessionFactory().publish(roleRemovedEvent(role));
|
||||
|
||||
em.flush();
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
@ -65,7 +65,6 @@ import java.util.Set;
|
||||
@NamedQuery(name="searchForRealmRoles", query="select role from RoleEntity role where role.clientRole = false and role.realmId = :realm and ( lower(role.name) like :search or lower(role.description) like :search ) order by role.name"),
|
||||
@NamedQuery(name="getRoleIdsFromIdList", query="select role.id from RoleEntity role where role.realmId = :realm and role.id in :ids order by role.name ASC"),
|
||||
@NamedQuery(name="getRoleIdsByNameContainingFromIdList", query="select role.id from RoleEntity role where role.realmId = :realm and lower(role.name) like lower(concat('%',:search,'%')) and role.id in :ids order by role.name ASC"),
|
||||
@NamedQuery(name="getParentRolesOfACompositeRole", query = "select role from RoleEntity role where :compositeRole member of role.compositeRoles"),
|
||||
})
|
||||
|
||||
public class RoleEntity {
|
||||
@ -99,6 +98,9 @@ public class RoleEntity {
|
||||
@JoinTable(name = "COMPOSITE_ROLE", joinColumns = @JoinColumn(name = "COMPOSITE"), inverseJoinColumns = @JoinColumn(name = "CHILD_ROLE"))
|
||||
private Set<RoleEntity> compositeRoles;
|
||||
|
||||
@ManyToMany(mappedBy = "compositeRoles", fetch = FetchType.LAZY, cascade = {})
|
||||
private Set<RoleEntity> parentRoles;
|
||||
|
||||
// Explicitly not using OrphanRemoval as we're handling the removal manually through HQL but at the same time we still
|
||||
// want to remove elements from the entity's collection in a manual way. Without this, Hibernate would do a duplicit
|
||||
// delete query.
|
||||
@ -158,6 +160,17 @@ public class RoleEntity {
|
||||
return compositeRoles;
|
||||
}
|
||||
|
||||
public Set<RoleEntity> getParentRoles() {
|
||||
if (parentRoles == null) {
|
||||
parentRoles = new HashSet<>();
|
||||
}
|
||||
return parentRoles;
|
||||
}
|
||||
|
||||
public void setParentRoles(Set<RoleEntity> parentRoles) {
|
||||
this.parentRoles = parentRoles;
|
||||
}
|
||||
|
||||
public void setCompositeRoles(Set<RoleEntity> compositeRoles) {
|
||||
this.compositeRoles = compositeRoles;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user