You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2018/11/06 16:18:49 UTC

[syncope] 01/03: [SYNCOPE-1392] Initial removal of ReflectionUtils, and most of ReflectionToStringBuilder, EqualsBuilder and HashCodeBuilder from Core

This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git

commit 8bbfe71a3e556fb7ef57fc092dc297b65b807253
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Mon Nov 5 10:04:07 2018 +0100

    [SYNCOPE-1392] Initial removal of ReflectionUtils, and most of ReflectionToStringBuilder, EqualsBuilder and HashCodeBuilder from Core
---
 .../syncope/core/persistence/api/dao/AnyDAO.java   |  12 +-
 .../api/dao/search/AbstractSearchCond.java         |  20 --
 .../core/persistence/api/dao/search/AnyCond.java   |   7 +
 .../persistence/api/dao/search/AnyTypeCond.java    |  34 ++++
 .../persistence/api/dao/search/AssignableCond.java |  38 ++++
 .../persistence/api/dao/search/AttributeCond.java  |  41 ++++
 .../persistence/api/dao/search/DynRealmCond.java   |  35 ++++
 .../persistence/api/dao/search/MemberCond.java     |  34 ++++
 .../persistence/api/dao/search/MembershipCond.java |  35 ++++
 .../persistence/api/dao/search/OrderByClause.java  |  32 +++-
 .../persistence/api/dao/search/PrivilegeCond.java  |  35 ++++
 .../api/dao/search/RelationshipCond.java           |  35 ++++
 .../api/dao/search/RelationshipTypeCond.java       |  35 ++++
 .../persistence/api/dao/search/ResourceCond.java   |  35 ++++
 .../core/persistence/api/dao/search/RoleCond.java  |  35 ++++
 .../persistence/api/dao/search/SearchCond.java     |  76 ++++++++
 .../core/persistence/api/entity/AnyUtils.java      |   3 +-
 core/persistence-jpa/pom.xml                       |   4 -
 .../persistence/jpa/content/MultiParentNode.java   |  38 +++-
 .../core/persistence/jpa/dao/AbstractAnyDAO.java   |  27 ++-
 .../persistence/jpa/dao/AbstractAnySearchDAO.java  |  45 +++--
 .../core/persistence/jpa/dao/JPAAnySearchDAO.java  | 211 +++++++++++++--------
 .../core/persistence/jpa/dao/JPADynRealmDAO.java   |   4 +-
 .../core/persistence/jpa/dao/JPAReportExecDAO.java |   2 +-
 .../core/persistence/jpa/dao/OrderBySupport.java   |   4 +-
 .../core/persistence/jpa/dao/SearchSupport.java    |  51 +++--
 .../persistence/jpa/dao/SearchViewSupport.java}    |  23 +--
 .../persistence/jpa/entity/AbstractEntity.java     |  36 +---
 .../jpa/entity/AbstractGeneratedKeyEntity.java     |   6 +-
 .../jpa/entity/AbstractProvidedKeyEntity.java      |   1 -
 .../core/persistence/jpa/entity/JPAAnyUtils.java   | 144 +++++---------
 .../persistence/jpa/entity/JPAConnPoolConf.java    |  38 +++-
 .../persistence/jpa/entity/JPAEntityFactory.java   |   6 +-
 .../persistence/jpa/entity/task/JPATaskUtils.java  |  15 +-
 .../jpa/entity/task/JPATaskUtilsFactory.java       |  17 +-
 .../persistence/jpa/openjpa/UUIDGenerator.java     |  58 ------
 .../main/resources/META-INF/spring-orm-oracle.xml  |   2 -
 .../resources/META-INF/spring-orm-sqlserver.xml    |   2 -
 .../src/main/resources/META-INF/spring-orm.xml     |   2 -
 core/persistence-jpa/src/main/resources/views.xml  |   2 +-
 .../core/persistence/jpa/inner/AnySearchTest.java  |   8 +-
 .../core/persistence/jpa/inner/RealmTest.java      |   7 +-
 .../persistence/jpa/inner/RemediationTest.java     |  23 ++-
 .../core/persistence/jpa/inner/UserTest.java       |  21 +-
 .../core/persistence/jpa/outer/ReportTest.java     |   7 +-
 .../syncope/core/provisioning/api/IntAttrName.java |  62 +++++-
 .../core/provisioning/api/WorkflowResult.java      |  36 +++-
 core/provisioning-java/pom.xml                     |   5 -
 .../core/provisioning/java/IntAttrNameParser.java  |   6 +-
 .../java/data/AccessTokenDataBinderImpl.java       |   7 +-
 .../java/data/ConnInstanceDataBinderImpl.java      |   5 +-
 .../provisioning/java/job/AfterHandlingJob.java    |   7 +-
 .../java/pushpull/SchedulingPullActions.java       |   7 +-
 .../core/rest/cxf/service/AbstractAnyService.java  |   5 +-
 .../cxf/service/AbstractExecutableService.java     |   3 +-
 .../core/rest/cxf/service/AbstractServiceImpl.java |   4 -
 core/spring/pom.xml                                |   5 +
 .../core/spring/security/SecureRandomUtils.java    |   9 +
 .../security/SyncopeAuthenticationDetails.java     |  30 ++-
 .../spring/security/SyncopeGrantedAuthority.java   |  33 +++-
 .../jpa/dao/ElasticsearchAnySearchDAO.java         |   5 +-
 .../core/flowable/impl/FlowableRuntimeUtils.java   |   2 +
 .../apache/syncope/core/logic/OIDCClientLogic.java |  11 +-
 .../jpa/entity/JPAOIDCEntityFactory.java           |   6 +-
 .../apache/syncope/core/logic/SAML2SPLogic.java    |  15 +-
 .../jpa/entity/JPASAML2EntityFactory.java          |   5 +
 .../fit/core/reference/TestAccountRule.java        |   1 -
 .../fit/core/reference/TestPasswordRule.java       |   4 +-
 .../org/apache/syncope/fit/core/UserITCase.java    |   2 +-
 69 files changed, 1129 insertions(+), 492 deletions(-)

diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
index 1408585..6675de6 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyDAO.java
@@ -39,22 +39,22 @@ public interface AnyDAO<A extends Any<?>> extends DAO<A> {
 
     A find(String key);
 
-    List<A> findByPlainAttrValue(String schemaName, PlainAttrValue attrValue, boolean ignoreCaseMatch);
+    List<A> findByPlainAttrValue(String schema, PlainAttrValue attrValue, boolean ignoreCaseMatch);
 
-    A findByPlainAttrUniqueValue(String schemaName, PlainAttrValue attrUniqueValue, boolean ignoreCaseMatch);
+    A findByPlainAttrUniqueValue(String schema, PlainAttrValue attrUniqueValue, boolean ignoreCaseMatch);
 
     /**
      * Find any objects by derived attribute value. This method could fail if one or more string literals contained
-     * into the derived attribute value provided derive from identifier (schema name) replacement. When you are going to
+     * into the derived attribute value provided derive from identifier (schema key) replacement. When you are going to
      * specify a derived attribute expression you must be quite sure that string literals used to build the expression
-     * cannot be found into the attribute values used to replace attribute schema names used as identifiers.
+     * cannot be found into the attribute values used to replace attribute schema keys used as identifiers.
      *
-     * @param schemaName derived schema name
+     * @param schema derived schema
      * @param value derived attribute value
      * @param ignoreCaseMatch whether comparison for string values should take case into account or not
      * @return list of any objects
      */
-    List<A> findByDerAttrValue(String schemaName, String value, boolean ignoreCaseMatch);
+    List<A> findByDerAttrValue(String schema, String value, boolean ignoreCaseMatch);
 
     List<A> findByResource(ExternalResource resource);
 
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AbstractSearchCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AbstractSearchCond.java
index d84083c..47e33d2 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AbstractSearchCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AbstractSearchCond.java
@@ -19,30 +19,10 @@
 package org.apache.syncope.core.persistence.api.dao.search;
 
 import java.io.Serializable;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
 
 public abstract class AbstractSearchCond implements Serializable {
 
     private static final long serialVersionUID = 5376869884544910804L;
 
-    @Override
-    public boolean equals(final Object obj) {
-        return EqualsBuilder.reflectionEquals(this, obj);
-    }
-
-    @Override
-    public int hashCode() {
-        return HashCodeBuilder.reflectionHashCode(this);
-    }
-
-    @Override
-    public String toString() {
-        return ReflectionToStringBuilder.toString(this, ToStringStyle.JSON_STYLE);
-    }
-
     public abstract boolean isValid();
-
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyCond.java
index 8bc9669..55736fa 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyCond.java
@@ -18,6 +18,8 @@
  */
 package org.apache.syncope.core.persistence.api.dao.search;
 
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
 /**
  * Search condition to be applied when comparing bean field values.
  */
@@ -32,4 +34,9 @@ public class AnyCond extends AttributeCond {
     public AnyCond(final Type conditionType) {
         super(conditionType);
     }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this).appendSuper(super.toString()).build();
+    }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyTypeCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyTypeCond.java
index 5072fc1..98d5f9d 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyTypeCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AnyTypeCond.java
@@ -18,6 +18,10 @@
  */
 package org.apache.syncope.core.persistence.api.dao.search;
 
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
 public class AnyTypeCond extends AbstractSearchCond {
 
     private static final long serialVersionUID = 4298076973281246633L;
@@ -37,4 +41,34 @@ public class AnyTypeCond extends AbstractSearchCond {
         return anyTypeKey != null;
     }
 
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(anyTypeKey).
+                build();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final AnyTypeCond other = (AnyTypeCond) obj;
+        return new EqualsBuilder().
+                append(anyTypeKey, other.anyTypeKey).
+                build();
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this).
+                append(anyTypeKey).
+                build();
+    }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AssignableCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AssignableCond.java
index 93a4d1c..dae0a44 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AssignableCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AssignableCond.java
@@ -18,6 +18,10 @@
  */
 package org.apache.syncope.core.persistence.api.dao.search;
 
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
 public class AssignableCond extends AbstractSearchCond {
 
     private static final long serialVersionUID = 1237627275756159522L;
@@ -51,4 +55,38 @@ public class AssignableCond extends AbstractSearchCond {
     public final boolean isValid() {
         return realmFullPath != null;
     }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(realmFullPath).
+                append(fromGroup).
+                build();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final AssignableCond other = (AssignableCond) obj;
+        return new EqualsBuilder().
+                append(realmFullPath, other.realmFullPath).
+                append(fromGroup, other.fromGroup).
+                build();
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this).
+                append(realmFullPath).
+                append(fromGroup).
+                build();
+    }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AttributeCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AttributeCond.java
index b8e2b85..c008f69 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AttributeCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/AttributeCond.java
@@ -18,6 +18,10 @@
  */
 package org.apache.syncope.core.persistence.api.dao.search;
 
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
 /**
  * Search condition to be applied when comparing attribute values.
  */
@@ -83,4 +87,41 @@ public class AttributeCond extends AbstractSearchCond {
     public final boolean isValid() {
         return type != null && schema != null && (type == Type.ISNULL || type == Type.ISNOTNULL || expression != null);
     }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(type).
+                append(schema).
+                append(expression).
+                build();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final AttributeCond other = (AttributeCond) obj;
+        return new EqualsBuilder().
+                append(type, other.type).
+                append(schema, other.schema).
+                append(expression, other.expression).
+                build();
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this).
+                append(type).
+                append(schema).
+                append(expression).
+                build();
+    }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/DynRealmCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/DynRealmCond.java
index e3f3590..20057f8 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/DynRealmCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/DynRealmCond.java
@@ -18,6 +18,10 @@
  */
 package org.apache.syncope.core.persistence.api.dao.search;
 
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
 public class DynRealmCond extends AbstractSearchCond {
 
     private static final long serialVersionUID = 9110213614796095482L;
@@ -36,4 +40,35 @@ public class DynRealmCond extends AbstractSearchCond {
     public final boolean isValid() {
         return dynRealm != null;
     }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(dynRealm).
+                build();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final DynRealmCond other = (DynRealmCond) obj;
+        return new EqualsBuilder().
+                append(dynRealm, other.dynRealm).
+                build();
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this).
+                append(dynRealm).
+                build();
+    }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/MemberCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/MemberCond.java
index 677d65a..e0cb715 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/MemberCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/MemberCond.java
@@ -18,6 +18,10 @@
  */
 package org.apache.syncope.core.persistence.api.dao.search;
 
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
 public class MemberCond extends AbstractSearchCond {
 
     private static final long serialVersionUID = 1193754148321878685L;
@@ -37,4 +41,34 @@ public class MemberCond extends AbstractSearchCond {
         return member != null;
     }
 
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(member).
+                build();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final MemberCond other = (MemberCond) obj;
+        return new EqualsBuilder().
+                append(member, other.member).
+                build();
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this).
+                append(member).
+                build();
+    }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/MembershipCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/MembershipCond.java
index 1d09753..ef3eed5 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/MembershipCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/MembershipCond.java
@@ -18,6 +18,10 @@
  */
 package org.apache.syncope.core.persistence.api.dao.search;
 
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
 public class MembershipCond extends AbstractSearchCond {
 
     private static final long serialVersionUID = -728155256293925989L;
@@ -36,4 +40,35 @@ public class MembershipCond extends AbstractSearchCond {
     public final boolean isValid() {
         return group != null;
     }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(group).
+                build();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final MembershipCond other = (MembershipCond) obj;
+        return new EqualsBuilder().
+                append(group, other.group).
+                build();
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this).
+                append(group).
+                build();
+    }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/OrderByClause.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/OrderByClause.java
index 5fa9e79..eb01ee2 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/OrderByClause.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/OrderByClause.java
@@ -21,8 +21,7 @@ package org.apache.syncope.core.persistence.api.dao.search;
 import java.io.Serializable;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.commons.lang3.builder.ToStringBuilder;
 
 public class OrderByClause implements Serializable {
 
@@ -56,17 +55,36 @@ public class OrderByClause implements Serializable {
     }
 
     @Override
-    public boolean equals(final Object obj) {
-        return EqualsBuilder.reflectionEquals(this, obj);
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(field).
+                append(direction).
+                build();
     }
 
     @Override
-    public int hashCode() {
-        return HashCodeBuilder.reflectionHashCode(this);
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final OrderByClause other = (OrderByClause) obj;
+        return new EqualsBuilder().
+                append(field, other.field).
+                append(direction, other.direction).
+                build();
     }
 
     @Override
     public String toString() {
-        return ReflectionToStringBuilder.toString(this, ToStringStyle.JSON_STYLE);
+        return new ToStringBuilder(this).
+                append(field).
+                append(direction).
+                build();
     }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/PrivilegeCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/PrivilegeCond.java
index 1647cdb..18369a0 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/PrivilegeCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/PrivilegeCond.java
@@ -18,6 +18,10 @@
  */
 package org.apache.syncope.core.persistence.api.dao.search;
 
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
 public class PrivilegeCond extends AbstractSearchCond {
 
     private static final long serialVersionUID = -8095105031495519762L;
@@ -36,4 +40,35 @@ public class PrivilegeCond extends AbstractSearchCond {
     public final boolean isValid() {
         return privilege != null;
     }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(privilege).
+                build();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final PrivilegeCond other = (PrivilegeCond) obj;
+        return new EqualsBuilder().
+                append(privilege, other.privilege).
+                build();
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this).
+                append(privilege).
+                build();
+    }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RelationshipCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RelationshipCond.java
index 069278e..16d71ab 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RelationshipCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RelationshipCond.java
@@ -18,6 +18,10 @@
  */
 package org.apache.syncope.core.persistence.api.dao.search;
 
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
 public class RelationshipCond extends AbstractSearchCond {
 
     private static final long serialVersionUID = 6865985945516722103L;
@@ -36,4 +40,35 @@ public class RelationshipCond extends AbstractSearchCond {
     public final boolean isValid() {
         return anyObject != null;
     }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(anyObject).
+                build();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final RelationshipCond other = (RelationshipCond) obj;
+        return new EqualsBuilder().
+                append(anyObject, other.anyObject).
+                build();
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this).
+                append(anyObject).
+                build();
+    }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RelationshipTypeCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RelationshipTypeCond.java
index d120e62..59f8e49 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RelationshipTypeCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RelationshipTypeCond.java
@@ -18,6 +18,10 @@
  */
 package org.apache.syncope.core.persistence.api.dao.search;
 
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
 public class RelationshipTypeCond extends AbstractSearchCond {
 
     private static final long serialVersionUID = 906241367466433419L;
@@ -36,4 +40,35 @@ public class RelationshipTypeCond extends AbstractSearchCond {
     public final boolean isValid() {
         return relationshipTypeKey != null;
     }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(relationshipTypeKey).
+                build();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final RelationshipTypeCond other = (RelationshipTypeCond) obj;
+        return new EqualsBuilder().
+                append(relationshipTypeKey, other.relationshipTypeKey).
+                build();
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this).
+                append(relationshipTypeKey).
+                build();
+    }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/ResourceCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/ResourceCond.java
index a20f3e6..ea87bb2 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/ResourceCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/ResourceCond.java
@@ -18,6 +18,10 @@
  */
 package org.apache.syncope.core.persistence.api.dao.search;
 
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
 /**
  * Search condition to be applied when searching for associated resources.
  */
@@ -39,4 +43,35 @@ public class ResourceCond extends AbstractSearchCond {
     public final boolean isValid() {
         return resourceKey != null;
     }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(resourceKey).
+                build();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final ResourceCond other = (ResourceCond) obj;
+        return new EqualsBuilder().
+                append(resourceKey, other.resourceKey).
+                build();
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this).
+                append(resourceKey).
+                build();
+    }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RoleCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RoleCond.java
index 08972fa..f543377 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RoleCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/RoleCond.java
@@ -18,6 +18,10 @@
  */
 package org.apache.syncope.core.persistence.api.dao.search;
 
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
 public class RoleCond extends AbstractSearchCond {
 
     private static final long serialVersionUID = 3581958527829522490L;
@@ -36,4 +40,35 @@ public class RoleCond extends AbstractSearchCond {
     public final boolean isValid() {
         return role != null;
     }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(role).
+                build();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final RoleCond other = (RoleCond) obj;
+        return new EqualsBuilder().
+                append(role, other.role).
+                build();
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this).
+                append(role).
+                build();
+    }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
index bb1dfa2..c90cdde 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/SearchCond.java
@@ -19,6 +19,9 @@
 package org.apache.syncope.core.persistence.api.dao.search;
 
 import java.util.List;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
 
 public class SearchCond extends AbstractSearchCond {
 
@@ -392,4 +395,77 @@ public class SearchCond extends AbstractSearchCond {
 
         return isValid;
     }
+
+    @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(type).
+                append(anyTypeCond).
+                append(anyCond).
+                append(attributeCond).
+                append(relationshipCond).
+                append(relationshipTypeCond).
+                append(membershipCond).
+                append(roleCond).
+                append(privilegeCond).
+                append(dynRealmCond).
+                append(resourceCond).
+                append(assignableCond).
+                append(memberCond).
+                append(leftSearchCond).
+                append(rightSearchCond).
+                build();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final SearchCond other = (SearchCond) obj;
+        return new EqualsBuilder().
+                append(type, other.type).
+                append(anyTypeCond, other.anyTypeCond).
+                append(anyCond, other.anyCond).
+                append(attributeCond, other.attributeCond).
+                append(relationshipCond, other.relationshipCond).
+                append(relationshipTypeCond, other.relationshipTypeCond).
+                append(membershipCond, other.membershipCond).
+                append(roleCond, other.roleCond).
+                append(privilegeCond, other.privilegeCond).
+                append(dynRealmCond, other.dynRealmCond).
+                append(resourceCond, other.resourceCond).
+                append(assignableCond, other.assignableCond).
+                append(memberCond, other.memberCond).
+                append(leftSearchCond, other.leftSearchCond).
+                append(rightSearchCond, other.rightSearchCond).
+                build();
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this).
+                append(type).
+                append(anyTypeCond).
+                append(anyCond).
+                append(attributeCond).
+                append(relationshipCond).
+                append(relationshipTypeCond).
+                append(membershipCond).
+                append(roleCond).
+                append(privilegeCond).
+                append(dynRealmCond).
+                append(resourceCond).
+                append(assignableCond).
+                append(memberCond).
+                append(leftSearchCond).
+                append(rightSearchCond).
+                build();
+    }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java
index 05bd85a..90b3c96 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/AnyUtils.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.persistence.api.entity;
 
+import java.lang.reflect.Field;
 import java.util.Set;
 import org.apache.syncope.common.lib.patch.AnyPatch;
 import org.apache.syncope.common.lib.to.AnyTO;
@@ -31,7 +32,7 @@ public interface AnyUtils {
 
     <T extends Any<?>> Class<T> anyClass();
 
-    boolean isFieldName(String name);
+    Field getField(String name);
 
     <T extends PlainAttr<?>> Class<T> plainAttrClass();
 
diff --git a/core/persistence-jpa/pom.xml b/core/persistence-jpa/pom.xml
index 373a45e..99c99b8 100644
--- a/core/persistence-jpa/pom.xml
+++ b/core/persistence-jpa/pom.xml
@@ -55,10 +55,6 @@ under the License.
       <groupId>org.apache.openjpa</groupId>
       <artifactId>openjpa-persistence-jdbc</artifactId>
     </dependency>
-    <dependency>
-      <groupId>com.fasterxml.uuid</groupId>
-      <artifactId>java-uuid-generator</artifactId>
-    </dependency>
     
     <dependency>
       <groupId>com.zaxxer</groupId>
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNode.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNode.java
index 232e22a..dbe1cf1 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNode.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/content/MultiParentNode.java
@@ -22,6 +22,7 @@ import java.util.HashSet;
 import java.util.Set;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
 
 class MultiParentNode<T> {
 
@@ -94,12 +95,43 @@ class MultiParentNode<T> {
     }
 
     @Override
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(object).
+                append(children).
+                append(level).
+                append(exploited).
+                build();
+    }
+
+    @Override
     public boolean equals(final Object obj) {
-        return EqualsBuilder.reflectionEquals(this, obj);
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        @SuppressWarnings("unchecked")
+        final MultiParentNode<T> other = (MultiParentNode<T>) obj;
+        return new EqualsBuilder().
+                append(object, other.object).
+                append(children, other.children).
+                append(level, other.level).
+                append(exploited, other.exploited).
+                build();
     }
 
     @Override
-    public int hashCode() {
-        return HashCodeBuilder.reflectionHashCode(this);
+    public String toString() {
+        return new ToStringBuilder(this).
+                append(object).
+                append(children).
+                append(level).
+                append(exploited).
+                build();
     }
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
index 567a6fc..3320bb6 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnyDAO.java
@@ -199,7 +199,7 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im
 
         PlainSchema schema = plainSchemaDAO().find(schemaKey);
         if (schema == null) {
-            LOG.error("Invalid schema name '{}'", schemaKey);
+            LOG.error("Invalid schema '{}'", schemaKey);
             return Collections.<A>emptyList();
         }
 
@@ -237,7 +237,7 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im
 
         PlainSchema schema = plainSchemaDAO().find(schemaKey);
         if (schema == null) {
-            LOG.error("Invalid schema name '{}'", schemaKey);
+            LOG.error("Invalid schema '{}'", schemaKey);
             return null;
         }
         if (!schema.isUniqueConstraint()) {
@@ -248,7 +248,7 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im
         List<A> result = findByPlainAttrValue(schemaKey, attrUniqueValue, ignoreCaseMatch);
         return result.isEmpty()
                 ? null
-                : result.iterator().next();
+                : result.get(0);
     }
 
     /**
@@ -277,13 +277,13 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im
     private Set<String> getWhereClause(final String expression, final String value, final boolean ignoreCaseMatch) {
         Parser parser = new Parser(new StringReader(expression));
 
-        // Schema names
+        // Schema keys
         List<String> identifiers = new ArrayList<>();
 
         // Literals
         List<String> literals = new ArrayList<>();
 
-        // Get schema names and literals
+        // Get schema keys and literals
         for (Token token = parser.getNextToken(); token != null && StringUtils.isNotBlank(token.toString());
                 token = parser.getNextToken()) {
 
@@ -297,16 +297,16 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im
         }
 
         // Sort literals in order to process later literals included into others
-        Collections.sort(literals, (final String t, final String t1) -> {
-            if (t == null && t1 == null) {
+        Collections.sort(literals, (l1, l2) -> {
+            if (l1 == null && l2 == null) {
                 return 0;
-            } else if (t != null && t1 == null) {
+            } else if (l1 != null && l2 == null) {
                 return -1;
-            } else if (t == null && t1 != null) {
+            } else if (l1 == null && l2 != null) {
                 return 1;
-            } else if (t.length() == t1.length()) {
+            } else if (l1.length() == l2.length()) {
                 return 0;
-            } else if (t.length() > t1.length()) {
+            } else if (l1.length() > l2.length()) {
                 return -1;
             } else {
                 return 1;
@@ -343,7 +343,7 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im
 
                     bld.append("(");
 
-                    // set schema name
+                    // set schema key
                     bld.append("s.id = '").append(identifiers.get(i)).append("'");
 
                     bld.append(" AND ");
@@ -396,7 +396,7 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im
     public List<A> findByDerAttrValue(final String schemaKey, final String value, final boolean ignoreCaseMatch) {
         DerSchema schema = derSchemaDAO().find(schemaKey);
         if (schema == null) {
-            LOG.error("Invalid schema name '{}'", schemaKey);
+            LOG.error("Invalid schema '{}'", schemaKey);
             return Collections.<A>emptyList();
         }
 
@@ -551,5 +551,4 @@ public abstract class AbstractAnyDAO<A extends Any<?>> extends AbstractDAO<A> im
                 });
         return result;
     }
-
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
index 178fa00..0d35ccb 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractAnySearchDAO.java
@@ -32,7 +32,6 @@ import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.ClassUtils;
-import org.apache.commons.lang3.SerializationUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.commons.lang3.tuple.Triple;
 import org.apache.syncope.common.lib.SyncopeConstants;
@@ -57,6 +56,7 @@ import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.Realm;
@@ -64,7 +64,6 @@ import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.util.ReflectionUtils;
 
 public abstract class AbstractAnySearchDAO extends AbstractDAO<Any<?>> implements AnySearchDAO {
 
@@ -91,6 +90,9 @@ public abstract class AbstractAnySearchDAO extends AbstractDAO<Any<?>> implement
     protected PlainSchemaDAO schemaDAO;
 
     @Autowired
+    protected EntityFactory entityFactory;
+
+    @Autowired
     protected AnyUtilsFactory anyUtilsFactory;
 
     protected SearchCond buildEffectiveCond(final SearchCond cond, final Set<String> dynRealmKeys) {
@@ -175,22 +177,23 @@ public abstract class AbstractAnySearchDAO extends AbstractDAO<Any<?>> implement
     }
 
     protected Triple<PlainSchema, PlainAttrValue, AnyCond> check(final AnyCond cond, final AnyTypeKind kind) {
-        AnyCond condClone = SerializationUtils.clone(cond);
+        AnyCond computed = new AnyCond(cond.getType());
+        computed.setSchema(cond.getSchema());
+        computed.setExpression(cond.getExpression());
 
-        AnyUtils attrUtils = anyUtilsFactory.getInstance(kind);
+        AnyUtils anyUtils = anyUtilsFactory.getInstance(kind);
 
-        // Keeps track of difference between entity's getKey() and JPA @Id fields
-        if ("key".equals(condClone.getSchema())) {
-            condClone.setSchema("id");
-        }
-
-        Field anyField = ReflectionUtils.findField(attrUtils.anyClass(), condClone.getSchema());
+        Field anyField = anyUtils.getField(computed.getSchema());
         if (anyField == null) {
-            LOG.warn("Ignoring invalid schema '{}'", condClone.getSchema());
+            LOG.warn("Ignoring invalid field '{}'", computed.getSchema());
             throw new IllegalArgumentException();
         }
+        // Keeps track of difference between entity's getKey() and JPA @Id fields
+        if ("key".equals(computed.getSchema())) {
+            computed.setSchema("id");
+        }
 
-        PlainSchema schema = new JPAPlainSchema();
+        PlainSchema schema = entityFactory.newEntity(PlainSchema.class);
         schema.setKey(anyField.getName());
         for (AttrSchemaType attrSchemaType : AttrSchemaType.values()) {
             if (anyField.getType().isAssignableFrom(attrSchemaType.getType())) {
@@ -224,26 +227,26 @@ public abstract class AbstractAnySearchDAO extends AbstractDAO<Any<?>> implement
             }
 
             if (relMethod != null && String.class.isAssignableFrom(relMethod.getReturnType())) {
-                condClone.setSchema(condClone.getSchema() + "_id");
+                computed.setSchema(computed.getSchema() + "_id");
                 schema.setType(AttrSchemaType.String);
             }
         }
 
-        PlainAttrValue attrValue = attrUtils.newPlainAttrValue();
-        if (condClone.getType() != AttributeCond.Type.LIKE
-                && condClone.getType() != AttributeCond.Type.ILIKE
-                && condClone.getType() != AttributeCond.Type.ISNULL
-                && condClone.getType() != AttributeCond.Type.ISNOTNULL) {
+        PlainAttrValue attrValue = anyUtils.newPlainAttrValue();
+        if (computed.getType() != AttributeCond.Type.LIKE
+                && computed.getType() != AttributeCond.Type.ILIKE
+                && computed.getType() != AttributeCond.Type.ISNULL
+                && computed.getType() != AttributeCond.Type.ISNOTNULL) {
 
             try {
-                ((JPAPlainSchema) schema).validator().validate(condClone.getExpression(), attrValue);
+                ((JPAPlainSchema) schema).validator().validate(computed.getExpression(), attrValue);
             } catch (ValidationException e) {
-                LOG.error("Could not validate expression '" + condClone.getExpression() + "'", e);
+                LOG.error("Could not validate expression '" + computed.getExpression() + "'", e);
                 throw new IllegalArgumentException();
             }
         }
 
-        return Triple.of(schema, attrValue, condClone);
+        return Triple.of(schema, attrValue, computed);
     }
 
     protected String check(final MembershipCond cond) {
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
index c6ebca1..0a04ac0 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -53,19 +53,19 @@ import org.apache.syncope.core.persistence.api.dao.search.RelationshipTypeCond;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.DynRealm;
+import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.springframework.util.ReflectionUtils;
 
 /**
  * Search engine implementation for users, groups and any objects, based on self-updating SQL views.
  */
 public class JPAAnySearchDAO extends AbstractAnySearchDAO {
 
-    private static final String EMPTY_QUERY = "SELECT any_id FROM user_search_attr WHERE 1=2";
+    protected static final String EMPTY_QUERY = "SELECT any_id FROM user_search WHERE 1=2";
 
-    private static final String[] RELATIONSHIP_FIELDS = new String[] { "realm", "userOwner", "groupOwner" };
+    protected static final String[] RELATIONSHIP_FIELDS = new String[] { "realm", "userOwner", "groupOwner" };
 
     private Pair<String, Set<String>> getAdminRealmsFilter(
             final Set<String> adminRealms,
@@ -83,7 +83,7 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
                     throw noRealm;
                 } else {
                     realmKeys.addAll(realmDAO.findDescendants(realm).stream().
-                            map(r -> r.getKey()).collect(Collectors.toSet()));
+                            map(Entity::getKey).collect(Collectors.toSet()));
                 }
             } else {
                 DynRealm dynRealm = dynRealmDAO.find(realmPath);
@@ -96,7 +96,7 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         });
         if (!dynRealmKeys.isEmpty()) {
             realmKeys.addAll(realmDAO.findAll().stream().
-                    map(r -> r.getKey()).collect(Collectors.toSet()));
+                    map(Entity::getKey).collect(Collectors.toSet()));
         }
 
         StringBuilder adminRealmFilter = new StringBuilder("u.any_id IN (").
@@ -119,11 +119,15 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         return Pair.of(adminRealmFilter.toString(), dynRealmKeys);
     }
 
+    SearchSupport buildSearchSupport(final AnyTypeKind kind) {
+        return new SearchViewSupport(kind);
+    }
+
     @Override
     protected int doCount(final Set<String> adminRealms, final SearchCond cond, final AnyTypeKind kind) {
-        List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
+        List<Object> parameters = new ArrayList<>();
 
-        SearchSupport svs = new SearchSupport(kind);
+        SearchSupport svs = buildSearchSupport(kind);
 
         Pair<String, Set<String>> filter = getAdminRealmsFilter(adminRealms, svs, parameters);
 
@@ -155,9 +159,9 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
             final AnyTypeKind kind) {
 
         try {
-            List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
+            List<Object> parameters = new ArrayList<>();
 
-            SearchSupport svs = new SearchSupport(kind);
+            SearchSupport svs = buildSearchSupport(kind);
 
             Pair<String, Set<String>> filter = getAdminRealmsFilter(adminRealms, svs, parameters);
 
@@ -199,14 +203,9 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         return Collections.emptyList();
     }
 
-    private int setParameter(final List<Object> parameters, final Object parameter) {
-        int key;
-        synchronized (parameters) {
-            parameters.add(parameter);
-            key = parameters.size();
-        }
-
-        return key;
+    protected int setParameter(final List<Object> parameters, final Object parameter) {
+        parameters.add(parameter);
+        return parameters.size();
     }
 
     private void fillWithParameters(final Query query, final List<Object> parameters) {
@@ -224,7 +223,7 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
     }
 
     private StringBuilder buildSelect(final OrderBySupport obs) {
-        final StringBuilder select = new StringBuilder("SELECT u.any_id");
+        StringBuilder select = new StringBuilder("SELECT u.any_id");
 
         obs.items.forEach(item -> {
             select.append(',').append(item.select);
@@ -234,15 +233,14 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         return select;
     }
 
-    private StringBuilder buildWhere(final SearchSupport svs, final OrderBySupport obs) {
-        StringBuilder where = new StringBuilder(" u");
+    protected void processOBS(final SearchSupport svs, final OrderBySupport obs, final StringBuilder where) {
         obs.views.forEach(searchView -> {
             where.append(',');
-            if (searchView.name.equals(svs.attr().name)) {
+            if (searchView.name.equals(svs.asSearchViewSupport().attr().name)) {
                 where.append(" (SELECT * FROM ").append(searchView.name);
 
                 if (svs.nonMandatorySchemas || obs.nonMandatorySchemas) {
-                    where.append(" UNION SELECT * FROM ").append(svs.nullAttr().name);
+                    where.append(" UNION SELECT * FROM ").append(svs.asSearchViewSupport().nullAttr().name);
                 }
 
                 where.append(')');
@@ -251,6 +249,11 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
             }
             where.append(' ').append(searchView.alias);
         });
+    }
+
+    private StringBuilder buildWhere(final SearchSupport svs, final OrderBySupport obs) {
+        StringBuilder where = new StringBuilder(" u");
+        processOBS(svs, obs, where);
         where.append(" WHERE ");
         obs.views.forEach(searchView -> {
             where.append("u.any_id=").append(searchView.alias).append(".any_id AND ");
@@ -279,48 +282,62 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         return orderBy;
     }
 
+    protected void parseOrderByForPlainSchema(
+            final SearchSupport svs,
+            final OrderBySupport obs,
+            final OrderBySupport.Item item,
+            final OrderByClause clause,
+            final PlainSchema schema,
+            final String fieldName) {
+
+        // keep track of involvement of non-mandatory schemas in the order by clauses
+        obs.nonMandatorySchemas = !"true".equals(schema.getMandatoryCondition());
+
+        if (schema.isUniqueConstraint()) {
+            obs.views.add(svs.asSearchViewSupport().uniqueAttr());
+
+            item.select = new StringBuilder().
+                    append(svs.asSearchViewSupport().uniqueAttr().alias).append('.').
+                    append(svs.fieldName(schema.getType())).
+                    append(" AS ").append(fieldName).toString();
+            item.where = new StringBuilder().
+                    append(svs.asSearchViewSupport().uniqueAttr().alias).
+                    append(".schema_id='").append(fieldName).append("'").toString();
+            item.orderBy = fieldName + " " + clause.getDirection().name();
+        } else {
+            obs.views.add(svs.asSearchViewSupport().attr());
+
+            item.select = new StringBuilder().
+                    append(svs.asSearchViewSupport().attr().alias).append('.').append(svs.fieldName(schema.getType())).
+                    append(" AS ").append(fieldName).toString();
+            item.where = new StringBuilder().
+                    append(svs.asSearchViewSupport().attr().alias).
+                    append(".schema_id='").append(fieldName).append("'").toString();
+            item.orderBy = fieldName + " " + clause.getDirection().name();
+        }
+    }
+
     private OrderBySupport parseOrderBy(
-            final AnyTypeKind kind, final SearchSupport svs, final List<OrderByClause> orderBy) {
+            final AnyTypeKind kind,
+            final SearchSupport svs,
+            final List<OrderByClause> orderBy) {
 
-        AnyUtils attrUtils = anyUtilsFactory.getInstance(kind);
+        AnyUtils anyUtils = anyUtilsFactory.getInstance(kind);
 
         OrderBySupport obs = new OrderBySupport();
 
         filterOrderBy(orderBy).forEach(clause -> {
             OrderBySupport.Item item = new OrderBySupport.Item();
 
-            // Manage difference among external key attribute and internal JPA @Id
-            String fieldName = "key".equals(clause.getField()) ? "id" : clause.getField();
-
-            if (ReflectionUtils.findField(attrUtils.anyClass(), fieldName) == null) {
-                PlainSchema schema = schemaDAO.find(fieldName);
+            if (anyUtils.getField(clause.getField()) == null) {
+                PlainSchema schema = schemaDAO.find(clause.getField());
                 if (schema != null) {
-                    // keep track of involvement of non-mandatory schemas in the order by clauses
-                    obs.nonMandatorySchemas = !"true".equals(schema.getMandatoryCondition());
-
-                    if (schema.isUniqueConstraint()) {
-                        obs.views.add(svs.uniqueAttr());
-
-                        item.select = new StringBuilder().
-                                append(svs.uniqueAttr().alias).append('.').append(svs.fieldName(schema.getType())).
-                                append(" AS ").append(fieldName).toString();
-                        item.where = new StringBuilder().
-                                append(svs.uniqueAttr().alias).
-                                append(".schema_id='").append(fieldName).append("'").toString();
-                        item.orderBy = fieldName + " " + clause.getDirection().name();
-                    } else {
-                        obs.views.add(svs.attr());
-
-                        item.select = new StringBuilder().
-                                append(svs.attr().alias).append('.').append(svs.fieldName(schema.getType())).
-                                append(" AS ").append(fieldName).toString();
-                        item.where = new StringBuilder().
-                                append(svs.attr().alias).
-                                append(".schema_id='").append(fieldName).append("'").toString();
-                        item.orderBy = fieldName + " " + clause.getDirection().name();
-                    }
+                    parseOrderByForPlainSchema(svs, obs, item, clause, schema, clause.getField());
                 }
             } else {
+                // Manage difference among external key attribute and internal JPA @Id
+                String fieldName = "key".equals(clause.getField()) ? "id" : clause.getField();
+
                 // Adjust field name to column name
                 if (ArrayUtils.contains(RELATIONSHIP_FIELDS, fieldName)) {
                     fieldName += "_id";
@@ -419,8 +436,11 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         return query;
     }
 
-    private String getQuery(
-            final AnyTypeCond cond, final boolean not, final List<Object> parameters, final SearchSupport svs) {
+    protected String getQuery(
+            final AnyTypeCond cond,
+            final boolean not,
+            final List<Object> parameters,
+            final SearchSupport svs) {
 
         StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
                 append(svs.field().name).append(" WHERE type_id");
@@ -436,7 +456,7 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         return query.toString();
     }
 
-    private String getQuery(
+    protected String getQuery(
             final RelationshipTypeCond cond,
             final boolean not,
             final List<Object> parameters,
@@ -462,8 +482,11 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         return query.toString();
     }
 
-    private String getQuery(
-            final RelationshipCond cond, final boolean not, final List<Object> parameters, final SearchSupport svs) {
+    protected String getQuery(
+            final RelationshipCond cond,
+            final boolean not,
+            final List<Object> parameters,
+            final SearchSupport svs) {
 
         String rightAnyObjectKey;
         try {
@@ -489,8 +512,11 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         return query.toString();
     }
 
-    private String getQuery(
-            final MembershipCond cond, final boolean not, final List<Object> parameters, final SearchSupport svs) {
+    protected String getQuery(
+            final MembershipCond cond,
+            final boolean not,
+            final List<Object> parameters,
+            final SearchSupport svs) {
 
         String groupKey;
         try {
@@ -527,8 +553,11 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         return query.toString();
     }
 
-    private String getQuery(
-            final RoleCond cond, final boolean not, final List<Object> parameters, final SearchSupport svs) {
+    protected String getQuery(
+            final RoleCond cond,
+            final boolean not,
+            final List<Object> parameters,
+            final SearchSupport svs) {
 
         StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
                 append(svs.field().name).append(" WHERE (");
@@ -558,8 +587,11 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         return query.toString();
     }
 
-    private String getQuery(
-            final PrivilegeCond cond, final boolean not, final List<Object> parameters, final SearchSupport svs) {
+    protected String getQuery(
+            final PrivilegeCond cond,
+            final boolean not,
+            final List<Object> parameters,
+            final SearchSupport svs) {
 
         StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
                 append(svs.field().name).append(" WHERE (");
@@ -589,8 +621,11 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         return query.toString();
     }
 
-    private String getQuery(
-            final DynRealmCond cond, final boolean not, final List<Object> parameters, final SearchSupport svs) {
+    protected String getQuery(
+            final DynRealmCond cond,
+            final boolean not,
+            final List<Object> parameters,
+            final SearchSupport svs) {
 
         StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
                 append(svs.field().name).append(" WHERE (");
@@ -609,8 +644,11 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         return query.toString();
     }
 
-    private String getQuery(
-            final ResourceCond cond, final boolean not, final List<Object> parameters, final SearchSupport svs) {
+    protected String getQuery(
+            final ResourceCond cond,
+            final boolean not,
+            final List<Object> parameters,
+            final SearchSupport svs) {
 
         StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
                 append(svs.field().name).append(" WHERE ");
@@ -638,7 +676,11 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         return query.toString();
     }
 
-    private String getQuery(final AssignableCond cond, final List<Object> parameters, final SearchSupport svs) {
+    protected String getQuery(
+            final AssignableCond cond,
+            final List<Object> parameters,
+            final SearchSupport svs) {
+
         Realm realm;
         try {
             realm = check(cond);
@@ -664,8 +706,11 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         return query.toString();
     }
 
-    private String getQuery(
-            final MemberCond cond, final boolean not, final List<Object> parameters, final SearchSupport svs) {
+    protected String getQuery(
+            final MemberCond cond,
+            final boolean not,
+            final List<Object> parameters,
+            final SearchSupport svs) {
 
         String memberKey;
         try {
@@ -766,7 +811,7 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
                 } else {
                     query.append('=');
                 }
-                if ((schema.getType() == AttrSchemaType.String 
+                if ((schema.getType() == AttrSchemaType.String
                         || schema.getType() == AttrSchemaType.Enum) && ignoreCase) {
                     query.append("LOWER(?").append(setParameter(parameters, attrValue.getValue())).append(')');
                 } else {
@@ -818,8 +863,11 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         }
     }
 
-    private String getQuery(
-            final AttributeCond cond, final boolean not, final List<Object> parameters, final SearchSupport svs) {
+    protected String getQuery(
+            final AttributeCond cond,
+            final boolean not,
+            final List<Object> parameters,
+            final SearchSupport svs) {
 
         Pair<PlainSchema, PlainAttrValue> checked;
         try {
@@ -833,20 +881,20 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
             case ISNOTNULL:
                 query.append(svs.field().name).
                         append(" WHERE any_id NOT IN (SELECT any_id FROM ").
-                        append(svs.nullAttr().name).
+                        append(svs.asSearchViewSupport().nullAttr().name).
                         append(" WHERE schema_id='").append(checked.getLeft().getKey()).append("')");
                 break;
 
             case ISNULL:
-                query.append(svs.nullAttr().name).
+                query.append(svs.asSearchViewSupport().nullAttr().name).
                         append(" WHERE schema_id='").append(checked.getLeft().getKey()).append("'");
                 break;
 
             default:
                 if (checked.getLeft().isUniqueConstraint()) {
-                    query.append(svs.uniqueAttr().name);
+                    query.append(svs.asSearchViewSupport().uniqueAttr().name);
                 } else {
-                    query.append(svs.attr().name);
+                    query.append(svs.asSearchViewSupport().attr().name);
                 }
                 query.append(" WHERE schema_id='").append(checked.getLeft().getKey());
                 fillAttrQuery(query, checked.getRight(), checked.getLeft(), cond, not, parameters, svs);
@@ -855,8 +903,11 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         return query.toString();
     }
 
-    private String getQuery(
-            final AnyCond cond, final boolean not, final List<Object> parameters, final SearchSupport svs) {
+    protected String getQuery(
+            final AnyCond cond,
+            final boolean not,
+            final List<Object> parameters,
+            final SearchSupport svs) {
 
         Triple<PlainSchema, PlainAttrValue, AnyCond> checked;
         try {
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADynRealmDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADynRealmDAO.java
index 7657112..b9d2f01 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADynRealmDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADynRealmDAO.java
@@ -102,8 +102,8 @@ public class JPADynRealmDAO extends AbstractDAO<DynRealm> implements DynRealmDAO
                 SearchCondConverter.convert(memb.getFIQLCond()), memb.getAnyType().getKind())).
                 forEachOrdered(matching -> {
                     matching.forEach(any -> {
-                        Query insert = entityManager().createNativeQuery("INSERT INTO " + DYNMEMB_TABLE
-                                + " VALUES(?, ?)");
+                        Query insert = entityManager().createNativeQuery(
+                                "INSERT INTO " + DYNMEMB_TABLE + " VALUES(?, ?)");
                         insert.setParameter(1, any.getKey());
                         insert.setParameter(2, merged.getKey());
                         insert.executeUpdate();
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
index de8f5ec..e26ce31 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAReportExecDAO.java
@@ -159,8 +159,8 @@ public class JPAReportExecDAO extends AbstractDAO<ReportExec> implements ReportE
         return query.getResultList();
     }
 
-    @Override
     @Transactional(rollbackFor = Throwable.class)
+    @Override
     public ReportExec save(final ReportExec execution) {
         return entityManager().merge(execution);
     }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OrderBySupport.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OrderBySupport.java
index ec87f5b..0f31c57 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OrderBySupport.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OrderBySupport.java
@@ -23,9 +23,9 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-class OrderBySupport {
+public class OrderBySupport {
 
-    static class Item {
+    public static class Item {
 
         protected String select;
 
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
index aa65aea..3304a70 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
@@ -23,9 +23,9 @@ import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
 
-class SearchSupport {
+public class SearchSupport {
 
-    static class SearchView {
+    public static class SearchView {
 
         protected String alias;
 
@@ -37,13 +37,29 @@ class SearchSupport {
         }
 
         @Override
-        public boolean equals(final Object obj) {
-            return EqualsBuilder.reflectionEquals(this, obj);
+        public int hashCode() {
+            return new HashCodeBuilder().
+                    append(alias).
+                    append(name).
+                    build();
         }
 
         @Override
-        public int hashCode() {
-            return HashCodeBuilder.reflectionHashCode(this);
+        public boolean equals(final Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            final SearchView other = (SearchView) obj;
+            return new EqualsBuilder().
+                    append(alias, other.alias).
+                    append(name, other.name).
+                    build();
         }
     }
 
@@ -51,7 +67,7 @@ class SearchSupport {
 
     protected boolean nonMandatorySchemas = false;
 
-    SearchSupport(final AnyTypeKind anyTypeKind) {
+    public SearchSupport(final AnyTypeKind anyTypeKind) {
         this.anyTypeKind = anyTypeKind;
     }
 
@@ -88,7 +104,7 @@ class SearchSupport {
     }
 
     public SearchView field() {
-        String result = "";
+        String result;
 
         switch (anyTypeKind) {
             case ANY_OBJECT:
@@ -108,10 +124,6 @@ class SearchSupport {
         return new SearchView("sv", result);
     }
 
-    public SearchView attr() {
-        return new SearchView("sva", field().name + "_attr");
-    }
-
     public SearchView relationship() {
         String kind = anyTypeKind == AnyTypeKind.USER ? "u" : "a";
         return new SearchView("sv" + kind + "m", field().name + "_" + kind + "relationship");
@@ -147,10 +159,6 @@ class SearchSupport {
         return new SearchView("svdrealm", JPADynRealmDAO.DYNMEMB_TABLE);
     }
 
-    public SearchView nullAttr() {
-        return new SearchView("svna", field().name + "_null_attr");
-    }
-
     public SearchView resource() {
         return new SearchView("svr", field().name + "_resource");
     }
@@ -159,11 +167,14 @@ class SearchSupport {
         return new SearchView("svrr", field().name + "_group_res");
     }
 
-    public SearchView uniqueAttr() {
-        return new SearchView("svua", field().name + "_unique_attr");
-    }
-
     public SearchView entitlements() {
         return new SearchView("sve", field().name + "_entitlements");
     }
+
+    SearchViewSupport asSearchViewSupport() {
+        if (this instanceof SearchViewSupport) {
+            return (SearchViewSupport) this;
+        }
+        throw new IllegalArgumentException("Not an " + SearchViewSupport.class + " instance");
+    }
 }
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/DynRealmCond.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchViewSupport.java
similarity index 59%
copy from core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/DynRealmCond.java
copy to core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchViewSupport.java
index e3f3590..9dc95d8 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/search/DynRealmCond.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchViewSupport.java
@@ -16,24 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.syncope.core.persistence.api.dao.search;
+package org.apache.syncope.core.persistence.jpa.dao;
 
-public class DynRealmCond extends AbstractSearchCond {
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 
-    private static final long serialVersionUID = 9110213614796095482L;
+public class SearchViewSupport extends SearchSupport {
 
-    private String dynRealm;
+    public SearchViewSupport(final AnyTypeKind anyTypeKind) {
+        super(anyTypeKind);
+    }
 
-    public String getDynRealm() {
-        return dynRealm;
+    public SearchView attr() {
+        return new SearchView("sva", field().name + "_attr");
     }
 
-    public void setDynRealm(final String dynRealm) {
-        this.dynRealm = dynRealm;
+    public SearchView nullAttr() {
+        return new SearchView("svna", field().name + "_null_attr");
     }
 
-    @Override
-    public final boolean isValid() {
-        return dynRealm != null;
+    public SearchView uniqueAttr() {
+        return new SearchView("svua", field().name + "_unique_attr");
     }
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java
index 7c9fdf7..93e281e 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java
@@ -18,18 +18,12 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity;
 
-import java.beans.PropertyDescriptor;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-import org.apache.commons.lang3.builder.EqualsBuilder;
-import org.apache.commons.lang3.builder.HashCodeBuilder;
+import java.util.Objects;
 import org.apache.syncope.common.lib.types.ImplementationType;
 import org.apache.syncope.core.persistence.api.entity.Entity;
 import org.apache.syncope.core.persistence.api.entity.Implementation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeanUtils;
 
 public abstract class AbstractEntity implements Entity {
 
@@ -49,31 +43,21 @@ public abstract class AbstractEntity implements Entity {
         }
     }
 
-    /**
-     * @return fields to be excluded when computing equals() or hashcode()
-     */
-    private String[] getExcludeFields() {
-        Set<String> excludeFields = new HashSet<>();
-
-        for (PropertyDescriptor propDesc : BeanUtils.getPropertyDescriptors(getClass())) {
-            if (propDesc.getPropertyType().isInstance(Collections.emptySet())
-                    || propDesc.getPropertyType().isInstance(Collections.emptyList())) {
-
-                excludeFields.add(propDesc.getName());
-            }
-        }
-
-        return excludeFields.toArray(new String[] {});
-    }
-
     @Override
     public boolean equals(final Object obj) {
-        return EqualsBuilder.reflectionEquals(this, obj, getExcludeFields());
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof AbstractEntity)) {
+            return false;
+        }
+        AbstractEntity entity = (AbstractEntity) obj;
+        return Objects.equals(getKey(), entity.getKey());
     }
 
     @Override
     public int hashCode() {
-        return HashCodeBuilder.reflectionHashCode(this, getExcludeFields());
+        return Objects.hash(getKey());
     }
 
     @Override
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractGeneratedKeyEntity.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractGeneratedKeyEntity.java
index c642ea3..c795d07 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractGeneratedKeyEntity.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractGeneratedKeyEntity.java
@@ -19,8 +19,6 @@
 package org.apache.syncope.core.persistence.jpa.entity;
 
 import javax.persistence.Column;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.MappedSuperclass;
 
@@ -30,7 +28,6 @@ public abstract class AbstractGeneratedKeyEntity extends AbstractEntity {
     private static final long serialVersionUID = 4705587655441599524L;
 
     @Id
-    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "uuid")
     @Column(length = 36)
     private String id;
 
@@ -39,4 +36,7 @@ public abstract class AbstractGeneratedKeyEntity extends AbstractEntity {
         return id;
     }
 
+    public void setKey(final String key) {
+        this.id = key;
+    }
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractProvidedKeyEntity.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractProvidedKeyEntity.java
index 3709584..f50f095 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractProvidedKeyEntity.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractProvidedKeyEntity.java
@@ -39,5 +39,4 @@ public abstract class AbstractProvidedKeyEntity extends AbstractEntity implement
     public void setKey(final String key) {
         this.id = key;
     }
-
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java
index 70f62c6..aa86519 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyUtils.java
@@ -21,6 +21,7 @@ package org.apache.syncope.core.persistence.jpa.entity;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -43,25 +44,26 @@ import org.apache.syncope.core.persistence.api.dao.UserDAO;
 import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttr;
-import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrValue;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttr;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrValue;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttr;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -73,19 +75,19 @@ public class JPAAnyUtils implements AnyUtils {
 
     private static final Logger LOG = LoggerFactory.getLogger(AnyUtils.class);
 
-    private static final Set<String> USER_FIELD_NAMES = new HashSet<>();
+    private static final Map<String, Field> USER_FIELDS = new HashMap<>();
 
-    private static final Set<String> GROUP_FIELD_NAMES = new HashSet<>();
+    private static final Map<String, Field> GROUP_FIELDS = new HashMap<>();
 
-    private static final Set<String> ANY_OBJECT_FIELD_NAMES = new HashSet<>();
+    private static final Map<String, Field> ANY_OBJECT_FIELDS = new HashMap<>();
 
     static {
-        initFieldNames(JPAUser.class, USER_FIELD_NAMES);
-        initFieldNames(JPAGroup.class, GROUP_FIELD_NAMES);
-        initFieldNames(JPAAnyObject.class, ANY_OBJECT_FIELD_NAMES);
+        initFieldNames(JPAUser.class, USER_FIELDS);
+        initFieldNames(JPAGroup.class, GROUP_FIELDS);
+        initFieldNames(JPAAnyObject.class, ANY_OBJECT_FIELDS);
     }
 
-    private static void initFieldNames(final Class<?> entityClass, final Set<String> keys) {
+    private static void initFieldNames(final Class<?> entityClass, final Map<String, Field> fields) {
         List<Class<?>> classes = ClassUtils.getAllSuperclasses(entityClass);
         classes.add(entityClass);
         classes.forEach(clazz -> {
@@ -95,16 +97,19 @@ public class JPAAnyUtils implements AnyUtils {
                         && !Collection.class.isAssignableFrom(field.getType())
                         && !Map.class.isAssignableFrom(field.getType())) {
 
-                    keys.add("id".equals(field.getName()) ? "key" : field.getName());
+                    fields.put(field.getName(), field);
+                    if ("id".equals(field.getName())) {
+                        fields.put("key", field);
+                    }
                 }
             }
         });
     }
 
     public static boolean matchesFieldName(final String candidate) {
-        return USER_FIELD_NAMES.contains(candidate)
-                || GROUP_FIELD_NAMES.contains(candidate)
-                || ANY_OBJECT_FIELD_NAMES.contains(candidate);
+        return USER_FIELDS.containsKey(candidate)
+                || GROUP_FIELDS.containsKey(candidate)
+                || ANY_OBJECT_FIELDS.containsKey(candidate);
     }
 
     private final AnyTypeKind anyTypeKind;
@@ -118,6 +123,9 @@ public class JPAAnyUtils implements AnyUtils {
     @Autowired
     private AnyObjectDAO anyObjectDAO;
 
+    @Autowired
+    private EntityFactory entityFactory;
+
     protected JPAAnyUtils(final AnyTypeKind typeKind) {
         this.anyTypeKind = typeKind;
     }
@@ -133,63 +141,47 @@ public class JPAAnyUtils implements AnyUtils {
 
         switch (anyTypeKind) {
             case GROUP:
-                result = JPAGroup.class;
+                result = entityFactory.newEntity(Group.class).getClass();
                 break;
 
             case ANY_OBJECT:
-                result = JPAAnyObject.class;
+                result = entityFactory.newEntity(AnyObject.class).getClass();
                 break;
 
             case USER:
             default:
-                result = JPAUser.class;
+                result = entityFactory.newEntity(User.class).getClass();
         }
 
         return result;
     }
 
     @Override
-    public boolean isFieldName(final String name) {
-        Set<String> names;
+    public Field getField(final String name) {
+        Map<String, Field> fields;
 
         switch (anyTypeKind) {
             case GROUP:
-                names = GROUP_FIELD_NAMES;
+                fields = GROUP_FIELDS;
                 break;
 
             case ANY_OBJECT:
-                names = ANY_OBJECT_FIELD_NAMES;
+                fields = ANY_OBJECT_FIELDS;
                 break;
 
             case USER:
             default:
-                names = USER_FIELD_NAMES;
+                fields = USER_FIELDS;
                 break;
         }
 
-        return names.contains(name);
+        return fields.get(name);
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public <T extends PlainAttr<?>> Class<T> plainAttrClass() {
-        Class result;
-
-        switch (anyTypeKind) {
-            case GROUP:
-                result = JPAGPlainAttr.class;
-                break;
-
-            case ANY_OBJECT:
-                result = JPAAPlainAttr.class;
-                break;
-
-            case USER:
-            default:
-                result = JPAUPlainAttr.class;
-                break;
-        }
-
-        return result;
+        return (Class<T>) newPlainAttr().getClass();
     }
 
     @Override
@@ -198,15 +190,15 @@ public class JPAAnyUtils implements AnyUtils {
 
         switch (anyTypeKind) {
             case USER:
-                result = (T) new JPAUPlainAttr();
+                result = (T) entityFactory.newEntity(UPlainAttr.class);
                 break;
 
             case GROUP:
-                result = (T) new JPAGPlainAttr();
+                result = (T) entityFactory.newEntity(GPlainAttr.class);
                 break;
 
             case ANY_OBJECT:
-                result = (T) new JPAAPlainAttr();
+                result = (T) entityFactory.newEntity(APlainAttr.class);
                 break;
 
             default:
@@ -216,25 +208,9 @@ public class JPAAnyUtils implements AnyUtils {
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public <T extends PlainAttrValue> Class<T> plainAttrValueClass() {
-        Class result;
-
-        switch (anyTypeKind) {
-            case GROUP:
-                result = JPAGPlainAttrValue.class;
-                break;
-
-            case ANY_OBJECT:
-                result = JPAAPlainAttrValue.class;
-                break;
-
-            case USER:
-            default:
-                result = JPAUPlainAttrValue.class;
-                break;
-        }
-
-        return result;
+        return (Class<T>) newPlainAttrValue().getClass();
     }
 
     @Override
@@ -243,15 +219,15 @@ public class JPAAnyUtils implements AnyUtils {
 
         switch (anyTypeKind) {
             case USER:
-                result = (T) new JPAUPlainAttrValue();
+                result = (T) entityFactory.newEntity(UPlainAttrValue.class);
                 break;
 
             case GROUP:
-                result = (T) new JPAGPlainAttrValue();
+                result = (T) entityFactory.newEntity(GPlainAttrValue.class);
                 break;
 
             case ANY_OBJECT:
-                result = (T) new JPAAPlainAttrValue();
+                result = (T) entityFactory.newEntity(APlainAttrValue.class);
                 break;
 
             default:
@@ -261,25 +237,9 @@ public class JPAAnyUtils implements AnyUtils {
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public <T extends PlainAttrValue> Class<T> plainAttrUniqueValueClass() {
-        Class result;
-
-        switch (anyTypeKind) {
-            case GROUP:
-                result = JPAGPlainAttrUniqueValue.class;
-                break;
-
-            case ANY_OBJECT:
-                result = JPAAPlainAttrUniqueValue.class;
-                break;
-
-            case USER:
-            default:
-                result = JPAUPlainAttrUniqueValue.class;
-                break;
-        }
-
-        return result;
+        return (Class<T>) newPlainAttrUniqueValue().getClass();
     }
 
     @Override
@@ -288,15 +248,15 @@ public class JPAAnyUtils implements AnyUtils {
 
         switch (anyTypeKind) {
             case USER:
-                result = (T) new JPAUPlainAttrUniqueValue();
+                result = (T) entityFactory.newEntity(UPlainAttrUniqueValue.class);
                 break;
 
             case GROUP:
-                result = (T) new JPAGPlainAttrUniqueValue();
+                result = (T) entityFactory.newEntity(GPlainAttrUniqueValue.class);
                 break;
 
             case ANY_OBJECT:
-                result = (T) new JPAAPlainAttrUniqueValue();
+                result = (T) entityFactory.newEntity(APlainAttrUniqueValue.class);
                 break;
 
             default:
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnPoolConf.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnPoolConf.java
index 2d40dd4..c871468 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnPoolConf.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAConnPoolConf.java
@@ -91,17 +91,45 @@ public class JPAConnPoolConf implements ConnPoolConf, Serializable {
     }
 
     @Override
-    public boolean equals(final Object obj) {
-        return EqualsBuilder.reflectionEquals(this, obj);
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(maxObjects).
+                append(minIdle).
+                append(maxIdle).
+                append(maxWait).
+                append(minEvictableIdleTimeMillis).
+                build();
     }
 
     @Override
-    public int hashCode() {
-        return HashCodeBuilder.reflectionHashCode(this);
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final JPAConnPoolConf other = (JPAConnPoolConf) obj;
+        return new EqualsBuilder().
+                append(maxObjects, other.maxObjects).
+                append(minIdle, other.minIdle).
+                append(maxIdle, other.maxIdle).
+                append(maxWait, other.maxWait).
+                append(minEvictableIdleTimeMillis, other.minEvictableIdleTimeMillis).
+                build();
     }
 
     @Override
     public String toString() {
-        return ToStringBuilder.reflectionToString(this);
+        return new ToStringBuilder(this).
+                append(maxObjects).
+                append(minIdle).
+                append(maxIdle).
+                append(maxWait).
+                append(minEvictableIdleTimeMillis).
+                build();
     }
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
index 96a333a..79bc299 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
@@ -142,6 +142,7 @@ import org.apache.syncope.core.persistence.jpa.entity.resource.JPAOrgUnitItem;
 import org.apache.syncope.core.persistence.api.entity.policy.PullCorrelationRuleEntity;
 import org.apache.syncope.core.persistence.api.entity.policy.PushCorrelationRuleEntity;
 import org.apache.syncope.core.persistence.jpa.entity.policy.JPAPushCorrelationRuleEntity;
+import org.apache.syncope.core.spring.security.SecureRandomUtils;
 
 @Component
 public class JPAEntityFactory implements EntityFactory {
@@ -303,6 +304,10 @@ public class JPAEntityFactory implements EntityFactory {
             throw new IllegalArgumentException("Could not find a JPA implementation of " + reference.getName());
         }
 
+        if (result instanceof AbstractGeneratedKeyEntity) {
+            ((AbstractGeneratedKeyEntity) result).setKey(SecureRandomUtils.generateRandomUUID().toString());
+        }
+
         return result;
     }
 
@@ -310,5 +315,4 @@ public class JPAEntityFactory implements EntityFactory {
     public ConnPoolConf newConnPoolConf() {
         return new JPAConnPoolConf();
     }
-
 }
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtils.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtils.java
index 0d83523..3f9ee99 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtils.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtils.java
@@ -25,6 +25,7 @@ import org.apache.syncope.common.lib.to.PushTaskTO;
 import org.apache.syncope.common.lib.to.SchedTaskTO;
 import org.apache.syncope.common.lib.to.PullTaskTO;
 import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.task.NotificationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
 import org.apache.syncope.core.persistence.api.entity.task.PushTask;
@@ -32,12 +33,16 @@ import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
 import org.apache.syncope.core.persistence.api.entity.task.Task;
 import org.apache.syncope.core.persistence.api.entity.task.TaskUtils;
 import org.apache.syncope.core.persistence.api.entity.task.PullTask;
+import org.springframework.beans.factory.annotation.Autowired;
 
 @SuppressWarnings("unchecked")
 public final class JPATaskUtils implements TaskUtils {
 
     private final TaskType type;
 
+    @Autowired
+    private EntityFactory entityFactory;
+
     protected JPATaskUtils(final TaskType type) {
         this.type = type;
     }
@@ -84,23 +89,23 @@ public final class JPATaskUtils implements TaskUtils {
 
         switch (type) {
             case PROPAGATION:
-                result = (T) new JPAPropagationTask();
+                result = (T) entityFactory.newEntity(PropagationTask.class);
                 break;
 
             case SCHEDULED:
-                result = (T) new JPASchedTask();
+                result = (T) entityFactory.newEntity(SchedTask.class);
                 break;
 
             case PULL:
-                result = (T) new JPAPullTask();
+                result = (T) entityFactory.newEntity(PullTask.class);
                 break;
 
             case PUSH:
-                result = (T) new JPAPushTask();
+                result = (T) entityFactory.newEntity(PushTask.class);
                 break;
 
             case NOTIFICATION:
-                result = (T) new JPANotificationTask();
+                result = (T) entityFactory.newEntity(NotificationTask.class);
                 break;
 
             default:
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtilsFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtilsFactory.java
index be38e3a..48a77fb 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtilsFactory.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtilsFactory.java
@@ -18,6 +18,8 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity.task;
 
+import java.util.HashMap;
+import java.util.Map;
 import org.apache.syncope.common.lib.to.TaskTO;
 import org.apache.syncope.common.lib.to.NotificationTaskTO;
 import org.apache.syncope.common.lib.to.PropagationTaskTO;
@@ -34,13 +36,26 @@ import org.apache.syncope.core.persistence.api.entity.task.TaskUtils;
 import org.apache.syncope.core.persistence.api.entity.task.TaskUtilsFactory;
 import org.springframework.stereotype.Component;
 import org.apache.syncope.core.persistence.api.entity.task.PullTask;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
 
 @Component
 public class JPATaskUtilsFactory implements TaskUtilsFactory {
 
+    private final Map<TaskType, TaskUtils> instances = new HashMap<>(5);
+
     @Override
     public TaskUtils getInstance(final TaskType type) {
-        return new JPATaskUtils(type);
+        TaskUtils instance;
+        synchronized (instances) {
+            instance = instances.get(type);
+            if (instance == null) {
+                instance = new JPATaskUtils(type);
+                ApplicationContextProvider.getBeanFactory().autowireBean(instance);
+                instances.put(type, instance);
+            }
+        }
+
+        return instance;
     }
 
     @Override
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/openjpa/UUIDGenerator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/openjpa/UUIDGenerator.java
deleted file mode 100644
index bf572fa..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/openjpa/UUIDGenerator.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.openjpa;
-
-import com.fasterxml.uuid.Generators;
-import com.fasterxml.uuid.impl.RandomBasedGenerator;
-import org.apache.openjpa.kernel.Seq;
-import org.apache.openjpa.kernel.StoreContext;
-import org.apache.openjpa.meta.ClassMetaData;
-
-/**
- * Fast UUID generator for OpenJPA entities.
- */
-public class UUIDGenerator implements Seq {
-
-    private static final RandomBasedGenerator GENERATOR = Generators.randomBasedGenerator();
-
-    private String last;
-
-    @Override
-    public void setType(final int i) {
-    }
-
-    @Override
-    public Object next(final StoreContext sc, final ClassMetaData cmd) {
-        last = GENERATOR.generate().toString();
-        return last;
-    }
-
-    @Override
-    public Object current(final StoreContext sc, final ClassMetaData cmd) {
-        return last;
-    }
-
-    @Override
-    public void allocate(final int i, final StoreContext sc, final ClassMetaData cmd) {
-    }
-
-    @Override
-    public void close() {
-    }
-}
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
index da39ce3..0ac2579 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-oracle.xml
@@ -34,8 +34,6 @@ under the License.
     </persistence-unit-defaults>
   </persistence-unit-metadata>
   
-  <sequence-generator name="uuid" sequence-name="org.apache.syncope.core.persistence.jpa.openjpa.UUIDGenerator()"/>
-
   <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrUniqueValue">
     <table>
       <unique-constraint>
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
index 8bcb833..8c52f2e 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm-sqlserver.xml
@@ -34,8 +34,6 @@ under the License.
     </persistence-unit-defaults>
   </persistence-unit-metadata>
 
-  <sequence-generator name="uuid" sequence-name="org.apache.syncope.core.persistence.jpa.openjpa.UUIDGenerator()"/>
-  
   <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrUniqueValue">
     <table>
       <unique-constraint>
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
index c0033a5..aaf42b3 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
@@ -34,8 +34,6 @@ under the License.
     </persistence-unit-defaults>
   </persistence-unit-metadata>
 
-  <sequence-generator name="uuid" sequence-name="org.apache.syncope.core.persistence.jpa.openjpa.UUIDGenerator()"/>
-  
   <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrUniqueValue">
     <table>
       <unique-constraint>
diff --git a/core/persistence-jpa/src/main/resources/views.xml b/core/persistence-jpa/src/main/resources/views.xml
index 37fd431..e8e9a21 100644
--- a/core/persistence-jpa/src/main/resources/views.xml
+++ b/core/persistence-jpa/src/main/resources/views.xml
@@ -265,4 +265,4 @@ under the License.
     FROM SyncopeGroup_ExternalResource st
   </entry>
 
-</properties>
+</properties>
\ No newline at end of file
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
index bac5f53..089b7b4 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnySearchTest.java
@@ -368,7 +368,7 @@ public class AnySearchTest extends AbstractTest {
         usernameLeafCond.setExpression("%ini");
 
         AnyCond idRightCond = new AnyCond(AnyCond.Type.LT);
-        idRightCond.setSchema("id");
+        idRightCond.setSchema("key");
         idRightCond.setExpression("2");
 
         SearchCond searchCondition = SearchCond.getAndCond(
@@ -389,7 +389,7 @@ public class AnySearchTest extends AbstractTest {
         groupNameLeafCond.setExpression("root");
 
         AnyCond idRightCond = new AnyCond(AnyCond.Type.EQ);
-        idRightCond.setSchema("id");
+        idRightCond.setSchema("key");
         idRightCond.setExpression("37d15e4c-cdc1-460b-a591-8505c8133806");
 
         SearchCond searchCondition = SearchCond.getAndCond(
@@ -448,7 +448,7 @@ public class AnySearchTest extends AbstractTest {
     @Test
     public void searchByKey() {
         AnyCond idLeafCond = new AnyCond(AnyCond.Type.EQ);
-        idLeafCond.setSchema("id");
+        idLeafCond.setSchema("key");
         idLeafCond.setExpression("74cd8ece-715a-44a4-a736-e17b46c4e7e6");
 
         SearchCond searchCondition = SearchCond.getLeafCond(idLeafCond);
@@ -605,7 +605,7 @@ public class AnySearchTest extends AbstractTest {
     @Test
     public void issue242() {
         AnyCond cond = new AnyCond(AttributeCond.Type.LIKE);
-        cond.setSchema("id");
+        cond.setSchema("key");
         cond.setExpression("test%");
 
         SearchCond searchCondition = SearchCond.getLeafCond(cond);
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RealmTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RealmTest.java
index 936e822..97eb737 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RealmTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RealmTest.java
@@ -109,7 +109,6 @@ public class RealmTest extends AbstractTest {
         Realm realm = entityFactory.newEntity(Realm.class);
         realm.setName("last");
         realm.setParent(realmDAO.findByFullPath("/even/two"));
-        assertNull(realm.getKey());
 
         Realm actual = realmDAO.save(realm);
         assertNotNull(actual.getKey());
@@ -120,10 +119,8 @@ public class RealmTest extends AbstractTest {
         assertEquals("ce93fcda-dc3a-4369-a7b0-a6108c261c85", realm.getPasswordPolicy().getKey());
 
         realm = actual;
-        realm.setAccountPolicy(
-                (AccountPolicy) policyDAO.find("06e2ed52-6966-44aa-a177-a0ca7434201f"));
-        realm.setPasswordPolicy(
-                (PasswordPolicy) policyDAO.find("986d1236-3ac5-4a19-810c-5ab21d79cba1"));
+        realm.setAccountPolicy((AccountPolicy) policyDAO.find("06e2ed52-6966-44aa-a177-a0ca7434201f"));
+        realm.setPasswordPolicy((PasswordPolicy) policyDAO.find("986d1236-3ac5-4a19-810c-5ab21d79cba1"));
 
         actual = realmDAO.save(realm);
         assertEquals("06e2ed52-6966-44aa-a177-a0ca7434201f", actual.getAccountPolicy().getKey());
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java
index fe4e571..cb2484a 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/RemediationTest.java
@@ -60,7 +60,7 @@ public class RemediationTest extends AbstractTest {
     }
 
     @Test
-    public void create() {
+    public void createMissingPayload() {
         Remediation remediation = entityFactory.newEntity(Remediation.class);
         remediation.setAnyType(anyTypeDAO.find("PRINTER"));
         remediation.setOperation(ResourceOperation.CREATE);
@@ -78,7 +78,17 @@ public class RemediationTest extends AbstractTest {
             assertEquals(2, violations.size());
             assertTrue(violations.stream().allMatch(violation -> violation.getPropertyPath().equals("payload")));
         }
+    }
 
+    @Test
+    public void createWrongPayload() {
+        Remediation remediation = entityFactory.newEntity(Remediation.class);
+        remediation.setAnyType(anyTypeDAO.find("PRINTER"));
+        remediation.setOperation(ResourceOperation.CREATE);
+        remediation.setError("Error");
+        remediation.setInstant(new Date());
+        remediation.setRemoteName("remote");
+        remediation.setPullTask(taskDAO.find("38abbf9e-a1a3-40a1-a15f-7d0ac02f47f1"));
         remediation.setPayload(UUID.randomUUID().toString());
 
         // wrong payload for operation
@@ -90,7 +100,18 @@ public class RemediationTest extends AbstractTest {
             assertEquals(1, violations.size());
             assertTrue(violations.stream().anyMatch(violation -> violation.getPropertyPath().equals("payload")));
         }
+    }
 
+    @Test
+    public void create() {
+        Remediation remediation = entityFactory.newEntity(Remediation.class);
+        remediation.setAnyType(anyTypeDAO.find("PRINTER"));
+        remediation.setOperation(ResourceOperation.CREATE);
+        remediation.setError("Error");
+        remediation.setInstant(new Date());
+        remediation.setRemoteName("remote");
+        remediation.setPullTask(taskDAO.find("38abbf9e-a1a3-40a1-a15f-7d0ac02f47f1"));
+        remediation.setPayload(UUID.randomUUID().toString());
         remediation.setOperation(ResourceOperation.DELETE);
 
         remediation = remediationDAO.save(remediation);
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
index 47f47d8..01d379d 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
@@ -152,13 +152,12 @@ public class UserTest extends AbstractTest {
     }
 
     @Test
-    public void save() {
+    public void saveInvalidPassword() {
         User user = entityFactory.newEntity(User.class);
         user.setUsername("username");
         user.setRealm(realmDAO.findByFullPath("/even/two"));
         user.setCreator("admin");
         user.setCreationDate(new Date());
-
         user.setPassword("pass", CipherAlgorithm.SHA256);
 
         try {
@@ -167,10 +166,16 @@ public class UserTest extends AbstractTest {
         } catch (InvalidEntityException e) {
             assertNotNull(e);
         }
+    }
 
-        user.setPassword("password123", CipherAlgorithm.SHA256);
-
+    @Test
+    public void saveInvalidUsername() {
+        User user = entityFactory.newEntity(User.class);
         user.setUsername("username!");
+        user.setRealm(realmDAO.findByFullPath("/even/two"));
+        user.setCreator("admin");
+        user.setCreationDate(new Date());
+        user.setPassword("password123", CipherAlgorithm.SHA256);
 
         try {
             userDAO.save(user);
@@ -178,8 +183,16 @@ public class UserTest extends AbstractTest {
         } catch (InvalidEntityException e) {
             assertNotNull(e);
         }
+    }
 
+    @Test
+    public void save() {
+        User user = entityFactory.newEntity(User.class);
         user.setUsername("username");
+        user.setRealm(realmDAO.findByFullPath("/even/two"));
+        user.setCreator("admin");
+        user.setCreationDate(new Date());
+        user.setPassword("password123", CipherAlgorithm.SHA256);
 
         User actual = userDAO.save(user);
         assertNotNull(actual);
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ReportTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ReportTest.java
index 9680379..f3ac215 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ReportTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ReportTest.java
@@ -90,12 +90,9 @@ public class ReportTest extends AbstractTest {
         reportExec.setStatus(ReportExecStatus.SUCCESS);
 
         report.add(reportExec);
+        reportDAO.save(report);
 
-        reportExec = reportExecDAO.save(reportExec);
-        assertNotNull(reportExec);
-        assertNotNull(reportExec.getKey());
-
-        reportExecDAO.flush();
+        reportDAO.flush();
 
         report = reportDAO.find("0062ea9c-924d-4ecf-9961-4492a8cc6d1b");
         assertNotNull(report);
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/IntAttrName.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/IntAttrName.java
index c504fd2..e8d5cb4 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/IntAttrName.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/IntAttrName.java
@@ -18,8 +18,9 @@
  */
 package org.apache.syncope.core.provisioning.api;
 
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.apache.commons.lang3.builder.ToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.SchemaType;
 
@@ -136,8 +137,63 @@ public class IntAttrName {
     }
 
     @Override
-    public String toString() {
-        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(anyTypeKind).
+                append(field).
+                append(schemaType).
+                append(schemaName).
+                append(enclosingGroup).
+                append(relatedUser).
+                append(relatedAnyObject).
+                append(membershipOfGroup).
+                append(privilegesOfApplication).
+                append(relationshipType).
+                append(relationshipAnyType).
+                build();
+    }
+
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final IntAttrName other = (IntAttrName) obj;
+        return new EqualsBuilder().
+                append(anyTypeKind, other.anyTypeKind).
+                append(field, other.field).
+                append(schemaType, other.schemaType).
+                append(schemaName, other.schemaName).
+                append(enclosingGroup, other.enclosingGroup).
+                append(relatedUser, other.relatedUser).
+                append(relatedAnyObject, other.relatedAnyObject).
+                append(membershipOfGroup, other.membershipOfGroup).
+                append(privilegesOfApplication, other.privilegesOfApplication).
+                append(relationshipType, other.relationshipType).
+                append(relationshipAnyType, other.relationshipAnyType).
+                build();
     }
 
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this).
+                append(anyTypeKind).
+                append(field).
+                append(schemaType).
+                append(schemaName).
+                append(enclosingGroup).
+                append(relatedUser).
+                append(relatedAnyObject).
+                append(membershipOfGroup).
+                append(privilegesOfApplication).
+                append(relationshipType).
+                append(relationshipAnyType).
+                build();
+    }
 }
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/WorkflowResult.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/WorkflowResult.java
index 472a108..cb59c82 100644
--- a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/WorkflowResult.java
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/WorkflowResult.java
@@ -22,8 +22,7 @@ import java.util.HashSet;
 import java.util.Set;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.commons.lang3.builder.ToStringBuilder;
 
 public class WorkflowResult<T> {
 
@@ -66,17 +65,40 @@ public class WorkflowResult<T> {
     }
 
     @Override
-    public boolean equals(final Object obj) {
-        return EqualsBuilder.reflectionEquals(this, obj);
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(result).
+                append(propByRes).
+                append(performedTasks).
+                build();
     }
 
     @Override
-    public int hashCode() {
-        return HashCodeBuilder.reflectionHashCode(this);
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        @SuppressWarnings("unchecked")
+        final WorkflowResult<T> other = (WorkflowResult<T>) obj;
+        return new EqualsBuilder().
+                append(result, other.result).
+                append(propByRes, other.propByRes).
+                append(performedTasks, other.performedTasks).
+                build();
     }
 
     @Override
     public String toString() {
-        return ReflectionToStringBuilder.toString(this, ToStringStyle.JSON_STYLE);
+        return new ToStringBuilder(this).
+                append(result).
+                append(propByRes).
+                append(performedTasks).
+                build();
     }
 }
diff --git a/core/provisioning-java/pom.xml b/core/provisioning-java/pom.xml
index 442a5ca..c4c04a3 100644
--- a/core/provisioning-java/pom.xml
+++ b/core/provisioning-java/pom.xml
@@ -48,11 +48,6 @@ under the License.
       <groupId>org.apache.commons</groupId>
       <artifactId>commons-jexl3</artifactId>
     </dependency>
-
-    <dependency>
-      <groupId>com.fasterxml.uuid</groupId>
-      <artifactId>java-uuid-generator</artifactId>
-    </dependency>
     
     <dependency>
       <groupId>org.springframework</groupId>
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/IntAttrNameParser.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/IntAttrNameParser.java
index 914d248..0a7a2c0 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/IntAttrNameParser.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/IntAttrNameParser.java
@@ -90,11 +90,11 @@ public class IntAttrNameParser {
             final AnyTypeKind anyTypeKind,
             final IntAttrName result) {
 
-        if (anyUtilsFactory.getInstance(anyTypeKind).isFieldName(fieldOrSchemaName)) {
-            result.setField(fieldOrSchemaName);
-        } else {
+        if (anyUtilsFactory.getInstance(anyTypeKind).getField(fieldOrSchemaName) == null) {
             result.setSchemaType(find(fieldOrSchemaName));
             result.setSchemaName(fieldOrSchemaName);
+        } else {
+            result.setField(fieldOrSchemaName);
         }
     }
 
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
index 351d21d..f6ec55f 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/AccessTokenDataBinderImpl.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.provisioning.java.data;
 
-import com.fasterxml.uuid.Generators;
-import com.fasterxml.uuid.impl.RandomBasedGenerator;
 import java.util.Date;
 import java.util.Map;
 import javax.annotation.Resource;
@@ -38,6 +36,7 @@ import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.provisioning.api.data.AccessTokenDataBinder;
 import org.apache.syncope.core.spring.BeanUtils;
 import org.apache.syncope.core.spring.security.DefaultCredentialChecker;
+import org.apache.syncope.core.spring.security.SecureRandomUtils;
 import org.apache.syncope.core.spring.security.jws.AccessTokenJwsSignatureProvider;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -45,8 +44,6 @@ import org.springframework.stereotype.Component;
 @Component
 public class AccessTokenDataBinderImpl implements AccessTokenDataBinder {
 
-    private static final RandomBasedGenerator UUID_GENERATOR = Generators.randomBasedGenerator();
-
     @Resource(name = "adminUser")
     private String adminUser;
 
@@ -134,7 +131,7 @@ public class AccessTokenDataBinderImpl implements AccessTokenDataBinder {
         if (accessToken == null) {
             // no AccessToken found: create new
             accessToken = entityFactory.newEntity(AccessToken.class);
-            accessToken.setKey(UUID_GENERATOR.generate().toString());
+            accessToken.setKey(SecureRandomUtils.generateRandomUUID().toString());
 
             accessToken = replace(subject, claims, authorities, accessToken);
         } else if (replace) {
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
index 333311c..6cd5e8e 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/ConnInstanceDataBinderImpl.java
@@ -19,7 +19,6 @@
 package org.apache.syncope.core.provisioning.java.data;
 
 import java.net.URI;
-import org.apache.syncope.core.provisioning.api.data.ConnInstanceDataBinder;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -44,6 +43,7 @@ import org.apache.syncope.core.persistence.api.entity.ConnInstanceHistoryConf;
 import org.apache.syncope.core.persistence.api.entity.EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.Realm;
 import org.apache.syncope.core.provisioning.api.ConnIdBundleManager;
+import org.apache.syncope.core.provisioning.api.data.ConnInstanceDataBinder;
 import org.apache.syncope.core.provisioning.api.utils.ConnPoolConfUtils;
 import org.identityconnectors.framework.api.ConfigurationProperties;
 import org.identityconnectors.framework.api.ConfigurationProperty;
@@ -57,7 +57,7 @@ import org.springframework.stereotype.Component;
 @Component
 public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
 
-    private static final String[] IGNORE_PROPERTIES = { "poolConf", "location", "adminRealm", "conf" };
+    private static final String[] IGNORE_PROPERTIES = { "key", "poolConf", "location", "adminRealm", "conf" };
 
     @Autowired
     private ConnIdBundleManager connIdBundleManager;
@@ -246,6 +246,7 @@ public class ConnInstanceDataBinderImpl implements ConnInstanceDataBinder {
 
         Pair<URI, ConnectorInfo> info = connIdBundleManager.getConnectorInfo(connInstance);
         BeanUtils.copyProperties(connInstance, connInstanceTO, IGNORE_PROPERTIES);
+        connInstanceTO.setKey(connInstance.getKey());
         connInstanceTO.setAdminRealm(connInstance.getAdminRealm().getFullPath());
         connInstanceTO.setLocation(info.getLeft().toASCIIString());
         connInstanceTO.getConf().addAll(connInstance.getConf());
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AfterHandlingJob.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AfterHandlingJob.java
index 4e53077..82f6d42 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AfterHandlingJob.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/job/AfterHandlingJob.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.provisioning.java.job;
 
-import com.fasterxml.uuid.Generators;
-import com.fasterxml.uuid.impl.RandomBasedGenerator;
 import java.util.Map;
 import org.apache.syncope.core.provisioning.api.AuditManager;
 import org.apache.syncope.core.provisioning.api.event.AfterHandlingEvent;
@@ -28,6 +26,7 @@ import org.apache.syncope.core.provisioning.api.job.JobNamer;
 import org.apache.syncope.core.provisioning.api.notification.NotificationManager;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.SecureRandomUtils;
 import org.quartz.JobBuilder;
 import org.quartz.JobDataMap;
 import org.quartz.JobExecutionContext;
@@ -50,13 +49,11 @@ public class AfterHandlingJob extends AbstractInterruptableJob {
 
     private static final Logger LOG = LoggerFactory.getLogger(AfterHandlingJob.class);
 
-    private static final RandomBasedGenerator UUID_GENERATOR = Generators.randomBasedGenerator();
-
     public static void schedule(final SchedulerFactoryBean scheduler, final Map<String, Object> jobMap) {
         @SuppressWarnings("unchecked")
         AfterHandlingJob jobInstance = (AfterHandlingJob) ApplicationContextProvider.getBeanFactory().
                 createBean(AfterHandlingJob.class, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
-        String jobName = AfterHandlingJob.class.getName() + UUID_GENERATOR.generate();
+        String jobName = AfterHandlingJob.class.getName() + SecureRandomUtils.generateRandomUUID();
 
         jobMap.put(JobManager.DOMAIN_KEY, AuthContextUtils.getDomain());
 
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SchedulingPullActions.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SchedulingPullActions.java
index 4320b9a..c7b0bea 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SchedulingPullActions.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/pushpull/SchedulingPullActions.java
@@ -18,14 +18,13 @@
  */
 package org.apache.syncope.core.provisioning.java.pushpull;
 
-import com.fasterxml.uuid.Generators;
-import com.fasterxml.uuid.impl.RandomBasedGenerator;
 import java.util.Map;
 import org.apache.syncope.core.provisioning.api.job.JobManager;
 import org.apache.syncope.core.provisioning.api.job.JobNamer;
 import org.apache.syncope.core.provisioning.api.pushpull.PullActions;
 import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
+import org.apache.syncope.core.spring.security.SecureRandomUtils;
 import org.quartz.Job;
 import org.quartz.JobBuilder;
 import org.quartz.JobDataMap;
@@ -44,8 +43,6 @@ import org.springframework.scheduling.quartz.SchedulerFactoryBean;
  */
 public abstract class SchedulingPullActions implements PullActions {
 
-    private static final RandomBasedGenerator UUID_GENERATOR = Generators.randomBasedGenerator();
-
     @Autowired
     protected SchedulerFactoryBean scheduler;
 
@@ -55,7 +52,7 @@ public abstract class SchedulingPullActions implements PullActions {
         @SuppressWarnings("unchecked")
         T jobInstance = (T) ApplicationContextProvider.getBeanFactory().
                 createBean(reference, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
-        String jobName = getClass().getName() + UUID_GENERATOR.generate();
+        String jobName = getClass().getName() + SecureRandomUtils.generateRandomUUID();
 
         jobMap.put(JobManager.DOMAIN_KEY, AuthContextUtils.getDomain());
 
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
index 59a451a..2d8c3b4 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractAnyService.java
@@ -53,6 +53,7 @@ import org.apache.syncope.core.persistence.api.dao.AnyDAO;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.spring.security.SecureRandomUtils;
 
 public abstract class AbstractAnyService<TO extends AnyTO, P extends AnyPatch>
         extends AbstractServiceImpl
@@ -279,7 +280,7 @@ public abstract class AbstractAnyService<TO extends AnyTO, P extends AnyPatch>
                     }).collect(Collectors.toList());
         }
 
-        String boundary = "deassociate_" + GENERATOR.generate().toString();
+        String boundary = "deassociate_" + SecureRandomUtils.generateRandomUUID().toString();
         return Response.ok(BatchPayloadGenerator.generate(
                 batchResponseItems, SyncopeConstants.DOUBLE_DASH + boundary)).
                 type(RESTHeaders.multipartMixedWith(boundary)).
@@ -368,7 +369,7 @@ public abstract class AbstractAnyService<TO extends AnyTO, P extends AnyPatch>
                     }).collect(Collectors.toList());
         }
 
-        String boundary = "associate_" + GENERATOR.generate().toString();
+        String boundary = "associate_" + SecureRandomUtils.generateRandomUUID().toString();
         return Response.ok(BatchPayloadGenerator.generate(
                 batchResponseItems, SyncopeConstants.DOUBLE_DASH + boundary)).
                 type(RESTHeaders.multipartMixedWith(boundary)).
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractExecutableService.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractExecutableService.java
index 569da48..48d238c 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractExecutableService.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractExecutableService.java
@@ -34,6 +34,7 @@ import org.apache.syncope.common.rest.api.beans.ExecQuery;
 import org.apache.syncope.common.rest.api.beans.ExecuteQuery;
 import org.apache.syncope.common.rest.api.service.ExecutableService;
 import org.apache.syncope.core.logic.AbstractExecutableLogic;
+import org.apache.syncope.core.spring.security.SecureRandomUtils;
 
 public abstract class AbstractExecutableService extends AbstractServiceImpl implements ExecutableService {
 
@@ -68,7 +69,7 @@ public abstract class AbstractExecutableService extends AbstractServiceImpl impl
                 query.getEndedBefore(),
                 query.getEndedAfter());
 
-        String boundary = "deleteExecutions_" + GENERATOR.generate().toString();
+        String boundary = "deleteExecutions_" + SecureRandomUtils.generateRandomUUID().toString();
         return Response.ok(BatchPayloadGenerator.generate(
                 batchResponseItems, SyncopeConstants.DOUBLE_DASH + boundary)).
                 type(RESTHeaders.multipartMixedWith(boundary)).
diff --git a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
index c92e7a2..2e9a0c0 100644
--- a/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
+++ b/core/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/AbstractServiceImpl.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.rest.cxf.service;
 
-import com.fasterxml.uuid.Generators;
-import com.fasterxml.uuid.impl.RandomBasedGenerator;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -58,8 +56,6 @@ abstract class AbstractServiceImpl implements JAXRSService {
 
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractServiceImpl.class);
 
-    protected static final RandomBasedGenerator GENERATOR = Generators.randomBasedGenerator();
-
     protected static final String OPTIONS_ALLOW = "GET,POST,OPTIONS,HEAD";
 
     @Context
diff --git a/core/spring/pom.xml b/core/spring/pom.xml
index cb60ce5..94ee57f 100644
--- a/core/spring/pom.xml
+++ b/core/spring/pom.xml
@@ -78,6 +78,11 @@ under the License.
     </dependency>
 
     <dependency>
+      <groupId>com.fasterxml.uuid</groupId>
+      <artifactId>java-uuid-generator</artifactId>
+    </dependency>
+
+    <dependency>
       <groupId>org.apache.syncope.core</groupId>
       <artifactId>syncope-core-provisioning-api</artifactId>
       <version>${project.version}</version>
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecureRandomUtils.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecureRandomUtils.java
index daf093a..5d9eeac 100644
--- a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecureRandomUtils.java
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SecureRandomUtils.java
@@ -18,7 +18,10 @@
  */
 package org.apache.syncope.core.spring.security;
 
+import com.fasterxml.uuid.Generators;
+import com.fasterxml.uuid.impl.RandomBasedGenerator;
 import java.security.SecureRandom;
+import java.util.UUID;
 import org.apache.commons.text.RandomStringGenerator;
 
 public final class SecureRandomUtils {
@@ -41,6 +44,8 @@ public final class SecureRandomUtils {
             withinRange('0', '9').
             build();
 
+    private static final RandomBasedGenerator UUID_GENERATOR = Generators.randomBasedGenerator(RANDOM);
+
     public static String generateRandomPassword(final int tokenLength) {
         return FOR_PASSWORD.generate(tokenLength);
     }
@@ -70,6 +75,10 @@ public final class SecureRandomUtils {
                 }).build().generate(1);
     }
 
+    public static UUID generateRandomUUID() {
+        return UUID_GENERATOR.generate();
+    }
+
     private SecureRandomUtils() {
         // private constructor for static utility class
     }
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetails.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetails.java
index cfd1eec..de86f94 100644
--- a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetails.java
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeAuthenticationDetails.java
@@ -23,8 +23,7 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.syncope.common.lib.SyncopeConstants;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 
@@ -49,18 +48,33 @@ public class SyncopeAuthenticationDetails implements Serializable {
     }
 
     @Override
-    public boolean equals(final Object obj) {
-        return EqualsBuilder.reflectionEquals(this, obj);
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(domain).
+                build();
     }
 
     @Override
-    public int hashCode() {
-        return HashCodeBuilder.reflectionHashCode(this);
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final SyncopeAuthenticationDetails other = (SyncopeAuthenticationDetails) obj;
+        return new EqualsBuilder().
+                append(domain, other.domain).
+                build();
     }
 
     @Override
     public String toString() {
-        return ReflectionToStringBuilder.toString(this, ToStringStyle.JSON_STYLE);
+        return new ToStringBuilder(this).
+                append(domain).
+                build();
     }
-
 }
diff --git a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeGrantedAuthority.java b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeGrantedAuthority.java
index c9ba8d3..9e2c29a 100644
--- a/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeGrantedAuthority.java
+++ b/core/spring/src/main/java/org/apache/syncope/core/spring/security/SyncopeGrantedAuthority.java
@@ -27,8 +27,7 @@ import java.util.Set;
 import java.util.TreeSet;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
-import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
-import org.apache.commons.lang3.builder.ToStringStyle;
+import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.syncope.core.provisioning.api.utils.RealmUtils;
 import org.springframework.security.core.GrantedAuthority;
 
@@ -70,18 +69,36 @@ public class SyncopeGrantedAuthority implements GrantedAuthority {
     }
 
     @Override
-    public boolean equals(final Object obj) {
-        return EqualsBuilder.reflectionEquals(this, obj);
+    public int hashCode() {
+        return new HashCodeBuilder().
+                append(entitlement).
+                append(realms).
+                build();
     }
 
     @Override
-    public int hashCode() {
-        return HashCodeBuilder.reflectionHashCode(this);
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final SyncopeGrantedAuthority other = (SyncopeGrantedAuthority) obj;
+        return new EqualsBuilder().
+                append(entitlement, other.entitlement).
+                append(realms, other.realms).
+                build();
     }
 
     @Override
     public String toString() {
-        return ReflectionToStringBuilder.toString(this, ToStringStyle.JSON_STYLE);
+        return new ToStringBuilder(this).
+                append(entitlement).
+                append(realms).
+                build();
     }
-
 }
diff --git a/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAO.java b/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAO.java
index de070f1..89f7ac2 100644
--- a/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAO.java
+++ b/ext/elasticsearch/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/ElasticsearchAnySearchDAO.java
@@ -63,7 +63,6 @@ import org.elasticsearch.index.query.QueryBuilder;
 import org.elasticsearch.index.query.QueryBuilders;
 import org.elasticsearch.search.sort.SortOrder;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.util.ReflectionUtils;
 
 /**
  * Search engine implementation for users, groups and any objects, based on Elasticsearch.
@@ -143,7 +142,7 @@ public class ElasticsearchAnySearchDAO extends AbstractAnySearchDAO {
             final AnyTypeKind kind,
             final List<OrderByClause> orderBy) {
 
-        AnyUtils attrUtils = anyUtilsFactory.getInstance(kind);
+        AnyUtils anyUtils = anyUtilsFactory.getInstance(kind);
 
         orderBy.forEach(clause -> {
             String sortName = null;
@@ -151,7 +150,7 @@ public class ElasticsearchAnySearchDAO extends AbstractAnySearchDAO {
             // Manage difference among external key attribute and internal JPA @Id
             String fieldName = "key".equals(clause.getField()) ? "id" : clause.getField();
 
-            Field anyField = ReflectionUtils.findField(attrUtils.anyClass(), fieldName);
+            Field anyField = anyUtils.getField(fieldName);
             if (anyField == null) {
                 PlainSchema schema = schemaDAO.find(fieldName);
                 if (schema != null) {
diff --git a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableRuntimeUtils.java b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableRuntimeUtils.java
index e02f017..9ff621c 100644
--- a/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableRuntimeUtils.java
+++ b/ext/flowable/flowable-bpmn/src/main/java/org/apache/syncope/core/flowable/impl/FlowableRuntimeUtils.java
@@ -215,6 +215,8 @@ public final class FlowableRuntimeUtils {
             throw (ParsingValidationException) e.getCause();
         } else if (e.getCause() instanceof InvalidEntityException) {
             throw (InvalidEntityException) e.getCause();
+        } else if (e.getCause().getClass().getName().contains("persistence")) {
+            throw (RuntimeException) e.getCause();
         }
 
         throw new WorkflowException(defaultMessage, e);
diff --git a/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/OIDCClientLogic.java b/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/OIDCClientLogic.java
index 12ca5fa..5141c6f 100644
--- a/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/OIDCClientLogic.java
+++ b/ext/oidcclient/logic/src/main/java/org/apache/syncope/core/logic/OIDCClientLogic.java
@@ -19,8 +19,6 @@
 package org.apache.syncope.core.logic;
 
 import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
-import com.fasterxml.uuid.Generators;
-import com.fasterxml.uuid.impl.RandomBasedGenerator;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.Method;
@@ -67,6 +65,7 @@ import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.security.AuthDataAccessor;
 import org.apache.syncope.core.spring.security.Encryptor;
+import org.apache.syncope.core.spring.security.SecureRandomUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Component;
@@ -74,14 +73,12 @@ import org.springframework.stereotype.Component;
 @Component
 public class OIDCClientLogic extends AbstractTransactionalLogic<AbstractBaseBean> {
 
-    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
-
-    private static final RandomBasedGenerator UUID_GENERATOR = Generators.randomBasedGenerator();
-
     private static final String JWT_CLAIM_OP_ENTITYID = "OP_ENTITYID";
 
     private static final String JWT_CLAIM_USERID = "USERID";
 
+    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
     @Autowired
     private AuthDataAccessor authDataAccessor;
 
@@ -124,7 +121,7 @@ public class OIDCClientLogic extends AbstractTransactionalLogic<AbstractBaseBean
         requestTO.setScope("openid email profile");
         requestTO.setResponseType(OAuthConstants.CODE_RESPONSE_TYPE);
         requestTO.setRedirectURI(redirectURI);
-        requestTO.setState(UUID_GENERATOR.generate().toString());
+        requestTO.setState(SecureRandomUtils.generateRandomUUID().toString());
         return requestTO;
     }
 
diff --git a/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCEntityFactory.java b/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCEntityFactory.java
index e5870bf..81608bb 100644
--- a/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCEntityFactory.java
+++ b/ext/oidcclient/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAOIDCEntityFactory.java
@@ -23,6 +23,7 @@ import org.apache.syncope.core.persistence.api.entity.OIDCEntityFactory;
 import org.apache.syncope.core.persistence.api.entity.OIDCProvider;
 import org.apache.syncope.core.persistence.api.entity.OIDCProviderItem;
 import org.apache.syncope.core.persistence.api.entity.OIDCUserTemplate;
+import org.apache.syncope.core.spring.security.SecureRandomUtils;
 import org.springframework.stereotype.Component;
 
 @Component
@@ -43,7 +44,10 @@ public class JPAOIDCEntityFactory implements OIDCEntityFactory {
             throw new IllegalArgumentException("Could not find a JPA implementation of " + reference.getName());
         }
 
+        if (result instanceof AbstractGeneratedKeyEntity) {
+            ((AbstractGeneratedKeyEntity) result).setKey(SecureRandomUtils.generateRandomUUID().toString());
+        }
+
         return result;
     }
-
 }
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
index 4ae24d7..b660b27 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.core.logic;
 
-import com.fasterxml.uuid.Generators;
-import com.fasterxml.uuid.impl.RandomBasedGenerator;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.lang.reflect.Method;
@@ -104,6 +102,7 @@ import org.apache.syncope.core.spring.ApplicationContextProvider;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.apache.syncope.core.spring.security.AuthDataAccessor;
 import org.apache.syncope.core.spring.security.Encryptor;
+import org.apache.syncope.core.spring.security.SecureRandomUtils;
 import org.opensaml.core.xml.schema.XSAny;
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
 import org.springframework.util.ResourceUtils;
@@ -125,8 +124,6 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
 
     private static final String JWT_CLAIM_SESSIONINDEX = "SESSIONINDEX";
 
-    private static final RandomBasedGenerator UUID_GENERATOR = Generators.randomBasedGenerator();
-
     private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
 
     @Autowired
@@ -310,7 +307,7 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
         }
 
         AuthnRequest authnRequest = new AuthnRequestBuilder().buildObject();
-        authnRequest.setID("_" + UUID_GENERATOR.generate().toString());
+        authnRequest.setID("_" + SecureRandomUtils.generateRandomUUID().toString());
         authnRequest.setForceAuthn(false);
         authnRequest.setIsPassive(false);
         authnRequest.setVersion(SAMLVersion.VERSION_20);
@@ -329,7 +326,8 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
             Map<String, Object> claims = new HashMap<>();
             claims.put(JWT_CLAIM_IDP_DEFLATE, idp.isUseDeflateEncoding());
             Pair<String, Date> relayState = accessTokenDataBinder.generateJWT(
-                    UUID_GENERATOR.generate().toString(), authnRequest.getID(), JWT_RELAY_STATE_DURATION, claims);
+                    SecureRandomUtils.generateRandomUUID().toString(),
+                    authnRequest.getID(), JWT_RELAY_STATE_DURATION, claims);
 
             // 4. sign and encode AuthnRequest
             switch (idp.getBindingType()) {
@@ -582,7 +580,7 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
 
         // 3. create LogoutRequest
         LogoutRequest logoutRequest = new LogoutRequestBuilder().buildObject();
-        logoutRequest.setID("_" + UUID_GENERATOR.generate().toString());
+        logoutRequest.setID("_" + SecureRandomUtils.generateRandomUUID().toString());
         logoutRequest.setDestination(idp.getSLOLocation(idp.getBindingType()).getLocation());
 
         DateTime now = new DateTime();
@@ -611,7 +609,8 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
             claims.put(JWT_CLAIM_IDP_DEFLATE,
                     idp.getBindingType() == SAML2BindingType.REDIRECT ? true : idp.isUseDeflateEncoding());
             Pair<String, Date> relayState = accessTokenDataBinder.generateJWT(
-                    UUID_GENERATOR.generate().toString(), logoutRequest.getID(), JWT_RELAY_STATE_DURATION, claims);
+                    SecureRandomUtils.generateRandomUUID().toString(),
+                    logoutRequest.getID(), JWT_RELAY_STATE_DURATION, claims);
             requestTO.setRelayState(relayState.getLeft());
 
             // 4. sign and encode AuthnRequest
diff --git a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java
index 888e870..bd17ac4 100644
--- a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java
+++ b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java
@@ -23,6 +23,7 @@ import org.apache.syncope.core.persistence.api.entity.SAML2EntityFactory;
 import org.apache.syncope.core.persistence.api.entity.SAML2IdP;
 import org.apache.syncope.core.persistence.api.entity.SAML2IdPItem;
 import org.apache.syncope.core.persistence.api.entity.SAML2UserTemplate;
+import org.apache.syncope.core.spring.security.SecureRandomUtils;
 import org.springframework.stereotype.Component;
 
 @Component
@@ -43,6 +44,10 @@ public class JPASAML2EntityFactory implements SAML2EntityFactory {
             throw new IllegalArgumentException("Could not find a JPA implementation of " + reference.getName());
         }
 
+        if (result instanceof AbstractGeneratedKeyEntity) {
+            ((AbstractGeneratedKeyEntity) result).setKey(SecureRandomUtils.generateRandomUUID().toString());
+        }
+
         return result;
     }
 }
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java
index ddd48fe..037bc59 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java
@@ -47,5 +47,4 @@ public class TestAccountRule implements AccountRule {
             throw new AccountPolicyException("Username not containing " + this.conf.getMustContainSubstring());
         }
     }
-
 }
diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java
index 69431ef..aeb8bf4 100644
--- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java
+++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java
@@ -43,15 +43,13 @@ public class TestPasswordRule implements PasswordRule {
             throw new IllegalArgumentException(
                     PasswordRuleConf.class.getName() + " expected, got " + conf.getClass().getName());
         }
-
     }
 
     @Transactional(readOnly = true)
     @Override
     public void enforce(final User user) {
-        if (!user.getClearPassword().endsWith(this.conf.getMustEndWith())) {
+        if (user.getClearPassword() != null && !user.getClearPassword().endsWith(this.conf.getMustEndWith())) {
             throw new PasswordPolicyException("Password not ending with " + this.conf.getMustEndWith());
         }
     }
-
 }
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
index cd4940f..6358b08 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/UserITCase.java
@@ -315,7 +315,7 @@ public class UserITCase extends AbstractITCase {
         assertNotNull(newUserTO.getCreator());
         assertNotNull(newUserTO.getLastChangeDate());
         assertNotNull(newUserTO.getLastModifier());
-        assertEquals(newUserTO.getCreationDate(), newUserTO.getLastChangeDate());
+        assertTrue(newUserTO.getLastChangeDate().getTime() - newUserTO.getCreationDate().getTime() < 3000);
 
         assertFalse(newUserTO.getPlainAttrs().contains(attrWithInvalidSchemaTO));