keycloak-developers

added developers cache

12/24/2019 1:49:52 PM

Details

diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/PermissionTicketAdapter.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/PermissionTicketAdapter.java
index 6f66a2e..04e9720 100644
--- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/PermissionTicketAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/PermissionTicketAdapter.java
@@ -31,6 +31,8 @@ import org.keycloak.authorization.model.Scope;
 import org.keycloak.authorization.store.StoreFactory;
 import org.keycloak.models.jpa.JpaModel;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -47,78 +49,84 @@ public class PermissionTicketAdapter implements PermissionTicket, JpaModel<Permi
         this.storeFactory = storeFactory;
     }
 
+public static GetterCache<PermissionTicketEntity> getEntity = new GetterCache<>("PermissionTicketAdapter.getEntity");
+
     @Override
     public PermissionTicketEntity getEntity() {
+        return getEntity.computeIfAbsent(() -> {
         return entity;
+        }, 120000);
     }
 
     @Override
     public String getId() {
-        return entity.getId();
+        return getEntity().getId();
     }
 
     @Override
     public String getOwner() {
-        return entity.getOwner();
+        return getEntity().getOwner();
     }
 
     @Override
     public String getRequester() {
-        return entity.getRequester();
+        return getEntity().getRequester();
     }
 
     @Override
     public boolean isGranted() {
-        return entity.isGranted();
+        return getEntity().isGranted();
     }
 
     @Override
     public Long getCreatedTimestamp() {
-        return entity.getCreatedTimestamp();
+        return getEntity().getCreatedTimestamp();
     }
 
     @Override
     public Long getGrantedTimestamp() {
-        return entity.getGrantedTimestamp();
+        return getEntity().getGrantedTimestamp();
     }
 
     @Override
     public void setGrantedTimestamp(Long millis) {
+        getEntity.invalidate();
         entity.setGrantedTimestamp(millis);
         updatePolicy(this, storeFactory);
     }
 
     @Override
     public ResourceServer getResourceServer() {
-        return storeFactory.getResourceServerStore().findById(entity.getResourceServer().getId());
+        return storeFactory.getResourceServerStore().findById(getEntity().getResourceServer().getId());
     }
 
     @Override
     public Policy getPolicy() {
-        PolicyEntity policy = entity.getPolicy();
+        PolicyEntity policy = getEntity().getPolicy();
 
         if (policy == null) {
             return null;
         }
 
-        return storeFactory.getPolicyStore().findById(policy.getId(), entity.getResourceServer().getId());
+        return storeFactory.getPolicyStore().findById(policy.getId(), getEntity().getResourceServer().getId());
     }
 
     @Override
     public void setPolicy(Policy policy) {
         if (policy != null) {
+            getEntity.invalidate();
             entity.setPolicy(entityManager.getReference(PolicyEntity.class, policy.getId()));
         }
     }
 
     @Override
     public Resource getResource() {
-        return storeFactory.getResourceStore().findById(entity.getResource().getId(), getResourceServer().getId());
+        return storeFactory.getResourceStore().findById(getEntity().getResource().getId(), getResourceServer().getId());
     }
 
     @Override
     public Scope getScope() {
-        ScopeEntity scope = entity.getScope();
+        ScopeEntity scope = getEntity().getScope();
 
         if (scope == null) {
             return null;
diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/PolicyAdapter.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/PolicyAdapter.java
index 4746b20..3ee06cc 100644
--- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/PolicyAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/PolicyAdapter.java
@@ -36,6 +36,8 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -52,54 +54,61 @@ public class PolicyAdapter extends AbstractAuthorizationModel implements Policy,
         this.storeFactory = storeFactory;
     }
 
+public static GetterCache<PolicyEntity> getEntity = new GetterCache<>("PolicyAdapter.getEntity");
+
     @Override
     public PolicyEntity getEntity() {
+return getEntity.computeIfAbsent(() -> {
         return entity;
+}, 120000);
     }
 
     @Override
     public String getId() {
-        return entity.getId();
+        return getEntity().getId();
     }
 
     @Override
     public String getType() {
-        return entity.getType();
+        return getEntity().getType();
     }
 
     @Override
     public DecisionStrategy getDecisionStrategy() {
-        return entity.getDecisionStrategy();
+        return getEntity().getDecisionStrategy();
     }
 
     @Override
     public void setDecisionStrategy(DecisionStrategy decisionStrategy) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.setDecisionStrategy(decisionStrategy);
 
     }
 
     @Override
     public Logic getLogic() {
-        return entity.getLogic();
+        return getEntity().getLogic();
     }
 
     @Override
     public void setLogic(Logic logic) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.setLogic(logic);
     }
 
     @Override
     public Map<String, String> getConfig() {
         Map<String, String> result = new HashMap<String, String>();
-        if (entity.getConfig() != null) result.putAll(entity.getConfig());
+        if (getEntity().getConfig() != null) result.putAll(getEntity().getConfig());
         return Collections.unmodifiableMap(result);
     }
 
     @Override
     public void setConfig(Map<String, String> config) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         if (entity.getConfig() == null) {
             entity.setConfig(new HashMap<>());
         } else {
@@ -111,6 +120,7 @@ public class PolicyAdapter extends AbstractAuthorizationModel implements Policy,
     @Override
     public void removeConfig(String name) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         if (entity.getConfig() == null) {
             return;
         }
@@ -120,6 +130,7 @@ public class PolicyAdapter extends AbstractAuthorizationModel implements Policy,
     @Override
     public void putConfig(String name, String value) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         if (entity.getConfig() == null) {
             entity.setConfig(new HashMap<>());
         }
@@ -129,37 +140,39 @@ public class PolicyAdapter extends AbstractAuthorizationModel implements Policy,
 
     @Override
     public String getName() {
-        return entity.getName();
+        return getEntity().getName();
     }
 
     @Override
     public void setName(String name) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.setName(name);
 
     }
 
     @Override
     public String getDescription() {
-        return entity.getDescription();
+        return getEntity().getDescription();
     }
 
     @Override
     public void setDescription(String description) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.setDescription(description);
 
     }
 
     @Override
     public ResourceServer getResourceServer() {
-        return storeFactory.getResourceServerStore().findById(entity.getResourceServer().getId());
+        return storeFactory.getResourceServerStore().findById(getEntity().getResourceServer().getId());
     }
 
     @Override
     public Set<Policy> getAssociatedPolicies() {
         Set<Policy> result = new HashSet<>();
-        for (PolicyEntity policy : entity.getAssociatedPolicies()) {
+        for (PolicyEntity policy : getEntity().getAssociatedPolicies()) {
             result.add(new PolicyAdapter(policy, em, storeFactory));
         }
         return Collections.unmodifiableSet(result);
@@ -168,8 +181,8 @@ public class PolicyAdapter extends AbstractAuthorizationModel implements Policy,
     @Override
     public Set<Resource> getResources() {
         Set<Resource> set = new HashSet<>();
-        for (ResourceEntity res : entity.getResources()) {
-            set.add(storeFactory.getResourceStore().findById(res.getId(), entity.getResourceServer().getId()));
+        for (ResourceEntity res : getEntity().getResources()) {
+            set.add(storeFactory.getResourceStore().findById(res.getId(), getEntity().getResourceServer().getId()));
         }
         return Collections.unmodifiableSet(set);
     }
@@ -177,8 +190,8 @@ public class PolicyAdapter extends AbstractAuthorizationModel implements Policy,
     @Override
     public Set<Scope> getScopes() {
         Set<Scope> set = new HashSet<>();
-        for (ScopeEntity res : entity.getScopes()) {
-            set.add(storeFactory.getScopeStore().findById(res.getId(), entity.getResourceServer().getId()));
+        for (ScopeEntity res : getEntity().getScopes()) {
+            set.add(storeFactory.getScopeStore().findById(res.getId(), getEntity().getResourceServer().getId()));
         }
         return Collections.unmodifiableSet(set);
     }
@@ -186,12 +199,14 @@ public class PolicyAdapter extends AbstractAuthorizationModel implements Policy,
     @Override
     public void addScope(Scope scope) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.getScopes().add(ScopeAdapter.toEntity(em, scope));
     }
 
     @Override
     public void removeScope(Scope scope) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.getScopes().remove(ScopeAdapter.toEntity(em, scope));
 
     }
@@ -199,12 +214,14 @@ public class PolicyAdapter extends AbstractAuthorizationModel implements Policy,
     @Override
     public void addAssociatedPolicy(Policy associatedPolicy) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.getAssociatedPolicies().add(toEntity(em, associatedPolicy));
     }
 
     @Override
     public void removeAssociatedPolicy(Policy associatedPolicy) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.getAssociatedPolicies().remove(toEntity(em, associatedPolicy));
 
     }
@@ -212,24 +229,27 @@ public class PolicyAdapter extends AbstractAuthorizationModel implements Policy,
     @Override
     public void addResource(Resource resource) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.getResources().add(ResourceAdapter.toEntity(em, resource));
     }
 
     @Override
     public void removeResource(Resource resource) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.getResources().remove(ResourceAdapter.toEntity(em, resource));
     }
 
     @Override
     public void setOwner(String owner) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.setOwner(owner);
     }
 
     @Override
     public String getOwner() {
-        return entity.getOwner();
+        return getEntity().getOwner();
     }
 
     @Override
diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ResourceAdapter.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ResourceAdapter.java
index a7a295e..2da0ae1 100644
--- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ResourceAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ResourceAdapter.java
@@ -40,6 +40,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -57,35 +59,40 @@ public class ResourceAdapter extends AbstractAuthorizationModel implements Resou
         this.storeFactory = storeFactory;
     }
 
+public static GetterCache<ResourceEntity> getEntity = new GetterCache<>("ResourceAdapter.getEntity");
+
     @Override
     public ResourceEntity getEntity() {
+return getEntity.computeIfAbsent(() -> {
         return entity;
+}, 120000);
     }
 
     @Override
     public String getId() {
-        return entity.getId();
+        return getEntity().getId();
     }
 
     @Override
     public String getName() {
-        return entity.getName();
+        return getEntity().getName();
     }
 
     @Override
     public String getDisplayName() {
-        return entity.getDisplayName();
+        return getEntity().getDisplayName();
     }
 
     @Override
     public void setDisplayName(String name) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.setDisplayName(name);
     }
 
     @Override
     public Set<String> getUris() {
-        return entity.getUris();
+        return getEntity().getUris();
     }
 
     @Override
@@ -97,18 +104,20 @@ public class ResourceAdapter extends AbstractAuthorizationModel implements Resou
     @Override
     public void setName(String name) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.setName(name);
 
     }
 
     @Override
     public String getType() {
-        return entity.getType();
+        return getEntity().getType();
     }
 
     @Override
     public void setType(String type) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.setType(type);
 
     }
@@ -116,8 +125,8 @@ public class ResourceAdapter extends AbstractAuthorizationModel implements Resou
     @Override
     public List<Scope> getScopes() {
         List<Scope> scopes = new LinkedList<>();
-        for (ScopeEntity scope : entity.getScopes()) {
-            scopes.add(storeFactory.getScopeStore().findById(scope.getId(), entity.getResourceServer().getId()));
+        for (ScopeEntity scope : getEntity().getScopes()) {
+            scopes.add(storeFactory.getScopeStore().findById(scope.getId(), getEntity().getResourceServer().getId()));
         }
 
         return Collections.unmodifiableList(scopes);
@@ -125,40 +134,43 @@ public class ResourceAdapter extends AbstractAuthorizationModel implements Resou
 
     @Override
     public String getIconUri() {
-        return entity.getIconUri();
+        return getEntity().getIconUri();
     }
 
     @Override
     public void setIconUri(String iconUri) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.setIconUri(iconUri);
 
     }
 
     @Override
     public ResourceServer getResourceServer() {
-        return storeFactory.getResourceServerStore().findById(entity.getResourceServer().getId());
+        return storeFactory.getResourceServerStore().findById(getEntity().getResourceServer().getId());
     }
 
     @Override
     public String getOwner() {
-        return entity.getOwner();
+        return getEntity().getOwner();
     }
 
     @Override
     public boolean isOwnerManagedAccess() {
-        return entity.isOwnerManagedAccess();
+        return getEntity().isOwnerManagedAccess();
     }
 
     @Override
     public void setOwnerManagedAccess(boolean ownerManagedAccess) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.setOwnerManagedAccess(ownerManagedAccess);
     }
 
     @Override
     public void updateScopes(Set<Scope> toUpdate) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         Set<String> ids = new HashSet<>();
         for (Scope scope : toUpdate) {
             ids.add(scope.getId());
@@ -177,7 +189,7 @@ public class ResourceAdapter extends AbstractAuthorizationModel implements Resou
     @Override
     public Map<String, List<String>> getAttributes() {
         MultivaluedHashMap<String, String> result = new MultivaluedHashMap<>();
-        for (ResourceAttributeEntity attr : entity.getAttributes()) {
+        for (ResourceAttributeEntity attr : getEntity().getAttributes()) {
             result.add(attr.getName(), attr.getValue());
         }
         return Collections.unmodifiableMap(result);
@@ -207,6 +219,7 @@ public class ResourceAdapter extends AbstractAuthorizationModel implements Resou
 
     @Override
     public void setAttribute(String name, List<String> values) {
+        getEntity.invalidate();
         removeAttribute(name);
 
         for (String value : values) {
@@ -223,6 +236,7 @@ public class ResourceAdapter extends AbstractAuthorizationModel implements Resou
     @Override
     public void removeAttribute(String name) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         Query query = em.createNamedQuery("deleteResourceAttributesByNameAndResource");
 
         query.setParameter("name", name);
diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ResourceServerAdapter.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ResourceServerAdapter.java
index a3098ef..62ba278 100644
--- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ResourceServerAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ResourceServerAdapter.java
@@ -25,6 +25,8 @@ import org.keycloak.representations.idm.authorization.PolicyEnforcementMode;
 
 import javax.persistence.EntityManager;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -41,36 +43,42 @@ public class ResourceServerAdapter extends AbstractAuthorizationModel implements
         this.storeFactory = storeFactory;
     }
 
+public static GetterCache<ResourceServerEntity> getEntity = new GetterCache<>("ResourceServerAdapter.getEntity");
+
     @Override
     public ResourceServerEntity getEntity() {
+return getEntity.computeIfAbsent(() -> {
         return entity;
+}, 120000);
     }
 
     @Override
     public String getId() {
-        return entity.getId();
+        return getEntity().getId();
     }
 
     @Override
     public boolean isAllowRemoteResourceManagement() {
-        return entity.isAllowRemoteResourceManagement();
+        return getEntity().isAllowRemoteResourceManagement();
     }
 
     @Override
     public void setAllowRemoteResourceManagement(boolean allowRemoteResourceManagement) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.setAllowRemoteResourceManagement(allowRemoteResourceManagement);
 
     }
 
     @Override
     public PolicyEnforcementMode getPolicyEnforcementMode() {
-        return entity.getPolicyEnforcementMode();
+        return getEntity().getPolicyEnforcementMode();
     }
 
     @Override
     public void setPolicyEnforcementMode(PolicyEnforcementMode enforcementMode) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.setPolicyEnforcementMode(enforcementMode);
 
     }
diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ScopeAdapter.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ScopeAdapter.java
index cb34b88..3267a37 100644
--- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ScopeAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ScopeAdapter.java
@@ -25,6 +25,8 @@ import org.keycloak.models.jpa.JpaModel;
 
 import javax.persistence.EntityManager;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -41,54 +43,61 @@ public class ScopeAdapter extends AbstractAuthorizationModel implements Scope, J
         this.storeFactory = storeFactory;
     }
 
+public static GetterCache<ScopeEntity> getEntity = new GetterCache<>("ScopeAdapter.getEntity");
+
     @Override
     public ScopeEntity getEntity() {
+return getEntity.computeIfAbsent(() -> {
         return entity;
+}, 120000);
     }
 
     @Override
     public String getId() {
-        return entity.getId();
+        return getEntity().getId();
     }
 
     @Override
     public String getName() {
-        return entity.getName();
+        return getEntity().getName();
     }
 
     @Override
     public void setName(String name) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.setName(name);
 
     }
 
     @Override
     public String getDisplayName() {
-        return entity.getDisplayName();
+        return getEntity().getDisplayName();
     }
 
     @Override
     public void setDisplayName(String name) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.setDisplayName(name);
     }
 
     @Override
     public String getIconUri() {
-        return entity.getIconUri();
+        return getEntity().getIconUri();
     }
 
     @Override
     public void setIconUri(String iconUri) {
         throwExceptionIfReadonly();
+        getEntity.invalidate();
         entity.setIconUri(iconUri);
 
     }
 
     @Override
     public ResourceServer getResourceServer() {
-        return storeFactory.getResourceServerStore().findById(entity.getResourceServer().getId());
+        return storeFactory.getResourceServerStore().findById(getEntity().getResourceServer().getId());
     }
 
     public static ScopeEntity toEntity(EntityManager em, Scope scope) {
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 592c1e2..b2a78e5 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
@@ -48,6 +48,8 @@ import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -66,13 +68,17 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
         this.entity = entity;
     }
 
+public static GetterCache<ClientEntity> getEntity = new GetterCache<>("ClientAdapter.getEntity");
+
     public ClientEntity getEntity() {
+return getEntity.computeIfAbsent(() -> {
         return entity;
+}, 120000);
     }
 
     @Override
     public String getId() {
-        return entity.getId();
+        return getEntity().getId();
     }
 
     @Override
@@ -82,64 +88,71 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
 
     @Override
     public String getName() {
-        return entity.getName();
+        return getEntity().getName();
     }
 
     @Override
     public void setName(String name) {
+        getEntity.invalidate();
         entity.setName(name);
     }
 
     @Override
-    public String getDescription() { return entity.getDescription(); }
+    public String getDescription() { return getEntity().getDescription(); }
 
     @Override
-    public void setDescription(String description) { entity.setDescription(description); }
+    public void setDescription(String description) { 
+getEntity.invalidate();
+        entity.setDescription(description); }
 
     @Override
     public boolean isEnabled() {
-        return entity.isEnabled();
+        return getEntity().isEnabled();
     }
 
     @Override
     public void setEnabled(boolean enabled) {
+        getEntity.invalidate();
         entity.setEnabled(enabled);
     }
 
     @Override
     public boolean isPublicClient() {
-        return entity.isPublicClient();
+        return getEntity().isPublicClient();
     }
 
     @Override
     public void setPublicClient(boolean flag) {
+        getEntity.invalidate();
         entity.setPublicClient(flag);
     }
 
     @Override
     public boolean isFrontchannelLogout() {
-        return entity.isFrontchannelLogout();
+        return getEntity().isFrontchannelLogout();
     }
 
     @Override
     public void setFrontchannelLogout(boolean flag) {
+        getEntity.invalidate();
         entity.setFrontchannelLogout(flag);
     }
 
     @Override
     public boolean isFullScopeAllowed() {
-        return entity.isFullScopeAllowed();
+        return getEntity().isFullScopeAllowed();
     }
 
     @Override
     public void setFullScopeAllowed(boolean value) {
+        getEntity.invalidate();
         entity.setFullScopeAllowed(value);
     }
 
     @Override
     public Set<String> getWebOrigins() {
         Set<String> result = new HashSet<String>();
-        result.addAll(entity.getWebOrigins());
+        result.addAll(getEntity().getWebOrigins());
         return result;
     }
 
@@ -147,83 +160,89 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
 
     @Override
     public void setWebOrigins(Set<String> webOrigins) {
+        getEntity.invalidate();
         entity.setWebOrigins(webOrigins);
     }
 
     @Override
     public void addWebOrigin(String webOrigin) {
-        entity.getWebOrigins().add(webOrigin);
+        getEntity().getWebOrigins().add(webOrigin);
     }
 
     @Override
     public void removeWebOrigin(String webOrigin) {
-        entity.getWebOrigins().remove(webOrigin);
+        getEntity().getWebOrigins().remove(webOrigin);
     }
 
     @Override
     public Set<String> getRedirectUris() {
         Set<String> result = new HashSet<String>();
-        result.addAll(entity.getRedirectUris());
+        result.addAll(getEntity().getRedirectUris());
         return result;
     }
 
     @Override
     public void setRedirectUris(Set<String> redirectUris) {
+        getEntity.invalidate();
         entity.setRedirectUris(redirectUris);
     }
 
     @Override
     public void addRedirectUri(String redirectUri) {
-        entity.getRedirectUris().add(redirectUri);
+        getEntity().getRedirectUris().add(redirectUri);
     }
 
     @Override
     public void removeRedirectUri(String redirectUri) {
-        entity.getRedirectUris().remove(redirectUri);
+        getEntity().getRedirectUris().remove(redirectUri);
     }
 
     @Override
     public String getClientAuthenticatorType() {
-        return entity.getClientAuthenticatorType();
+        return getEntity().getClientAuthenticatorType();
     }
 
     @Override
     public void setClientAuthenticatorType(String clientAuthenticatorType) {
+        getEntity.invalidate();
         entity.setClientAuthenticatorType(clientAuthenticatorType);
     }
 
     @Override
     public String getSecret() {
-        return entity.getSecret();
+        return getEntity().getSecret();
     }
 
     @Override
     public void setSecret(String secret) {
+        getEntity.invalidate();
         entity.setSecret(secret);
     }
 
     @Override
     public String getRegistrationToken() {
-        return entity.getRegistrationToken();
+        return getEntity().getRegistrationToken();
     }
 
     @Override
     public void setRegistrationToken(String registrationToken) {
+        getEntity.invalidate();
         entity.setRegistrationToken(registrationToken);
     }
 
     @Override
     public boolean validateSecret(String secret) {
-        return MessageDigest.isEqual(secret.getBytes(), entity.getSecret().getBytes());
+        return MessageDigest.isEqual(secret.getBytes(), getEntity().getSecret().getBytes());
     }
 
     @Override
     public int getNotBefore() {
-        return entity.getNotBefore();
+        return getEntity().getNotBefore();
     }
 
     @Override
     public void setNotBefore(int notBefore) {
+        getEntity.invalidate();
         entity.setNotBefore(notBefore);
     }
 
@@ -266,40 +285,42 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
 
     @Override
     public String getProtocol() {
-        return entity.getProtocol();
+        return getEntity().getProtocol();
     }
 
     @Override
     public void setProtocol(String protocol) {
+        getEntity.invalidate();
         entity.setProtocol(protocol);
 
     }
 
     @Override
     public void setAuthenticationFlowBindingOverride(String name, String value) {
-        entity.getAuthFlowBindings().put(name, value);
+        getEntity().getAuthFlowBindings().put(name, value);
 
     }
 
     @Override
     public void removeAuthenticationFlowBindingOverride(String name) {
-        entity.getAuthFlowBindings().remove(name);
+        getEntity().getAuthFlowBindings().remove(name);
     }
 
     @Override
     public String getAuthenticationFlowBindingOverride(String name) {
-        return entity.getAuthFlowBindings().get(name);
+        return getEntity().getAuthFlowBindings().get(name);
     }
 
     @Override
     public Map<String, String> getAuthenticationFlowBindingOverrides() {
         Map<String, String> copy = new HashMap<>();
-        copy.putAll(entity.getAuthFlowBindings());
+        copy.putAll(getEntity().getAuthFlowBindings());
         return copy;
     }
 
     @Override
     public void setAttribute(String name, String value) {
+        getEntity.invalidate();
         for (ClientAttributeEntity attr : entity.getAttributes()) {
             if (attr.getName().equals(name)) {
                 attr.setValue(value);
@@ -317,6 +338,7 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
 
     @Override
     public void removeAttribute(String name) {
+        getEntity.invalidate();
         Iterator<ClientAttributeEntity> it = entity.getAttributes().iterator();
         while (it.hasNext()) {
             ClientAttributeEntity attr = it.next();
@@ -335,7 +357,7 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
     @Override
     public Map<String, String> getAttributes() {
         Map<String, String> attrs = new HashMap<>();
-        for (ClientAttributeEntity attr : entity.getAttributes()) {
+        for (ClientAttributeEntity attr : getEntity().getAttributes()) {
             attrs.put(attr.getName(), attr.getValue());
         }
         return attrs;
@@ -343,6 +365,7 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
 
     @Override
     public void addClientScope(ClientScopeModel clientScope, boolean defaultScope) {
+        getEntity.invalidate();
         if (getClientScopes(defaultScope, false).containsKey(clientScope.getName())) return;
 
         ClientScopeClientMappingEntity entity = new ClientScopeClientMappingEntity();
@@ -394,8 +417,9 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
 
     @Override
     public Set<ProtocolMapperModel> getProtocolMappers() {
+        getEntity.invalidate();
         Set<ProtocolMapperModel> mappings = new HashSet<ProtocolMapperModel>();
-        for (ProtocolMapperEntity entity : this.entity.getProtocolMappers()) {
+        for (ProtocolMapperEntity entity : getEntity().getProtocolMappers()) {
             ProtocolMapperModel mapping = new ProtocolMapperModel();
             mapping.setId(entity.getId());
             mapping.setName(entity.getName());
@@ -413,6 +437,7 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
 
     @Override
     public ProtocolMapperModel addProtocolMapper(ProtocolMapperModel model) {
+        getEntity.invalidate();
         if (getProtocolMapperByName(model.getProtocol(), model.getName()) != null) {
             throw new ModelDuplicateException("Protocol mapper name must be unique per protocol");
         }
@@ -431,7 +456,8 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
     }
 
     protected ProtocolMapperEntity getProtocolMapperEntity(String id) {
-        for (ProtocolMapperEntity entity : this.entity.getProtocolMappers()) {
+        getEntity.invalidate();
+        for (ProtocolMapperEntity entity : getEntity().getProtocolMappers()) {
             if (entity.getId().equals(id)) {
                 return entity;
             }
@@ -441,7 +467,8 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
     }
 
     protected ProtocolMapperEntity getProtocolMapperEntityByName(String protocol, String name) {
-        for (ProtocolMapperEntity entity : this.entity.getProtocolMappers()) {
+        getEntity.invalidate();
+        for (ProtocolMapperEntity entity : getEntity().getProtocolMappers()) {
             if (entity.getProtocol().equals(protocol) && entity.getName().equals(name)) {
                 return entity;
             }
@@ -452,6 +479,7 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
 
     @Override
     public void removeProtocolMapper(ProtocolMapperModel mapping) {
+        getEntity.invalidate();
         ProtocolMapperEntity toDelete = getProtocolMapperEntity(mapping.getId());
         if (toDelete != null) {
             session.users().preRemove(mapping);
@@ -464,6 +492,7 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
 
     @Override
     public void updateProtocolMapper(ProtocolMapperModel mapping) {
+        getEntity.invalidate();
         ProtocolMapperEntity entity = getProtocolMapperEntity(mapping.getId());
         entity.setProtocolMapper(mapping.getProtocolMapper());
         if (entity.getConfig() == null) {
@@ -521,111 +550,122 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
 
     @Override
     public String getClientId() {
-        return entity.getClientId();
+        return getEntity().getClientId();
     }
 
     @Override
     public void setClientId(String clientId) {
+        getEntity.invalidate();
         entity.setClientId(clientId);
     }
 
     @Override
     public boolean isSurrogateAuthRequired() {
-        return entity.isSurrogateAuthRequired();
+        return getEntity().isSurrogateAuthRequired();
     }
 
     @Override
     public void setSurrogateAuthRequired(boolean surrogateAuthRequired) {
+        getEntity.invalidate();
         entity.setSurrogateAuthRequired(surrogateAuthRequired);
     }
 
     @Override
     public String getManagementUrl() {
-        return entity.getManagementUrl();
+        return getEntity().getManagementUrl();
     }
 
     @Override
     public void setManagementUrl(String url) {
+        getEntity.invalidate();
         entity.setManagementUrl(url);
     }
 
     @Override
     public String getRootUrl() {
-        return entity.getRootUrl();
+        return getEntity().getRootUrl();
     }
 
     @Override
     public void setRootUrl(String url) {
+        getEntity.invalidate();
         entity.setRootUrl(url);
     }
 
     @Override
     public String getBaseUrl() {
-        return entity.getBaseUrl();
+        return getEntity().getBaseUrl();
     }
 
     @Override
     public void setBaseUrl(String url) {
+        getEntity.invalidate();
         entity.setBaseUrl(url);
     }
 
     @Override
     public boolean isBearerOnly() {
-        return entity.isBearerOnly();
+        return getEntity().isBearerOnly();
     }
 
     @Override
     public void setBearerOnly(boolean only) {
+        getEntity.invalidate();
         entity.setBearerOnly(only);
     }
 
     @Override
     public boolean isConsentRequired() {
-        return entity.isConsentRequired();
+        return getEntity().isConsentRequired();
     }
 
     @Override
     public void setConsentRequired(boolean consentRequired) {
+        getEntity.invalidate();
         entity.setConsentRequired(consentRequired);
     }
 
     @Override
     public boolean isStandardFlowEnabled() {
-        return entity.isStandardFlowEnabled();
+        return getEntity().isStandardFlowEnabled();
     }
 
     @Override
     public void setStandardFlowEnabled(boolean standardFlowEnabled) {
+        getEntity.invalidate();
         entity.setStandardFlowEnabled(standardFlowEnabled);
     }
 
     @Override
     public boolean isImplicitFlowEnabled() {
-        return entity.isImplicitFlowEnabled();
+        return getEntity().isImplicitFlowEnabled();
     }
 
     @Override
     public void setImplicitFlowEnabled(boolean implicitFlowEnabled) {
+        getEntity.invalidate();
         entity.setImplicitFlowEnabled(implicitFlowEnabled);
     }
 
     @Override
     public boolean isDirectAccessGrantsEnabled() {
-        return entity.isDirectAccessGrantsEnabled();
+        return getEntity().isDirectAccessGrantsEnabled();
     }
 
     @Override
     public void setDirectAccessGrantsEnabled(boolean directAccessGrantsEnabled) {
+        getEntity.invalidate();
         entity.setDirectAccessGrantsEnabled(directAccessGrantsEnabled);
     }
 
     @Override
     public boolean isServiceAccountsEnabled() {
-        return entity.isServiceAccountsEnabled();
+        return getEntity().isServiceAccountsEnabled();
     }
 
     @Override
     public void setServiceAccountsEnabled(boolean serviceAccountsEnabled) {
+        getEntity.invalidate();
         entity.setServiceAccountsEnabled(serviceAccountsEnabled);
     }
 
@@ -674,7 +714,7 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
 
     @Override
     public List<String> getDefaultRoles() {
-        Collection<RoleEntity> entities = entity.getDefaultRoles();
+        Collection<RoleEntity> entities = getEntity().getDefaultRoles();
         List<String> roles = new ArrayList<String>();
         if (entities == null) return roles;
         for (RoleEntity entity : entities) {
@@ -689,7 +729,7 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
         if (role == null) {
             role = addRole(name);
         }
-        Collection<RoleEntity> entities = entity.getDefaultRoles();
+        Collection<RoleEntity> entities = getEntity().getDefaultRoles();
         for (RoleEntity entity : entities) {
             if (entity.getId().equals(role.getId())) {
                 return;
@@ -701,6 +741,7 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
 
     @Override
     public void updateDefaultRoles(String... defaultRoles) {
+        getEntity.invalidate();
         Collection<RoleEntity> entities = entity.getDefaultRoles();
         Set<String> already = new HashSet<String>();
         List<RoleEntity> remove = new ArrayList<>();
@@ -725,7 +766,7 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
 
     @Override
     public void removeDefaultRoles(String... defaultRoles) {
-        Collection<RoleEntity> entities = entity.getDefaultRoles();
+        Collection<RoleEntity> entities = getEntity().getDefaultRoles();
         List<RoleEntity> remove = new ArrayList<RoleEntity>();
         for (RoleEntity rel : entities) {
             if (contains(rel.getName(), defaultRoles)) {
@@ -743,17 +784,18 @@ public class ClientAdapter implements ClientModel, JpaModel<ClientEntity> {
 
     @Override
     public int getNodeReRegistrationTimeout() {
-        return entity.getNodeReRegistrationTimeout();
+        return getEntity().getNodeReRegistrationTimeout();
     }
 
     @Override
     public void setNodeReRegistrationTimeout(int timeout) {
+        getEntity.invalidate();
         entity.setNodeReRegistrationTimeout(timeout);
     }
 
     @Override
     public Map<String, Integer> getRegisteredNodes() {
-        return entity.getRegisteredNodes();
+        return getEntity().getRegisteredNodes();
     }
 
     @Override
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 13d84e8..03544a9 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
@@ -40,6 +40,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -58,13 +60,17 @@ public class ClientScopeAdapter implements ClientScopeModel, JpaModel<ClientScop
         this.entity = entity;
     }
 
+public static GetterCache<ClientScopeEntity> getEntity = new GetterCache<>("ClientScopeAdapter.getEntity");
+
     public ClientScopeEntity getEntity() {
+return getEntity.computeIfAbsent(() -> {
         return entity;
+}, 120000);
     }
 
     @Override
     public String getId() {
-        return entity.getId();
+        return getEntity().getId();
     }
 
     @Override
@@ -74,24 +80,27 @@ public class ClientScopeAdapter implements ClientScopeModel, JpaModel<ClientScop
 
     @Override
     public String getName() {
-        return entity.getName();
+        return getEntity().getName();
     }
 
     @Override
     public void setName(String name) {
+        getEntity.invalidate();
         name = KeycloakModelUtils.convertClientScopeName(name);
         entity.setName(name);
     }
 
     @Override
-    public String getDescription() { return entity.getDescription(); }
+    public String getDescription() { return getEntity().getDescription(); }
 
     @Override
-    public void setDescription(String description) { entity.setDescription(description); }
+    public void setDescription(String description) {
+getEntity.invalidate();
+     entity.setDescription(description); }
 
     @Override
     public String getProtocol() {
-        return entity.getProtocol();
+        return getEntity().getProtocol();
     }
 
     @Override
@@ -103,7 +112,7 @@ public class ClientScopeAdapter implements ClientScopeModel, JpaModel<ClientScop
     @Override
     public Set<ProtocolMapperModel> getProtocolMappers() {
         Set<ProtocolMapperModel> mappings = new HashSet<ProtocolMapperModel>();
-        for (ProtocolMapperEntity entity : this.entity.getProtocolMappers()) {
+        for (ProtocolMapperEntity entity : getEntity().getProtocolMappers()) {
             ProtocolMapperModel mapping = new ProtocolMapperModel();
             mapping.setId(entity.getId());
             mapping.setName(entity.getName());
@@ -139,7 +148,7 @@ public class ClientScopeAdapter implements ClientScopeModel, JpaModel<ClientScop
     }
 
     protected ProtocolMapperEntity getProtocolMapperEntity(String id) {
-        for (ProtocolMapperEntity entity : this.entity.getProtocolMappers()) {
+        for (ProtocolMapperEntity entity : getEntity().getProtocolMappers()) {
             if (entity.getId().equals(id)) {
                 return entity;
             }
@@ -149,7 +158,7 @@ public class ClientScopeAdapter implements ClientScopeModel, JpaModel<ClientScop
     }
 
     protected ProtocolMapperEntity getProtocolMapperEntityByName(String protocol, String name) {
-        for (ProtocolMapperEntity entity : this.entity.getProtocolMappers()) {
+        for (ProtocolMapperEntity entity : getEntity().getProtocolMappers()) {
             if (entity.getProtocol().equals(protocol) && entity.getName().equals(name)) {
                 return entity;
             }
@@ -284,6 +293,7 @@ public class ClientScopeAdapter implements ClientScopeModel, JpaModel<ClientScop
 
     @Override
     public void setAttribute(String name, String value) {
+        getEntity.invalidate();
         for (ClientScopeAttributeEntity attr : entity.getAttributes()) {
             if (attr.getName().equals(name)) {
                 attr.setValue(value);
@@ -327,7 +337,7 @@ public class ClientScopeAdapter implements ClientScopeModel, JpaModel<ClientScop
     @Override
     public Map<String, String> getAttributes() {
         Map<String, String> attrs = new HashMap<>();
-        for (ClientScopeAttributeEntity attr : entity.getAttributes()) {
+        for (ClientScopeAttributeEntity attr : getEntity().getAttributes()) {
             attrs.put(attr.getName(), attr.getValue());
         }
         return attrs;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/GroupAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/GroupAdapter.java
index 3dc7bcc..090b054 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/GroupAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/GroupAdapter.java
@@ -38,6 +38,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -54,35 +56,40 @@ public class GroupAdapter implements GroupModel , JpaModel<GroupEntity> {
         this.realm = realm;
     }
 
+public static GetterCache<GroupEntity> getEntity = new GetterCache<>("GroupAdapter.getEntity");
+
     public GroupEntity getEntity() {
+return getEntity.computeIfAbsent(() -> {
         return group;
+}, 120000);
     }
 
     @Override
     public String getId() {
-        return group.getId();
+        return getEntity().getId();
     }
 
     @Override
     public String getName() {
-        return group.getName();
+        return getEntity().getName();
     }
 
     @Override
     public void setName(String name) {
+        getEntity.invalidate();
         group.setName(name);
     }
 
     @Override
     public GroupModel getParent() {
-        GroupEntity parent = group.getParent();
+        GroupEntity parent = getEntity().getParent();
         if (parent == null) return null;
         return realm.getGroupById(parent.getId());
     }
 
     @Override
     public String getParentId() {
-        GroupEntity parent = group.getParent();
+        GroupEntity parent = getEntity().getParent();
         if (parent == null) return null;
         return parent.getId();
     }
@@ -96,6 +103,7 @@ public class GroupAdapter implements GroupModel , JpaModel<GroupEntity> {
 
     @Override
     public void setParent(GroupModel parent) {
+        getEntity.invalidate();
         if (parent == null) group.setParent(null);
         else if (parent.getId().equals(getId())) {
             return;
@@ -124,6 +132,7 @@ public class GroupAdapter implements GroupModel , JpaModel<GroupEntity> {
 
     @Override
     public Set<GroupModel> getSubGroups() {
+        getEntity.invalidate();
         TypedQuery<String> query = em.createNamedQuery("getGroupIdsByParent", String.class);
         query.setParameter("parent", group);
         List<String> ids = query.getResultList();
@@ -138,6 +147,7 @@ public class GroupAdapter implements GroupModel , JpaModel<GroupEntity> {
 
     @Override
     public void setSingleAttribute(String name, String value) {
+        getEntity.invalidate();
         boolean found = false;
         List<GroupAttributeEntity> toRemove = new ArrayList<>();
         for (GroupAttributeEntity attr : group.getAttributes()) {
@@ -186,6 +196,7 @@ public class GroupAdapter implements GroupModel , JpaModel<GroupEntity> {
 
     @Override
     public void removeAttribute(String name) {
+        getEntity.invalidate();
         Iterator<GroupAttributeEntity> it = group.getAttributes().iterator();
         while (it.hasNext()) {
             GroupAttributeEntity attr = it.next();
@@ -198,7 +209,7 @@ public class GroupAdapter implements GroupModel , JpaModel<GroupEntity> {
 
     @Override
     public String getFirstAttribute(String name) {
-        for (GroupAttributeEntity attr : group.getAttributes()) {
+        for (GroupAttributeEntity attr : getEntity().getAttributes()) {
             if (attr.getName().equals(name)) {
                 return attr.getValue();
             }
@@ -209,7 +220,7 @@ public class GroupAdapter implements GroupModel , JpaModel<GroupEntity> {
     @Override
     public List<String> getAttribute(String name) {
         List<String> result = new ArrayList<>();
-        for (GroupAttributeEntity attr : group.getAttributes()) {
+        for (GroupAttributeEntity attr : getEntity().getAttributes()) {
             if (attr.getName().equals(name)) {
                 result.add(attr.getValue());
             }
@@ -220,7 +231,7 @@ public class GroupAdapter implements GroupModel , JpaModel<GroupEntity> {
     @Override
     public Map<String, List<String>> getAttributes() {
         MultivaluedHashMap<String, String> result = new MultivaluedHashMap<>();
-        for (GroupAttributeEntity attr : group.getAttributes()) {
+        for (GroupAttributeEntity attr : getEntity().getAttributes()) {
             result.add(attr.getName(), attr.getValue());
         }
         return result;
@@ -283,6 +294,7 @@ public class GroupAdapter implements GroupModel , JpaModel<GroupEntity> {
 
     @Override
     public void deleteRoleMapping(RoleModel role) {
+        getEntity.invalidate();
         if (group == null || role == null) return;
 
         TypedQuery<GroupRoleMappingEntity> query = getGroupRoleMappingEntityTypedQuery(role);
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index f5e45cf..3255270 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -36,6 +36,8 @@ import java.util.stream.Collectors;
 
 import static java.util.Objects.nonNull;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -54,22 +56,27 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
         this.realm = realm;
     }
 
+public static GetterCache<RealmEntity> getEntity = new GetterCache<>("RealmAdapter.getEntity");
+
     public RealmEntity getEntity() {
+return getEntity.computeIfAbsent(() -> {
         return realm;
+}, 120000);
     }
 
     @Override
     public String getId() {
-        return realm.getId();
+        return getEntity().getId();
     }
 
     @Override
     public String getName() {
-        return realm.getName();
+        return getEntity().getName();
     }
 
     @Override
     public void setName(String name) {
+        getEntity.invalidate();
         realm.setName(name);
         em.flush();
     }
@@ -81,6 +88,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void setDisplayName(String displayName) {
+        getEntity.invalidate();
         setAttribute(RealmAttributes.DISPLAY_NAME, displayName);
     }
 
@@ -91,60 +99,66 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void setDisplayNameHtml(String displayNameHtml) {
+        getEntity.invalidate();
         setAttribute(RealmAttributes.DISPLAY_NAME_HTML, displayNameHtml);
     }
 
     @Override
     public boolean isEnabled() {
-        return realm.isEnabled();
+        return getEntity().isEnabled();
     }
 
     @Override
     public void setEnabled(boolean enabled) {
+        getEntity.invalidate();
         realm.setEnabled(enabled);
         em.flush();
     }
 
     @Override
     public SslRequired getSslRequired() {
-        return realm.getSslRequired() != null ? SslRequired.valueOf(realm.getSslRequired()) : null;
+        return getEntity().getSslRequired() != null ? SslRequired.valueOf(getEntity().getSslRequired()) : null;
     }
 
     @Override
     public void setSslRequired(SslRequired sslRequired) {
+        getEntity.invalidate();
         realm.setSslRequired(sslRequired.name());
         em.flush();
     }
 
     @Override
     public boolean isUserManagedAccessAllowed() {
-        return realm.isAllowUserManagedAccess();
+        return getEntity().isAllowUserManagedAccess();
     }
 
     @Override
     public void setUserManagedAccessAllowed(boolean userManagedAccessAllowed) {
+        getEntity.invalidate();
         realm.setAllowUserManagedAccess(userManagedAccessAllowed);
         em.flush();
     }
 
     @Override
     public boolean isRegistrationAllowed() {
-        return realm.isRegistrationAllowed();
+        return getEntity().isRegistrationAllowed();
     }
 
     @Override
     public void setRegistrationAllowed(boolean registrationAllowed) {
+        getEntity.invalidate();
         realm.setRegistrationAllowed(registrationAllowed);
         em.flush();
     }
 
     @Override
     public boolean isRegistrationEmailAsUsername() {
-        return realm.isRegistrationEmailAsUsername();
+        return getEntity().isRegistrationEmailAsUsername();
     }
 
     @Override
     public void setRegistrationEmailAsUsername(boolean registrationEmailAsUsername) {
+        getEntity.invalidate();
         realm.setRegistrationEmailAsUsername(registrationEmailAsUsername);
         if (registrationEmailAsUsername) realm.setDuplicateEmailsAllowed(false);
         em.flush();
@@ -152,17 +166,19 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public boolean isRememberMe() {
-        return realm.isRememberMe();
+        return getEntity().isRememberMe();
     }
 
     @Override
     public void setRememberMe(boolean rememberMe) {
+        getEntity.invalidate();
         realm.setRememberMe(rememberMe);
         em.flush();
     }
 
     @Override
     public void setAttribute(String name, String value) {
+        getEntity.invalidate();
         for (RealmAttributeEntity attr : realm.getAttributes()) {
             if (attr.getName().equals(name)) {
                 attr.setValue(value);
@@ -194,6 +210,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void removeAttribute(String name) {
+        getEntity.invalidate();
         Iterator<RealmAttributeEntity> it = realm.getAttributes().iterator();
         while (it.hasNext()) {
             RealmAttributeEntity attr = it.next();
@@ -206,7 +223,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public String getAttribute(String name) {
-        for (RealmAttributeEntity attr : realm.getAttributes()) {
+        for (RealmAttributeEntity attr : getEntity().getAttributes()) {
             if (attr.getName().equals(name)) {
                 return attr.getValue();
             }
@@ -239,7 +256,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
     public Map<String, String> getAttributes() {
         // should always return a copy
         Map<String, String> result = new HashMap<String, String>();
-        for (RealmAttributeEntity attr : realm.getAttributes()) {
+        for (RealmAttributeEntity attr : getEntity().getAttributes()) {
             result.put(attr.getName(), attr.getValue());
         }
         return result;
@@ -337,22 +354,24 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public boolean isVerifyEmail() {
-        return realm.isVerifyEmail();
+        return getEntity().isVerifyEmail();
     }
 
     @Override
     public void setVerifyEmail(boolean verifyEmail) {
+        getEntity.invalidate();
         realm.setVerifyEmail(verifyEmail);
         em.flush();
     }
 
     @Override
     public boolean isLoginWithEmailAllowed() {
-        return realm.isLoginWithEmailAllowed();
+        return getEntity().isLoginWithEmailAllowed();
     }
 
     @Override
     public void setLoginWithEmailAllowed(boolean loginWithEmailAllowed) {
+        getEntity.invalidate();
         realm.setLoginWithEmailAllowed(loginWithEmailAllowed);
         if (loginWithEmailAllowed) realm.setDuplicateEmailsAllowed(false);
         em.flush();
@@ -360,11 +379,12 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public boolean isDuplicateEmailsAllowed() {
-        return realm.isDuplicateEmailsAllowed();
+        return getEntity().isDuplicateEmailsAllowed();
     }
 
     @Override
     public void setDuplicateEmailsAllowed(boolean duplicateEmailsAllowed) {
+        getEntity.invalidate();
         realm.setDuplicateEmailsAllowed(duplicateEmailsAllowed);
         if (duplicateEmailsAllowed) {
             realm.setLoginWithEmailAllowed(false);
@@ -375,124 +395,136 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public boolean isResetPasswordAllowed() {
-        return realm.isResetPasswordAllowed();
+        return getEntity().isResetPasswordAllowed();
     }
 
     @Override
     public void setResetPasswordAllowed(boolean resetPasswordAllowed) {
+        getEntity.invalidate();
         realm.setResetPasswordAllowed(resetPasswordAllowed);
         em.flush();
     }
 
     @Override
     public boolean isEditUsernameAllowed() {
-        return realm.isEditUsernameAllowed();
+        return getEntity().isEditUsernameAllowed();
     }
 
     @Override
     public void setEditUsernameAllowed(boolean editUsernameAllowed) {
+        getEntity.invalidate();
         realm.setEditUsernameAllowed(editUsernameAllowed);
         em.flush();
     }
 
     @Override
     public int getNotBefore() {
-        return realm.getNotBefore();
+        return getEntity().getNotBefore();
     }
 
     @Override
     public void setNotBefore(int notBefore) {
+        getEntity.invalidate();
         realm.setNotBefore(notBefore);
     }
 
     @Override
     public boolean isRevokeRefreshToken() {
-        return realm.isRevokeRefreshToken();
+        return getEntity().isRevokeRefreshToken();
     }
 
     @Override
     public void setRevokeRefreshToken(boolean revokeRefreshToken) {
+        getEntity.invalidate();
         realm.setRevokeRefreshToken(revokeRefreshToken);
     }
 
     @Override
     public int getRefreshTokenMaxReuse() {
-        return realm.getRefreshTokenMaxReuse();
+        return getEntity().getRefreshTokenMaxReuse();
     }
 
     @Override
     public void setRefreshTokenMaxReuse(int revokeRefreshTokenReuseCount) {
+        getEntity.invalidate();
         realm.setRefreshTokenMaxReuse(revokeRefreshTokenReuseCount);
     }
 
     @Override
     public int getAccessTokenLifespan() {
-        return realm.getAccessTokenLifespan();
+        return getEntity().getAccessTokenLifespan();
     }
 
     @Override
     public void setAccessTokenLifespan(int tokenLifespan) {
+        getEntity.invalidate();
         realm.setAccessTokenLifespan(tokenLifespan);
         em.flush();
     }
 
     @Override
     public int getAccessTokenLifespanForImplicitFlow() {
-        return realm.getAccessTokenLifespanForImplicitFlow();
+        return getEntity().getAccessTokenLifespanForImplicitFlow();
     }
 
     @Override
     public void setAccessTokenLifespanForImplicitFlow(int seconds) {
+        getEntity.invalidate();
         realm.setAccessTokenLifespanForImplicitFlow(seconds);
     }
 
     @Override
     public int getSsoSessionIdleTimeout() {
-        return realm.getSsoSessionIdleTimeout();
+        return getEntity().getSsoSessionIdleTimeout();
     }
 
     @Override
     public void setSsoSessionIdleTimeout(int seconds) {
+        getEntity.invalidate();
         realm.setSsoSessionIdleTimeout(seconds);
     }
 
     @Override
     public int getSsoSessionMaxLifespan() {
-        return realm.getSsoSessionMaxLifespan();
+        return getEntity().getSsoSessionMaxLifespan();
     }
 
     @Override
     public void setSsoSessionMaxLifespan(int seconds) {
+        getEntity.invalidate();
         realm.setSsoSessionMaxLifespan(seconds);
     }
 
     @Override
     public int getSsoSessionIdleTimeoutRememberMe() {
-        return realm.getSsoSessionIdleTimeoutRememberMe();
+        return getEntity().getSsoSessionIdleTimeoutRememberMe();
     }
 
     @Override
     public void setSsoSessionIdleTimeoutRememberMe(int seconds){
+        getEntity.invalidate();
         realm.setSsoSessionIdleTimeoutRememberMe(seconds);
     }
 
     @Override
     public int getSsoSessionMaxLifespanRememberMe() {
-        return realm.getSsoSessionMaxLifespanRememberMe();
+        return getEntity().getSsoSessionMaxLifespanRememberMe();
     }
 
     @Override
     public void setSsoSessionMaxLifespanRememberMe(int seconds) {
+        getEntity.invalidate();
         realm.setSsoSessionMaxLifespanRememberMe(seconds);
     }
 
     @Override
     public int getOfflineSessionIdleTimeout() {
-        return realm.getOfflineSessionIdleTimeout();
+        return getEntity().getOfflineSessionIdleTimeout();
     }
 
     @Override
     public void setOfflineSessionIdleTimeout(int seconds) {
+        getEntity.invalidate();
         realm.setOfflineSessionIdleTimeout(seconds);
     }
 
@@ -519,22 +551,24 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public int getAccessCodeLifespan() {
-        return realm.getAccessCodeLifespan();
+        return getEntity().getAccessCodeLifespan();
     }
 
     @Override
     public void setAccessCodeLifespan(int accessCodeLifespan) {
+        getEntity.invalidate();
         realm.setAccessCodeLifespan(accessCodeLifespan);
         em.flush();
     }
 
     @Override
     public int getAccessCodeLifespanUserAction() {
-        return realm.getAccessCodeLifespanUserAction();
+        return getEntity().getAccessCodeLifespanUserAction();
     }
 
     @Override
     public void setAccessCodeLifespanUserAction(int accessCodeLifespanUserAction) {
+        getEntity.invalidate();
         realm.setAccessCodeLifespanUserAction(accessCodeLifespanUserAction);
         em.flush();
     }
@@ -555,11 +589,12 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public int getAccessCodeLifespanLogin() {
-        return realm.getAccessCodeLifespanLogin();
+        return getEntity().getAccessCodeLifespanLogin();
     }
 
     @Override
     public void setAccessCodeLifespanLogin(int accessCodeLifespanLogin) {
+        getEntity.invalidate();
         realm.setAccessCodeLifespanLogin(accessCodeLifespanLogin);
         em.flush();
     }
@@ -605,12 +640,14 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void addRequiredCredential(String type) {
+        getEntity.invalidate();
         RequiredCredentialModel model = initRequiredCredentialModel(type);
         addRequiredCredential(model);
         em.flush();
     }
 
     public void addRequiredCredential(RequiredCredentialModel model) {
+        getEntity.invalidate();
         RequiredCredentialEntity entity = new RequiredCredentialEntity();
         entity.setRealm(realm);
         entity.setInput(model.isInput());
@@ -624,6 +661,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void updateRequiredCredentials(Set<String> creds) {
+        getEntity.invalidate();
         Collection<RequiredCredentialEntity> relationships = realm.getRequiredCredentials();
         if (relationships == null) relationships = new ArrayList<RequiredCredentialEntity>();
 
@@ -651,7 +689,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public List<RequiredCredentialModel> getRequiredCredentials() {
-        Collection<RequiredCredentialEntity> entities = realm.getRequiredCredentials();
+        Collection<RequiredCredentialEntity> entities = getEntity().getRequiredCredentials();
         if (entities == null) return Collections.EMPTY_LIST;
         List<RequiredCredentialModel> requiredCredentialModels = new LinkedList<>();
         for (RequiredCredentialEntity entity : entities) {
@@ -668,7 +706,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public List<String> getDefaultRoles() {
-        Collection<RoleEntity> entities = realm.getDefaultRoles();
+        Collection<RoleEntity> entities = getEntity().getDefaultRoles();
         if (entities == null || entities.isEmpty()) return Collections.emptyList();
         List<String> roles = new LinkedList<>();
         for (RoleEntity entity : entities) {
@@ -679,6 +717,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void addDefaultRole(String name) {
+        getEntity.invalidate();
         RoleModel role = getRole(name);
         if (role == null) {
             role = addRole(name);
@@ -703,6 +742,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void updateDefaultRoles(String[] defaultRoles) {
+        getEntity.invalidate();
         Collection<RoleEntity> entities = realm.getDefaultRoles();
         Set<String> already = new HashSet<String>();
         List<RoleEntity> remove = new ArrayList<RoleEntity>();
@@ -727,6 +767,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void removeDefaultRoles(String... defaultRoles) {
+        getEntity.invalidate();
         Collection<RoleEntity> entities = realm.getDefaultRoles();
         List<RoleEntity> remove = new ArrayList<RoleEntity>();
         for (RoleEntity rel : entities) {
@@ -742,7 +783,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public List<GroupModel> getDefaultGroups() {
-        Collection<GroupEntity> entities = realm.getDefaultGroups();
+        Collection<GroupEntity> entities = getEntity().getDefaultGroups();
         if (entities == null || entities.isEmpty()) return Collections.EMPTY_LIST;
         List<GroupModel> defaultGroups = new LinkedList<>();
         for (GroupEntity entity : entities) {
@@ -753,6 +794,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void addDefaultGroup(GroupModel group) {
+        getEntity.invalidate();
         Collection<GroupEntity> entities = realm.getDefaultGroups();
         for (GroupEntity entity : entities) {
             if (entity.getId().equals(group.getId())) return;
@@ -765,6 +807,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void removeDefaultGroup(GroupModel group) {
+        getEntity.invalidate();
         GroupEntity found = null;
         for (GroupEntity defaultGroup : realm.getDefaultGroups()) {
             if (defaultGroup.getId().equals(group.getId())) {
@@ -837,12 +880,13 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
     @Override
     public Map<String, String> getSmtpConfig() {
         Map<String, String> config = new HashMap<String, String>();
-        config.putAll(realm.getSmtpConfig());
+        config.putAll(getEntity().getSmtpConfig());
         return Collections.unmodifiableMap(config);
     }
 
     @Override
     public void setSmtpConfig(Map<String, String> smtpConfig) {
+        getEntity.invalidate();
         realm.setSmtpConfig(smtpConfig);
         em.flush();
     }
@@ -881,13 +925,14 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
     @Override
     public PasswordPolicy getPasswordPolicy() {
         if (passwordPolicy == null) {
-            passwordPolicy = PasswordPolicy.parse(session, realm.getPasswordPolicy());
+            passwordPolicy = PasswordPolicy.parse(session, getEntity().getPasswordPolicy());
         }
         return passwordPolicy;
     }
 
     @Override
     public void setPasswordPolicy(PasswordPolicy policy) {
+        getEntity.invalidate();
         this.passwordPolicy = policy;
         realm.setPasswordPolicy(policy.toString());
         em.flush();
@@ -895,6 +940,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public OTPPolicy getOTPPolicy() {
+        getEntity.invalidate();
         if (otpPolicy == null) {
             otpPolicy = new OTPPolicy();
             otpPolicy.setDigits(realm.getOtpPolicyDigits());
@@ -909,6 +955,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void setOTPPolicy(OTPPolicy policy) {
+        getEntity.invalidate();
         realm.setOtpPolicyAlgorithm(policy.getAlgorithm());
         realm.setOtpPolicyDigits(policy.getDigits());
         realm.setOtpPolicyInitialCounter(policy.getInitialCounter());
@@ -935,73 +982,79 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public String getLoginTheme() {
-        return realm.getLoginTheme();
+        return getEntity().getLoginTheme();
     }
 
     @Override
     public void setLoginTheme(String name) {
+        getEntity.invalidate();
         realm.setLoginTheme(name);
         em.flush();
     }
 
     @Override
     public String getAccountTheme() {
-        return realm.getAccountTheme();
+        return getEntity().getAccountTheme();
     }
 
     @Override
     public void setAccountTheme(String name) {
+        getEntity.invalidate();
         realm.setAccountTheme(name);
         em.flush();
     }
 
     @Override
     public String getAdminTheme() {
-        return realm.getAdminTheme();
+        return getEntity().getAdminTheme();
     }
 
     @Override
     public void setAdminTheme(String name) {
+        getEntity.invalidate();
         realm.setAdminTheme(name);
         em.flush();
     }
 
     @Override
     public String getEmailTheme() {
-        return realm.getEmailTheme();
+        return getEntity().getEmailTheme();
     }
 
     @Override
     public void setEmailTheme(String name) {
+        getEntity.invalidate();
         realm.setEmailTheme(name);
         em.flush();
     }
 
     @Override
     public boolean isEventsEnabled() {
-        return realm.isEventsEnabled();
+        return getEntity().isEventsEnabled();
     }
 
     @Override
     public void setEventsEnabled(boolean enabled) {
+        getEntity.invalidate();
         realm.setEventsEnabled(enabled);
         em.flush();
     }
 
     @Override
     public long getEventsExpiration() {
-        return realm.getEventsExpiration();
+        return getEntity().getEventsExpiration();
     }
 
     @Override
     public void setEventsExpiration(long expiration) {
+        getEntity.invalidate();
         realm.setEventsExpiration(expiration);
         em.flush();
     }
 
     @Override
     public Set<String> getEventsListeners() {
-        Set<String> eventsListeners = realm.getEventsListeners();
+        Set<String> eventsListeners = getEntity().getEventsListeners();
         if (eventsListeners.isEmpty()) return Collections.EMPTY_SET;
         Set<String> copy = new HashSet<>();
         copy.addAll(eventsListeners);
@@ -1010,13 +1063,14 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void setEventsListeners(Set<String> listeners) {
+        getEntity.invalidate();
         realm.setEventsListeners(listeners);
         em.flush();
     }
 
     @Override
     public Set<String> getEnabledEventTypes() {
-        Set<String> enabledEventTypes = realm.getEnabledEventTypes();
+        Set<String> enabledEventTypes = getEntity().getEnabledEventTypes();
         if (enabledEventTypes.isEmpty()) return Collections.EMPTY_SET;
         Set<String> copy = new HashSet<>();
         copy.addAll(enabledEventTypes);
@@ -1025,34 +1079,38 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void setEnabledEventTypes(Set<String> enabledEventTypes) {
+        getEntity.invalidate();
         realm.setEnabledEventTypes(enabledEventTypes);
         em.flush();
     }
 
     @Override
     public boolean isAdminEventsEnabled() {
-        return realm.isAdminEventsEnabled();
+        return getEntity().isAdminEventsEnabled();
     }
 
     @Override
     public void setAdminEventsEnabled(boolean enabled) {
+        getEntity.invalidate();
         realm.setAdminEventsEnabled(enabled);
         em.flush();
     }
 
     @Override
     public boolean isAdminEventsDetailsEnabled() {
-        return realm.isAdminEventsDetailsEnabled();
+        return getEntity().isAdminEventsDetailsEnabled();
     }
 
     @Override
     public void setAdminEventsDetailsEnabled(boolean enabled) {
+        getEntity.invalidate();
         realm.setAdminEventsDetailsEnabled(enabled);
         em.flush();
     }
 
     @Override
     public ClientModel getMasterAdminClient() {
+        getEntity.invalidate();
         ClientEntity masterAdminClient = realm.getMasterAdminClient();
         if (masterAdminClient == null) {
             return null;
@@ -1069,6 +1127,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void setMasterAdminClient(ClientModel client) {
+        getEntity.invalidate();
         ClientEntity appEntity = client !=null ? em.getReference(ClientEntity.class, client.getId()) : null;
         realm.setMasterAdminClient(appEntity);
         em.flush();
@@ -1076,7 +1135,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public List<IdentityProviderModel> getIdentityProviders() {
-        List<IdentityProviderEntity> entities = realm.getIdentityProviders();
+        List<IdentityProviderEntity> entities = getEntity().getIdentityProviders();
         if (entities.isEmpty()) return Collections.EMPTY_LIST;
         List<IdentityProviderModel> identityProviders = new ArrayList<IdentityProviderModel>();
 
@@ -1124,6 +1183,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void addIdentityProvider(IdentityProviderModel identityProvider) {
+        getEntity.invalidate();
         IdentityProviderEntity entity = new IdentityProviderEntity();
 
         if (identityProvider.getInternalId() == null) {
@@ -1154,6 +1214,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void removeIdentityProviderByAlias(String alias) {
+        getEntity.invalidate();
         for (IdentityProviderEntity entity : realm.getIdentityProviders()) {
             if (entity.getAlias().equals(alias)) {
 
@@ -1185,6 +1246,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void updateIdentityProvider(IdentityProviderModel identityProvider) {
+        getEntity.invalidate();
         for (IdentityProviderEntity entity : this.realm.getIdentityProviders()) {
             if (entity.getInternalId().equals(identityProvider.getInternalId())) {
                 entity.setAlias(identityProvider.getAlias());
@@ -1224,23 +1286,24 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public boolean isIdentityFederationEnabled() {
-        return !this.realm.getIdentityProviders().isEmpty();
+        return !getEntity().getIdentityProviders().isEmpty();
     }
 
     @Override
     public boolean isInternationalizationEnabled() {
-        return realm.isInternationalizationEnabled();
+        return getEntity().isInternationalizationEnabled();
     }
 
     @Override
     public void setInternationalizationEnabled(boolean enabled) {
+        getEntity.invalidate();
         realm.setInternationalizationEnabled(enabled);
         em.flush();
     }
 
     @Override
     public Set<String> getSupportedLocales() {
-        Set<String> supportedLocales = realm.getSupportedLocales();
+        Set<String> supportedLocales = getEntity().getSupportedLocales();
         if (supportedLocales == null || supportedLocales.isEmpty()) return Collections.EMPTY_SET;
         Set<String> copy = new HashSet<>();
         copy.addAll(supportedLocales);
@@ -1249,24 +1312,26 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void setSupportedLocales(Set<String> locales) {
+        getEntity.invalidate();
         realm.setSupportedLocales(locales);
         em.flush();
     }
 
     @Override
     public String getDefaultLocale() {
-        return realm.getDefaultLocale();
+        return getEntity().getDefaultLocale();
     }
 
     @Override
     public void setDefaultLocale(String locale) {
+        getEntity.invalidate();
         realm.setDefaultLocale(locale);
         em.flush();
     }
 
     @Override
     public Set<IdentityProviderMapperModel> getIdentityProviderMappers() {
-        Collection<IdentityProviderMapperEntity> entities = this.realm.getIdentityProviderMappers();
+        Collection<IdentityProviderMapperEntity> entities = getEntity().getIdentityProviderMappers();
         if (entities.isEmpty()) return Collections.EMPTY_SET;
         Set<IdentityProviderMapperModel> mappings = new HashSet<IdentityProviderMapperModel>();
         for (IdentityProviderMapperEntity entity : entities) {
@@ -1279,7 +1344,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
     @Override
     public Set<IdentityProviderMapperModel> getIdentityProviderMappersByAlias(String brokerAlias) {
         Set<IdentityProviderMapperModel> mappings = new HashSet<IdentityProviderMapperModel>();
-        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
+        for (IdentityProviderMapperEntity entity : getEntity().getIdentityProviderMappers()) {
             if (!entity.getIdentityProviderAlias().equals(brokerAlias)) {
                 continue;
             }
@@ -1291,6 +1356,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public IdentityProviderMapperModel addIdentityProviderMapper(IdentityProviderMapperModel model) {
+        getEntity.invalidate();
         if (getIdentityProviderMapperByName(model.getIdentityProviderAlias(), model.getName()) != null) {
             throw new RuntimeException("identity provider mapper name must be unique per identity provider");
         }
@@ -1309,7 +1375,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
     }
 
     protected IdentityProviderMapperEntity getIdentityProviderMapperEntity(String id) {
-        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
+        for (IdentityProviderMapperEntity entity : getEntity().getIdentityProviderMappers()) {
             if (entity.getId().equals(id)) {
                 return entity;
             }
@@ -1319,7 +1385,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
     }
 
     protected IdentityProviderMapperEntity getIdentityProviderMapperEntityByName(String alias, String name) {
-        for (IdentityProviderMapperEntity entity : this.realm.getIdentityProviderMappers()) {
+        for (IdentityProviderMapperEntity entity : getEntity().getIdentityProviderMappers()) {
             if (entity.getIdentityProviderAlias().equals(alias) && entity.getName().equals(name)) {
                 return entity;
             }
@@ -1330,6 +1396,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public void removeIdentityProviderMapper(IdentityProviderMapperModel mapping) {
+        getEntity.invalidate();
         IdentityProviderMapperEntity toDelete = getIdentityProviderMapperEntity(mapping.getId());
         if (toDelete != null) {
             this.realm.getIdentityProviderMappers().remove(toDelete);
@@ -1381,80 +1448,86 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public AuthenticationFlowModel getBrowserFlow() {
-        String flowId = realm.getBrowserFlow();
+        String flowId = getEntity().getBrowserFlow();
         if (flowId == null) return null;
         return getAuthenticationFlowById(flowId);
     }
 
     @Override
     public void setBrowserFlow(AuthenticationFlowModel flow) {
+        getEntity.invalidate();
         realm.setBrowserFlow(flow.getId());
 
     }
 
     @Override
     public AuthenticationFlowModel getRegistrationFlow() {
-        String flowId = realm.getRegistrationFlow();
+        String flowId = getEntity().getRegistrationFlow();
         if (flowId == null) return null;
         return getAuthenticationFlowById(flowId);
     }
 
     @Override
     public void setRegistrationFlow(AuthenticationFlowModel flow) {
+        getEntity.invalidate();
         realm.setRegistrationFlow(flow.getId());
 
     }
 
     @Override
     public AuthenticationFlowModel getDirectGrantFlow() {
-        String flowId = realm.getDirectGrantFlow();
+        String flowId = getEntity().getDirectGrantFlow();
         if (flowId == null) return null;
         return getAuthenticationFlowById(flowId);
     }
 
     @Override
     public void setDirectGrantFlow(AuthenticationFlowModel flow) {
+        getEntity.invalidate();
         realm.setDirectGrantFlow(flow.getId());
 
     }
 
     @Override
     public AuthenticationFlowModel getResetCredentialsFlow() {
-        String flowId = realm.getResetCredentialsFlow();
+        String flowId = getEntity().getResetCredentialsFlow();
         if (flowId == null) return null;
         return getAuthenticationFlowById(flowId);
     }
 
     @Override
     public void setResetCredentialsFlow(AuthenticationFlowModel flow) {
+        getEntity.invalidate();
         realm.setResetCredentialsFlow(flow.getId());
     }
 
     public AuthenticationFlowModel getClientAuthenticationFlow() {
-        String flowId = realm.getClientAuthenticationFlow();
+        String flowId = getEntity().getClientAuthenticationFlow();
         if (flowId == null) return null;
         return getAuthenticationFlowById(flowId);
     }
 
     public void setClientAuthenticationFlow(AuthenticationFlowModel flow) {
+        getEntity.invalidate();
         realm.setClientAuthenticationFlow(flow.getId());
     }
 
     @Override
     public AuthenticationFlowModel getDockerAuthenticationFlow() {
-        String flowId = realm.getDockerAuthenticationFlow();
+        String flowId = getEntity().getDockerAuthenticationFlow();
         if (flowId == null) return null;
         return getAuthenticationFlowById(flowId);
     }
 
     @Override
     public void setDockerAuthenticationFlow(AuthenticationFlowModel flow) {
+        getEntity.invalidate();
         realm.setDockerAuthenticationFlow(flow.getId());
     }
 
     @Override
     public List<AuthenticationFlowModel> getAuthenticationFlows() {
-        return realm.getAuthenticationFlows().stream()
+        return getEntity().getAuthenticationFlows().stream()
                 .map(this::entityToModel)
                 .collect(Collectors.collectingAndThen(
                         Collectors.toList(), Collections::unmodifiableList));
@@ -1523,6 +1596,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public AuthenticationFlowModel addAuthenticationFlow(AuthenticationFlowModel model) {
+        getEntity.invalidate();
         AuthenticationFlowEntity entity = new AuthenticationFlowEntity();
         String id = (model.getId() == null) ? KeycloakModelUtils.generateId(): model.getId();
         entity.setId(id);
@@ -1572,6 +1646,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public AuthenticationExecutionModel addAuthenticatorExecution(AuthenticationExecutionModel model) {
+        getEntity.invalidate();
         AuthenticationExecutionEntity entity = new AuthenticationExecutionEntity();
         String id = (model.getId() == null) ? KeycloakModelUtils.generateId(): model.getId();
         entity.setId(id);
@@ -1615,6 +1690,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public AuthenticatorConfigModel addAuthenticatorConfig(AuthenticatorConfigModel model) {
+        getEntity.invalidate();
         AuthenticatorConfigEntity auth = new AuthenticatorConfigEntity();
         String id = (model.getId() == null) ? KeycloakModelUtils.generateId(): model.getId();
         auth.setId(id);
@@ -1670,7 +1746,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public List<AuthenticatorConfigModel> getAuthenticatorConfigs() {
-        Collection<AuthenticatorConfigEntity> entities = realm.getAuthenticatorConfigs();
+        Collection<AuthenticatorConfigEntity> entities = getEntity().getAuthenticatorConfigs();
         if (entities.isEmpty()) return Collections.EMPTY_LIST;
         List<AuthenticatorConfigModel> authenticators = new LinkedList<>();
         for (AuthenticatorConfigEntity entity : entities) {
@@ -1681,6 +1757,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public RequiredActionProviderModel addRequiredActionProvider(RequiredActionProviderModel model) {
+        getEntity.invalidate();
         RequiredActionProviderEntity auth = new RequiredActionProviderEntity();
         String id = (model.getId() == null) ? KeycloakModelUtils.generateId(): model.getId();
         auth.setId(id);
@@ -1752,7 +1829,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public List<RequiredActionProviderModel> getRequiredActionProviders() {
-        Collection<RequiredActionProviderEntity> entities = realm.getRequiredActionProviders();
+        Collection<RequiredActionProviderEntity> entities = getEntity().getRequiredActionProviders();
         if (entities.isEmpty()) return Collections.EMPTY_LIST;
         List<RequiredActionProviderModel> actions = new LinkedList<>();
         for (RequiredActionProviderEntity entity : entities) {
@@ -1827,7 +1904,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public List<ClientScopeModel> getClientScopes() {
-        Collection<ClientScopeEntity> entities = realm.getClientScopes();
+        Collection<ClientScopeEntity> entities = getEntity().getClientScopes();
         if (entities == null || entities.isEmpty()) return Collections.EMPTY_LIST;
         List<ClientScopeModel> list = new LinkedList<>();
         for (ClientScopeEntity entity : entities) {
@@ -1843,6 +1920,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public ClientScopeModel addClientScope(String id, String name) {
+        getEntity.invalidate();
         ClientScopeEntity entity = new ClientScopeEntity();
         entity.setId(id);
         name = KeycloakModelUtils.convertClientScopeName(name);
@@ -1858,6 +1936,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public boolean removeClientScope(String id) {
+        getEntity.invalidate();
         if (id == null) return false;
         ClientScopeModel clientScope = getClientScopeById(id);
         if (clientScope == null) return false;
@@ -1947,6 +2026,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public ComponentModel importComponentModel(ComponentModel model) {
+        getEntity.invalidate();
         ComponentFactory componentFactory = null;
         try {
             componentFactory = ComponentUtil.getComponentFactory(session, model);
@@ -2051,7 +2131,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
         if (parentId == null) parentId = getId();
         final String parent = parentId;
 
-        return realm.getComponents().stream()
+        return getEntity().getComponents().stream()
                 .filter(c -> parent.equals(c.getParentId())
                         && providerType.equals(c.getProviderType()))
                 .map(this::entityToModel)
@@ -2060,7 +2140,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public List<ComponentModel> getComponents(final String parentId) {
-        return realm.getComponents().stream()
+        return getEntity().getComponents().stream()
                 .filter(c -> parentId.equals(c.getParentId()))
                 .map(this::entityToModel)
                 .collect(Collectors.toList());
@@ -2084,7 +2164,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
 
     @Override
     public List<ComponentModel> getComponents() {
-        return realm.getComponents().stream().map(this::entityToModel).collect(Collectors.toList());
+        return getEntity().getComponents().stream().map(this::entityToModel).collect(Collectors.toList());
     }
 
     @Override
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
index eb10c37..f06101d 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RoleAdapter.java
@@ -36,6 +36,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -53,36 +55,43 @@ public class RoleAdapter implements RoleModel, JpaModel<RoleEntity> {
         this.session = session;
     }
 
+public static GetterCache<RoleEntity> getEntity = new GetterCache<>("RoleAdapter.getEntity");
+
     public RoleEntity getEntity() {
+return getEntity.computeIfAbsent(() -> {
         return role;
+}, 120000);
     }
 
     public void setRole(RoleEntity role) {
+        getEntity.invalidate();
         this.role = role;
     }
 
     @Override
     public String getName() {
-        return role.getName();
+        return getEntity().getName();
     }
 
     @Override
     public String getDescription() {
-        return role.getDescription();
+        return getEntity().getDescription();
     }
 
     @Override
     public void setDescription(String description) {
+        getEntity.invalidate();
         role.setDescription(description);
     }
 
     @Override
     public String getId() {
-        return role.getId();
+        return getEntity().getId();
     }
 
     @Override
     public void setName(String name) {
+        getEntity.invalidate();
         role.setName(name);
     }
 
@@ -93,6 +102,7 @@ public class RoleAdapter implements RoleModel, JpaModel<RoleEntity> {
 
     @Override
     public void addCompositeRole(RoleModel role) {
+        getEntity.invalidate();
         RoleEntity entity = RoleAdapter.toRoleEntity(role, em);
         for (RoleEntity composite : getEntity().getCompositeRoles()) {
             if (composite.equals(entity)) return;
@@ -102,6 +112,7 @@ public class RoleAdapter implements RoleModel, JpaModel<RoleEntity> {
 
     @Override
     public void removeCompositeRole(RoleModel role) {
+        getEntity.invalidate();
         RoleEntity entity = RoleAdapter.toRoleEntity(role, em);
         getEntity().getCompositeRoles().remove(entity);
     }
@@ -125,6 +136,7 @@ public class RoleAdapter implements RoleModel, JpaModel<RoleEntity> {
     }
 
     private void persistAttributeValue(String name, String value) {
+        getEntity.invalidate();
         RoleAttributeEntity attr = new RoleAttributeEntity();
         attr.setId(KeycloakModelUtils.generateId());
         attr.setName(name);
@@ -150,6 +162,7 @@ public class RoleAdapter implements RoleModel, JpaModel<RoleEntity> {
 
     @Override
     public void removeAttribute(String name) {
+        getEntity.invalidate();
         Collection<RoleAttributeEntity> attributes = role.getAttributes();
         if (attributes == null) {
             return;
@@ -165,7 +178,7 @@ public class RoleAdapter implements RoleModel, JpaModel<RoleEntity> {
 
     @Override
     public String getFirstAttribute(String name) {
-        for (RoleAttributeEntity attribute : role.getAttributes()) {
+        for (RoleAttributeEntity attribute : getEntity().getAttributes()) {
             if (attribute.getName().equals(name)) {
                 return attribute.getValue();
             }
@@ -177,7 +190,7 @@ public class RoleAdapter implements RoleModel, JpaModel<RoleEntity> {
     @Override
     public List<String> getAttribute(String name) {
         List<String> attributes = new ArrayList<>();
-        for (RoleAttributeEntity attribute : role.getAttributes()) {
+        for (RoleAttributeEntity attribute : getEntity().getAttributes()) {
             if (attribute.getName().equals(name)) {
                 attributes.add(attribute.getValue());
             }
@@ -188,7 +201,7 @@ public class RoleAdapter implements RoleModel, JpaModel<RoleEntity> {
     @Override
     public Map<String, List<String>> getAttributes() {
         Map<String, List<String>> map = new HashMap<>();
-        for (RoleAttributeEntity attribute : role.getAttributes()) {
+        for (RoleAttributeEntity attribute : getEntity().getAttributes()) {
             map.computeIfAbsent(attribute.getName(), name -> new ArrayList<>()).add(attribute.getValue());
         }
 
@@ -197,20 +210,20 @@ public class RoleAdapter implements RoleModel, JpaModel<RoleEntity> {
 
     @Override
     public boolean isClientRole() {
-        return role.isClientRole();
+        return getEntity().isClientRole();
     }
 
     @Override
     public String getContainerId() {
-        if (isClientRole()) return role.getClient().getId();
+        if (isClientRole()) return getEntity().getClient().getId();
         else return realm.getId();
     }
 
 
     @Override
     public RoleContainerModel getContainer() {
-        if (role.isClientRole()) {
-            return realm.getClientById(role.getClient().getId());
+        if (getEntity().isClientRole()) {
+            return realm.getClientById(getEntity().getClient().getId());
 
         } else {
             return realm;
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
index 754229b..4ae29df 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/UserAdapter.java
@@ -52,6 +52,8 @@ import java.util.Map;
 import java.util.Set;
 import java.util.Objects;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -70,48 +72,56 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
         this.session = session;
     }
 
+public static GetterCache<UserEntity> getEntity = new GetterCache<>("UserAdapter.getEntity");
+
     public UserEntity getEntity() {
+return getEntity.computeIfAbsent(() -> {
         return user;
+}, 120000);
     }
 
     @Override
     public String getId() {
-        return user.getId();
+        return getEntity().getId();
     }
 
     @Override
     public String getUsername() {
-        return user.getUsername();
+        return getEntity().getUsername();
     }
 
     @Override
     public void setUsername(String username) {
+        getEntity.invalidate();
         username = KeycloakModelUtils.toLowerCaseSafe(username);
         user.setUsername(username);
     }
 
     @Override
     public Long getCreatedTimestamp() {
-        return user.getCreatedTimestamp();
+        return getEntity().getCreatedTimestamp();
     }
 
     @Override
     public void setCreatedTimestamp(Long timestamp) {
+        getEntity.invalidate();
         user.setCreatedTimestamp(timestamp);
     }
 
     @Override
     public boolean isEnabled() {
-        return user.isEnabled();
+        return getEntity().isEnabled();
     }
 
     @Override
     public void setEnabled(boolean enabled) {
+        getEntity.invalidate();
         user.setEnabled(enabled);
     }
 
     @Override
     public void setSingleAttribute(String name, String value) {
+        getEntity.invalidate();
         String firstExistingAttrId = null;
         List<UserAttributeEntity> toRemove = new ArrayList<>();
         for (UserAttributeEntity attr : user.getAttributes()) {
@@ -143,6 +153,7 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
 
     @Override
     public void setAttribute(String name, List<String> values) {
+        getEntity.invalidate();
         // Remove all existing
         removeAttribute(name);
 
@@ -153,6 +164,7 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
     }
 
     private void persistAttributeValue(String name, String value) {
+        getEntity.invalidate();
         UserAttributeEntity attr = new UserAttributeEntity();
         attr.setId(KeycloakModelUtils.generateId());
         attr.setName(name);
@@ -164,6 +176,7 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
 
     @Override
     public void removeAttribute(String name) {
+        getEntity.invalidate();
         // KEYCLOAK-3296 : Remove attribute through HQL to avoid StaleUpdateException
         Query query = em.createNamedQuery("deleteUserAttributesByNameAndUser");
         query.setParameter("name", name);
@@ -182,7 +195,7 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
 
     @Override
     public String getFirstAttribute(String name) {
-        for (UserAttributeEntity attr : user.getAttributes()) {
+        for (UserAttributeEntity attr : getEntity().getAttributes()) {
             if (attr.getName().equals(name)) {
                 return attr.getValue();
             }
@@ -193,7 +206,7 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
     @Override
     public List<String> getAttribute(String name) {
         List<String> result = new ArrayList<>();
-        for (UserAttributeEntity attr : user.getAttributes()) {
+        for (UserAttributeEntity attr : getEntity().getAttributes()) {
             if (attr.getName().equals(name)) {
                 result.add(attr.getValue());
             }
@@ -204,7 +217,7 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
     @Override
     public Map<String, List<String>> getAttributes() {
         MultivaluedHashMap<String, String> result = new MultivaluedHashMap<>();
-        for (UserAttributeEntity attr : user.getAttributes()) {
+        for (UserAttributeEntity attr : getEntity().getAttributes()) {
             result.add(attr.getName(), attr.getValue());
         }
         return result;
@@ -213,7 +226,7 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
     @Override
     public Set<String> getRequiredActions() {
         Set<String> result = new HashSet<>();
-        for (UserRequiredActionEntity attr : user.getRequiredActions()) {
+        for (UserRequiredActionEntity attr : getEntity().getRequiredActions()) {
             result.add(attr.getAction());
         }
         return result;
@@ -227,6 +240,7 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
 
     @Override
     public void addRequiredAction(String actionName) {
+        getEntity.invalidate();
         for (UserRequiredActionEntity attr : user.getRequiredActions()) {
             if (attr.getAction().equals(actionName)) {
                 return;
@@ -247,6 +261,7 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
 
     @Override
     public void removeRequiredAction(String actionName) {
+        getEntity.invalidate();
         Iterator<UserRequiredActionEntity> it = user.getRequiredActions().iterator();
         while (it.hasNext()) {
             UserRequiredActionEntity attr = it.next();
@@ -259,42 +274,46 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
 
     @Override
     public String getFirstName() {
-        return user.getFirstName();
+        return getEntity().getFirstName();
     }
 
     @Override
     public void setFirstName(String firstName) {
+        getEntity.invalidate();
         user.setFirstName(firstName);
     }
 
     @Override
     public String getLastName() {
-        return user.getLastName();
+        return getEntity().getLastName();
     }
 
     @Override
     public void setLastName(String lastName) {
+        getEntity.invalidate();
         user.setLastName(lastName);
     }
 
     @Override
     public String getEmail() {
-        return user.getEmail();
+        return getEntity().getEmail();
     }
 
     @Override
     public void setEmail(String email) {
+        getEntity.invalidate();
         email = KeycloakModelUtils.toLowerCaseSafe(email);
         user.setEmail(email, realm.isDuplicateEmailsAllowed());
     }
 
     @Override
     public boolean isEmailVerified() {
-        return user.isEmailVerified();
+        return getEntity().isEmailVerified();
     }
 
     @Override
     public void setEmailVerified(boolean verified) {
+        getEntity.invalidate();
         user.setEmailVerified(verified);
     }
 
@@ -389,6 +408,7 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
 
     @Override
     public void leaveGroup(GroupModel group) {
+        getEntity.invalidate();
         if (user == null || group == null) return;
 
         TypedQuery<UserGroupMembershipEntity> query = getUserGroupMappingQuery(group);
@@ -507,21 +527,23 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
 
     @Override
     public String getFederationLink() {
-        return user.getFederationLink();
+        return getEntity().getFederationLink();
     }
 
     @Override
     public void setFederationLink(String link) {
+        getEntity.invalidate();
         user.setFederationLink(link);
     }
 
     @Override
     public String getServiceAccountClientLink() {
-        return user.getServiceAccountClientLink();
+        return getEntity().getServiceAccountClientLink();
     }
 
     @Override
     public void setServiceAccountClientLink(String clientInternalId) {
+        getEntity.invalidate();
         user.setServiceAccountClientLink(clientInternalId);
     }
 

services/pom.xml 5(+5 -0)

diff --git a/services/pom.xml b/services/pom.xml
index 246e25a..af19f38 100755
--- a/services/pom.xml
+++ b/services/pom.xml
@@ -36,6 +36,11 @@
 
     <dependencies>
         <dependency>
+            <groupId>br.ufrgs.inf.prosoft.cache</groupId>
+            <artifactId>Cache</artifactId>
+            <version>1.0</version>
+        </dependency>
+        <dependency>
             <groupId>org.bouncycastle</groupId>
             <artifactId>bcprov-jdk15on</artifactId>
         </dependency>
diff --git a/services/src/main/java/org/keycloak/credential/OTPCredentialProvider.java b/services/src/main/java/org/keycloak/credential/OTPCredentialProvider.java
index f3f1ce7..f0db2dc 100644
--- a/services/src/main/java/org/keycloak/credential/OTPCredentialProvider.java
+++ b/services/src/main/java/org/keycloak/credential/OTPCredentialProvider.java
@@ -34,6 +34,8 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -44,12 +46,14 @@ public class OTPCredentialProvider implements CredentialProvider, CredentialInpu
     protected KeycloakSession session;
 
     // protected List<CredentialModel> getCachedCredentials(UserModel user, String type) {
-    //     if (!(user instanceof CachedUserModel)) return null;
-    //     CachedUserModel cached = (CachedUserModel)user;
-    //     if (cached.isMarkedForEviction()) return null;
-    //     List<CredentialModel> rtn = (List<CredentialModel>)cached.getCachedWith().get(OTPCredentialProvider.class.getName() + "." + type);
-    //     if (rtn == null) return Collections.EMPTY_LIST;
-    //     return rtn;
+// return getCachedCredentials.computeIfAbsent(new Parameters(user, type), () -> {
+        // if (!(user instanceof CachedUserModel)) return null;
+        // CachedUserModel cached = (CachedUserModel)user;
+        // if (cached.isMarkedForEviction()) return null;
+        // List<CredentialModel> rtn = (List<CredentialModel>)cached.getCachedWith().get(OTPCredentialProvider.class.getName() + "." + type);
+        // if (rtn == null) return Collections.EMPTY_LIST;
+        // return rtn;
+// }, 20000);
     // }
 
     protected UserCredentialStore getCredentialStore() {
@@ -193,11 +197,14 @@ public class OTPCredentialProvider implements CredentialProvider, CredentialInpu
         return !getCredentialStore().getStoredCredentialsByType(realm, user, CredentialModel.HOTP).isEmpty();
     }
 
+public static MultiCache<Parameters, List<CredentialModel>> getCachedCredentials = new MultiCache<>("OTPCredentialProvider.getCachedCredentials");
+
     protected boolean configuredForTOTP(RealmModel realm, UserModel user) {
-        // List<CredentialModel> cachedCredentials = getCachedCredentials(user, CredentialModel.TOTP);
+        List<CredentialModel> cachedCredentials = getCachedCredentials.computeIfAbsent(new Parameters(realm, user), () -> {
         // if (cachedCredentials == null) 
-            return !getCredentialStore().getStoredCredentialsByType(realm, user, CredentialModel.TOTP).isEmpty();
-        // return !cachedCredentials.isEmpty();
+            return getCredentialStore().getStoredCredentialsByType(realm, user, CredentialModel.TOTP);
+        }, 120000);
+        return !cachedCredentials.isEmpty();
     }
 
     public static boolean validOTP(RealmModel realm, String token, String secret) {
@@ -237,11 +244,13 @@ public class OTPCredentialProvider implements CredentialProvider, CredentialInpu
             }
         } else {
             TimeBasedOTP validator = new TimeBasedOTP(policy.getAlgorithm(), policy.getDigits(), policy.getPeriod(), policy.getLookAheadWindow());
-            List<CredentialModel> creds;// = getCachedCredentials(user, CredentialModel.TOTP);
+            List<CredentialModel> creds = getCachedCredentials.computeIfAbsent(new Parameters(realm, user), () -> { 
+            return getCredentialStore().getStoredCredentialsByType(realm, user, CredentialModel.TOTP);
+        }, 120000);
             // if (creds == null) {
-                creds = getCredentialStore().getStoredCredentialsByType(realm, user, CredentialModel.TOTP);
+                // creds = getCredentialStore().getStoredCredentialsByType(realm, user, CredentialModel.TOTP);
             // } else {
-            //     logger.debugv("Cache hit for TOTP for user {0}", user.getUsername());
+                // logger.debugv("Cache hit for TOTP for user {0}", user.getUsername());
             // }
             for (CredentialModel cred : creds) {
                 if (validator.validateTOTP(token, cred.getValue().getBytes())) {
diff --git a/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java b/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java
index 3086fd6..a4253e1 100644
--- a/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java
+++ b/services/src/main/java/org/keycloak/credential/UserCredentialStoreManager.java
@@ -37,6 +37,8 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 
+import br.ufrgs.inf.prosoft.cache.*;
+
 /**
  * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
  * @version $Revision: 1 $
@@ -82,9 +84,13 @@ public class UserCredentialStoreManager implements UserCredentialManager{//, OnU
         return getStoreForUser(user).getStoredCredentials(realm, user);
     }
 
+public static MultiCache<Parameters, List<CredentialModel>> getStoredCredentialsByType = new MultiCache<>("UserCredentialStoreManager.getStoredCredentialsByType");
+
     @Override
     public List<CredentialModel> getStoredCredentialsByType(RealmModel realm, UserModel user, String type) {
+return getStoredCredentialsByType.computeIfAbsent(new Parameters(realm, user, type), () -> {
         return getStoreForUser(user).getStoredCredentialsByType(realm, user, type);
+}, 120000);
     }
 
     @Override