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 2019/01/10 07:07:18 UTC

[syncope] branch SYNCOPE-1400_SYNCOPE-1401 updated (44ae13b -> e59d745)

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

ilgrosso pushed a change to branch SYNCOPE-1400_SYNCOPE-1401
in repository https://gitbox.apache.org/repos/asf/syncope.git.


 discard 44ae13b  [SYNCOPE-1400] Adding support for MySQL 8 via OpenJPA 3.0.1 + [SYNCOPE-1401] Adding support for MySQL with JSON type
     add 7e4e6db  [SYNCOPE-1418] Added harmless spring lazy loading on some shared DAO beans
     add 79964a9  [SYNCOPE-1420] Replacing expired access tokens upon login
     add 880bbdf  Upgrading Tika and maven-jar-plugin
     add 8944569  Attempt to get longer builds on Travis CI
     add b7c49f3  [SYNCOPE-1416] fixes searches for unique attributes
     add 772167f  [SYNCOPE-1402] (Temporary?) switching to hibernate-validator
     add 49a6f86  [SYNCOPE-1422] permits to provide custom AuditManager/NotificationManager implementation
     add 460fedd  [SYNCOPE-1422] Aligning names with the rest
     add de52b42  Upgrading Groovy
     add f6649e3  It's 2019
     add dff4747  Upgrading maven-assembly-plugin
     add ff5984b  Upgrading HikariCP
     add 972a8cb  [SYNCOPE-1422] Forgot to update
     add 7f07c58  [SYNCOPE-1424] changes the way to build the task search query and fixes some test weeknesses
     new d9176e3  Upgrading Spring
     new e59d745  [SYNCOPE-1400] Adding support for MySQL 8 via OpenJPA 3.0.1 + [SYNCOPE-1401] Adding support for MySQL with JSON type

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (44ae13b)
            \
             N -- N -- N   refs/heads/SYNCOPE-1400_SYNCOPE-1401 (e59d745)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .travis.yml                                        |  2 +-
 NOTICE                                             |  2 +-
 client/cli/NOTICE                                  |  2 +-
 client/console/NOTICE                              |  2 +-
 core/persistence-jpa/pom.xml                       |  8 +-
 .../core/persistence/jpa/dao/AbstractAnyDAO.java   |  4 +
 .../core/persistence/jpa/dao/JPAAnySearchDAO.java  | 12 ++-
 .../core/persistence/jpa/dao/JPAPolicyDAO.java     |  3 +
 .../core/persistence/jpa/dao/JPARealmDAO.java      |  2 +
 .../core/persistence/jpa/dao/JPATaskDAO.java       | 92 +++++++++++-----------
 .../core/persistence/jpa/dao/JPAVirSchemaDAO.java  |  2 +
 .../core/persistence/jpa/inner/AnySearchTest.java  | 19 +++++
 .../api/notification/NotificationManager.java      |  2 +
 ...itManagerImpl.java => DefaultAuditManager.java} |  4 +-
 .../java/data/AccessTokenDataBinderImpl.java       |  4 +-
 .../java/job/AbstractSchedTaskJobDelegate.java     |  1 +
 .../DefaultNotificationJobDelegate.java            |  2 +
 ...erImpl.java => DefaultNotificationManager.java} |  7 +-
 .../AbstractPropagationTaskExecutor.java           |  6 +-
 .../java/pushpull/AbstractPullResultHandler.java   |  4 +-
 .../pushpull/DefaultRealmPullResultHandler.java    |  4 +-
 .../src/main/resources/provisioning.properties     |  2 +
 .../src/main/resources/provisioningContext.xml     |  2 +
 core/upgrade/NOTICE                                |  2 +-
 deb/console/NOTICE                                 |  2 +-
 deb/core/NOTICE                                    |  2 +-
 deb/enduser/NOTICE                                 |  2 +-
 .../src/main/resources/provisioning.properties     |  2 +
 .../apache/syncope/core/flowable/task/Notify.java  |  2 +
 fit/build-tools/NOTICE                             |  2 +-
 fit/core-reference/pom.xml                         | 11 ---
 .../src/main/resources/all/provisioning.properties |  2 +
 .../resources/mariadb/domains/Master.properties    |  2 +-
 .../main/resources/mariadb/provisioning.properties |  2 +
 .../main/resources/mysql/provisioning.properties   |  2 +
 .../main/resources/oracle/provisioning.properties  |  2 +
 .../main/resources/pgjsonb/provisioning.properties |  2 +
 .../resources/postgres/provisioning.properties     |  2 +
 .../src/main/resources/provisioning.properties     |  2 +
 .../resources/sqlserver/provisioning.properties    |  2 +
 .../org/apache/syncope/fit/core/JWTITCase.java     | 38 +++++++++
 .../syncope/fit/core/PropagationTaskITCase.java    |  6 +-
 .../apache/syncope/fit/core/PullTaskITCase.java    |  3 +-
 .../org/apache/syncope/fit/core/SearchITCase.java  | 43 +++++++---
 ide/eclipse/NOTICE                                 |  2 +-
 ide/netbeans/NOTICE                                |  2 +-
 installer/NOTICE                                   |  2 +-
 pom.xml                                            | 37 ++++-----
 .../asciidoc/reference-guide/concepts/tasks.adoc   |  4 +-
 src/site/site.xml                                  |  2 +-
 standalone/NOTICE                                  |  2 +-
 51 files changed, 245 insertions(+), 127 deletions(-)
 rename core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/{AuditManagerImpl.java => DefaultAuditManager.java} (97%)
 rename core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/notification/{NotificationManagerImpl.java => DefaultNotificationManager.java} (99%)


[syncope] 01/02: Upgrading Spring

Posted by il...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch SYNCOPE-1400_SYNCOPE-1401
in repository https://gitbox.apache.org/repos/asf/syncope.git

commit d9176e3f0b74151a5749ec852bac2c7c376529ea
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Thu Jan 10 08:05:39 2019 +0100

    Upgrading Spring
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 67f5142..a6579f2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -393,7 +393,7 @@ under the License.
 
     <jackson.version>2.9.8</jackson.version>
 
-    <spring.version>5.1.3.RELEASE</spring.version>
+    <spring.version>5.1.4.RELEASE</spring.version>
     <spring-security.version>5.1.2.RELEASE</spring-security.version>
 
     <openjpa.version>3.0.0</openjpa.version>


[syncope] 02/02: [SYNCOPE-1400] Adding support for MySQL 8 via OpenJPA 3.0.1 + [SYNCOPE-1401] Adding support for MySQL with JSON type

Posted by il...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch SYNCOPE-1400_SYNCOPE-1401
in repository https://gitbox.apache.org/repos/asf/syncope.git

commit e59d7455c1f180b92dee32297c15899e034071b8
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Mon Dec 3 13:18:36 2018 +0100

    [SYNCOPE-1400] Adding support for MySQL 8 via OpenJPA 3.0.1 + [SYNCOPE-1401] Adding support for MySQL with JSON type
---
 core/persistence-jpa-json/pom.xml                  | 129 ++++++---
 ...AJSONAnyDAO.java => AbstractJPAJSONAnyDAO.java} |  81 ++----
 .../jpa/dao/AbstractJPAJSONAnySearchDAO.java       |  87 ++++++
 .../core/persistence/jpa/dao/MyJPAJSONAnyDAO.java  | 120 ++++++++
 ...nySearchDAO.java => MyJPAJSONAnySearchDAO.java} | 145 ++--------
 .../core/persistence/jpa/dao/PGJPAJSONAnyDAO.java  | 305 ++-------------------
 .../persistence/jpa/dao/PGJPAJSONAnySearchDAO.java |  92 +------
 .../jpa/entity/JPAJSONEntityFactory.java           |   3 +-
 .../jpa/entity/MyJPAJSONEntityFactory.java         |  37 +++
 .../main/resources/META-INF/spring-orm-myjson.xml  | 137 +++++++++
 .../resources/myjson}/domains/Master.properties    |   8 +-
 .../src/main/resources/myjson/indexes.xml          |  58 ++++
 .../main/resources/myjson/persistence.properties   |  23 +-
 .../src/main/resources/myjson/views.xml            | 181 ++++++++++++
 .../{pgjsonb => }/domains/MasterContent.xml        |   0
 .../core/persistence/jpa/dao/JPAAnySearchDAO.java  |  40 ++-
 .../core/persistence/jpa/dao/SearchSupport.java    |  33 ---
 .../main/resources/audit/audit_mysql_innodb.sql    |   2 +-
 .../core/persistence/jpa/inner/AnyTypeTest.java    |   2 +
 fit/core-reference/pom.xml                         | 168 +++++++++++-
 .../{mysql => myjson}/domains/Master.properties    |   8 +-
 .../{mysql => myjson}/provisioning.properties      |   4 +-
 .../main/resources/mysql/domains/Master.properties |   6 +-
 .../main/resources/mysql/provisioning.properties   |   2 +-
 pom.xml                                            |   5 +-
 25 files changed, 1022 insertions(+), 654 deletions(-)

diff --git a/core/persistence-jpa-json/pom.xml b/core/persistence-jpa-json/pom.xml
index dfd7bb2..0331a27 100644
--- a/core/persistence-jpa-json/pom.xml
+++ b/core/persistence-jpa-json/pom.xml
@@ -227,10 +227,6 @@ under the License.
             <filtering>true</filtering>
           </testResource>
           <testResource>
-            <directory>src/test/resources/pgjsonb</directory>
-            <filtering>true</filtering>
-          </testResource>
-          <testResource>
             <directory>src/main/resources</directory>
             <filtering>true</filtering>
           </testResource>
@@ -243,62 +239,119 @@ under the License.
     </profile>
     
     <profile>
-      <id>sqlgen</id>
-      
-      <properties>
-        <skipTests>true</skipTests>
-      </properties>
+      <id>mysql</id>
       
+      <dependencies>
+        <dependency>
+          <groupId>mysql</groupId>
+          <artifactId>mysql-connector-java</artifactId>
+          <version>${jdbc.mysql.version}</version>
+          <scope>test</scope>
+        </dependency>
+      </dependencies>
+
       <build>
         <defaultGoal>clean verify</defaultGoal>
         
         <plugins>
           <plugin>
-            <groupId>org.apache.openjpa</groupId>
-            <artifactId>openjpa-maven-plugin</artifactId>
-            <inherited>true</inherited>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>build-helper-maven-plugin</artifactId>
             <executions>
               <execution>
-                <id>sqlgen</id>
-                <phase>process-classes</phase>
+                <id>add-test-source</id>
+                <phase>generate-test-sources</phase>
                 <goals>
-                  <goal>sql</goal>
+                  <goal>add-test-source</goal>
                 </goals>
+                <configuration>
+                  <sources>
+                    <source>${basedir}/../persistence-jpa/src/test/java</source>
+                  </sources>
+                </configuration>
               </execution>
             </executions>
-          </plugin>          
-        </plugins>
-      </build>
-    </profile>
-    
-    <profile>
-      <id>schemagen</id>
-      
-      <properties>
-        <skipTests>true</skipTests>
-      </properties>
+          </plugin>
       
-      <build>
-        <defaultGoal>clean verify</defaultGoal>
-        
-        <plugins>
           <plugin>
-            <groupId>org.apache.openjpa</groupId>
-            <artifactId>openjpa-maven-plugin</artifactId>
-            <inherited>true</inherited>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <configuration>
+              <skip>true</skip>
+            </configuration>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-failsafe-plugin</artifactId>
+            <configuration>
+              <includes>
+                <include>**/*Test.java</include>
+              </includes>
+              <excludedGroups>multitenancy,plainAttrTable</excludedGroups>
+            </configuration>
+          </plugin>
+
+          <plugin>
+            <groupId>io.fabric8</groupId>
+            <artifactId>docker-maven-plugin</artifactId>
+            <configuration>
+              <images>
+                <image>
+                  <name>mysql/mysql-server:${docker.mysql.version}</name>
+                  <run>
+                    <cmd>--skip-log-bin --server-id=1</cmd>
+                    <env>
+                      <MYSQL_ROOT_PASSWORD>password</MYSQL_ROOT_PASSWORD>
+                      <MYSQL_DATABASE>syncope</MYSQL_DATABASE>
+                      <MYSQL_USER>syncope</MYSQL_USER>
+                      <MYSQL_PASSWORD>syncope</MYSQL_PASSWORD>
+                    </env>
+                    <ports>
+                      <port>3306:3306</port>
+                    </ports>
+                    <wait>
+                      <log>MySQL init process done. Ready for start up.</log>
+                      <time>30000</time>
+                    </wait>
+                  </run>
+                </image>
+              </images>
+            </configuration>
             <executions>
               <execution>
-                <id>schemagen</id>
-                <phase>process-classes</phase>
+                <id>start-mysql</id>
+                <phase>pre-integration-test</phase>
+                <goals>
+                  <goal>start</goal>
+                </goals>
+              </execution>
+              <execution>
+                <id>stop-mysql</id>
+                <phase>post-integration-test</phase>
                 <goals>
-                  <goal>schema</goal>
+                  <goal>stop</goal>
+                  <goal>remove</goal>
                 </goals>
               </execution>
             </executions>
-          </plugin>          
+          </plugin>
         </plugins>
+        
+        <testResources>
+          <testResource>
+            <directory>src/test/resources</directory>
+            <filtering>true</filtering>
+          </testResource>
+          <testResource>
+            <directory>src/main/resources</directory>
+            <filtering>true</filtering>
+          </testResource>
+          <testResource>
+            <directory>src/main/resources/myjson</directory>
+            <filtering>true</filtering>
+          </testResource>
+        </testResources>
       </build>
     </profile>
   </profiles>
-
 </project>
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONAnyDAO.java
similarity index 81%
copy from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java
copy to core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONAnyDAO.java
index 94bb72a..f0bca9a 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONAnyDAO.java
@@ -20,40 +20,37 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.io.StringReader;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
-import java.util.StringJoiner;
 import java.util.regex.Pattern;
 import javax.persistence.Query;
 import org.apache.commons.jexl3.parser.Parser;
 import org.apache.commons.jexl3.parser.ParserConstants;
 import org.apache.commons.jexl3.parser.Token;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.DuplicateException;
+import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
 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.DerSchema;
-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.JSONPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractEntity;
-import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.spring.security.AuthContextUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Transactional;
-import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr;
-import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO;
 
-@Repository
-public class PGJPAJSONAnyDAO extends AbstractDAO<AbstractEntity> implements JPAJSONAnyDAO {
+abstract class AbstractJPAJSONAnyDAO extends AbstractDAO<AbstractEntity> implements JPAJSONAnyDAO {
 
     @Autowired
     private PlainSchemaDAO plainSchemaDAO;
@@ -61,22 +58,19 @@ public class PGJPAJSONAnyDAO extends AbstractDAO<AbstractEntity> implements JPAJ
     @Autowired
     private DerSchemaDAO derSchemaDAO;
 
-    private String queryBegin(final String table) {
-        return "SELECT DISTINCT id FROM " + table + " u,"
-                + "jsonb_array_elements(u.plainAttrs) attrs,"
-                + "jsonb_array_elements(COALESCE(attrs -> 'values', '[{}]'::jsonb)) attrValues ";
-    }
+    protected abstract String queryBegin(String table);
 
-    private String attrValueMatch(
-            final AnyUtils anyUtils,
-            final PlainSchema schema,
-            final PlainAttrValue attrValue,
-            final boolean ignoreCaseMatch) {
+    protected abstract String attrValueMatch(
+            AnyUtils anyUtils,
+            PlainSchema schema,
+            PlainAttrValue attrValue,
+            boolean ignoreCaseMatch);
 
+    protected Pair<String, Boolean> schemaInfo(final AttrSchemaType schemaType, final boolean ignoreCaseMatch) {
         String key;
         boolean lower = false;
 
-        switch (schema.getType()) {
+        switch (schemaType) {
             case Boolean:
                 key = "booleanValue";
                 break;
@@ -102,29 +96,10 @@ public class PGJPAJSONAnyDAO extends AbstractDAO<AbstractEntity> implements JPAJ
                 key = "stringValue";
         }
 
-        if (lower) {
-            return "attrs ->> 'schema' = ? "
-                    + "AND "
-                    + (lower ? "LOWER(" : "")
-                    + (schema.isUniqueConstraint() ? "attrs -> 'uniqueValue'" : "attrValues") + " ->> '" + key
-                    + "'" + (lower ? ")" : "")
-                    + " = "
-                    + (lower ? "LOWER(" : "")
-                    + "?"
-                    + (lower ? ")" : "");
-        } else {
-            PlainAttr<?> container = anyUtils.newPlainAttr();
-            container.setSchema(schema);
-            if (attrValue instanceof PlainAttrUniqueValue) {
-                container.setUniqueValue((PlainAttrUniqueValue) attrValue);
-            } else {
-                ((JSONPlainAttr) container).add(attrValue);
-            }
-            return "plainAttrs @> '" + POJOHelper.serialize(Arrays.asList(container)) + "'::jsonb";
-        }
+        return Pair.of(key, lower);
     }
 
-    private <A extends Any<?>> List<A> buildResult(final AnyUtils anyUtils, final List<Object> queryResult) {
+    protected <A extends Any<?>> List<A> buildResult(final AnyUtils anyUtils, final List<Object> queryResult) {
         List<A> result = new ArrayList<>();
         queryResult.forEach(anyKey -> {
             A any = anyUtils.<A>dao().find(anyKey.toString());
@@ -210,6 +185,8 @@ public class PGJPAJSONAnyDAO extends AbstractDAO<AbstractEntity> implements JPAJ
         return attrValues;
     }
 
+    protected abstract List<Object> findByDerAttrValue(String table, Map<String, List<Object>> clauses);
+
     @SuppressWarnings("unchecked")
     @Transactional(readOnly = true)
     @Override
@@ -272,7 +249,7 @@ public class PGJPAJSONAnyDAO extends AbstractDAO<AbstractEntity> implements JPAJ
             return Collections.emptyList();
         }
 
-        StringJoiner clauses = new StringJoiner(" AND id IN ");
+        Map<String, List<Object>> clauses = new LinkedHashMap<>();
 
         // builder to build the clauses
         StringBuilder bld = new StringBuilder();
@@ -280,8 +257,6 @@ public class PGJPAJSONAnyDAO extends AbstractDAO<AbstractEntity> implements JPAJ
         // Contains used identifiers in order to avoid replications
         Set<String> used = new HashSet<>();
 
-        List<Object> queryParams = new ArrayList<>();
-
         // Create several clauses: one for eanch identifiers
         for (int i = 0; i < identifiers.size(); i++) {
             if (!used.contains(identifiers.get(i))) {
@@ -306,25 +281,21 @@ public class PGJPAJSONAnyDAO extends AbstractDAO<AbstractEntity> implements JPAJ
                             append("WHERE ").
                             append(attrValueMatch(anyUtils, schema, attrValue, ignoreCaseMatch)).
                             append(')');
-                    queryParams.add(schema.getKey());
-                    queryParams.add(attrValues.get(i));
 
                     used.add(identifiers.get(i));
 
-                    clauses.add(bld.toString());
+                    List<Object> queryParams = new ArrayList<>();
+                    queryParams.add(schema.getKey());
+                    queryParams.add(attrValues.get(i));
+
+                    clauses.put(bld.toString(), queryParams);
                 }
             }
         }
 
         LOG.debug("Generated where clauses {}", clauses);
 
-        Query query = entityManager().createNativeQuery(
-                "SELECT DISTINCT id FROM " + table + " u WHERE id IN " + clauses.toString());
-        for (int i = 0; i < queryParams.size(); i++) {
-            query.setParameter(i + 1, queryParams.get(i));
-        }
-
-        return buildResult(anyUtils, query.getResultList());
+        return buildResult(anyUtils, findByDerAttrValue(table, clauses));
     }
 
     @Transactional
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONAnySearchDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONAnySearchDAO.java
new file mode 100644
index 0000000..7dbf95d
--- /dev/null
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractJPAJSONAnySearchDAO.java
@@ -0,0 +1,87 @@
+/*
+ * 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.dao;
+
+import org.apache.commons.lang3.time.FastDateFormat;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+
+abstract class AbstractJPAJSONAnySearchDAO extends JPAAnySearchDAO {
+
+    protected static final FastDateFormat DATE_FORMAT =
+            FastDateFormat.getInstance(SyncopeConstants.DEFAULT_DATE_PATTERN);
+
+    @Override
+    SearchSupport buildSearchSupport(final AnyTypeKind kind) {
+        return new SearchSupport(kind);
+    }
+
+    protected void appendOp(final StringBuilder query, final AttributeCond.Type condType, final boolean not) {
+        switch (condType) {
+            case LIKE:
+            case ILIKE:
+                if (not) {
+                    query.append("NOT ");
+                }
+                query.append(" LIKE ");
+                break;
+
+            case GE:
+                if (not) {
+                    query.append('<');
+                } else {
+                    query.append(">=");
+                }
+                break;
+
+            case GT:
+                if (not) {
+                    query.append("<=");
+                } else {
+                    query.append('>');
+                }
+                break;
+
+            case LE:
+                if (not) {
+                    query.append('>');
+                } else {
+                    query.append("<=");
+                }
+                break;
+
+            case LT:
+                if (not) {
+                    query.append(">=");
+                } else {
+                    query.append('<');
+                }
+                break;
+
+            case EQ:
+            case IEQ:
+            default:
+                if (not) {
+                    query.append('!');
+                }
+                query.append('=');
+        }
+    }
+}
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnyDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnyDAO.java
new file mode 100644
index 0000000..e15e690
--- /dev/null
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnyDAO.java
@@ -0,0 +1,120 @@
+/*
+ * 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.dao;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+import javax.persistence.Query;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+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.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr;
+
+public class MyJPAJSONAnyDAO extends AbstractJPAJSONAnyDAO {
+
+    @Override
+    protected String queryBegin(final String table) {
+        String view = StringUtils.containsIgnoreCase(table, AnyTypeKind.USER.name())
+                ? "user_search"
+                : StringUtils.containsIgnoreCase(table, AnyTypeKind.GROUP.name())
+                ? "group_search"
+                : "anyObject_search";
+        return "SELECT DISTINCT id FROM " + view + " ";
+    }
+
+    @Override
+    protected String attrValueMatch(
+            final AnyUtils anyUtils,
+            final PlainSchema schema,
+            final PlainAttrValue attrValue,
+            final boolean ignoreCaseMatch) {
+
+        Pair<String, Boolean> schemaInfo = schemaInfo(schema.getType(), ignoreCaseMatch);
+        if (schemaInfo.getRight()) {
+            return "plainSchema = ? "
+                    + "AND "
+                    + (schemaInfo.getRight() ? "LOWER(" : "")
+                    + (schema.isUniqueConstraint()
+                    ? "attrUniqueValue ->> '$." + schemaInfo.getLeft() + "'"
+                    : schemaInfo.getLeft())
+                    + (schemaInfo.getRight() ? ")" : "")
+                    + " = "
+                    + (schemaInfo.getRight() ? "LOWER(" : "")
+                    + "?"
+                    + (schemaInfo.getRight() ? ")" : "");
+        } else {
+            PlainAttr<?> container = anyUtils.newPlainAttr();
+            container.setSchema(schema);
+            if (attrValue instanceof PlainAttrUniqueValue) {
+                container.setUniqueValue((PlainAttrUniqueValue) attrValue);
+            } else {
+                ((JSONPlainAttr) container).add(attrValue);
+            }
+            return "JSON_CONTAINS(plainAttrs, '" + POJOHelper.serialize(Arrays.asList(container)) + "')";
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * This method is a workaround for a bug experienced with MySQL 8.0.13, where the correct implementation (as shown
+     * in PGJPAJSONAnyDAO.findByDerAttrValue(String, Map&lt;String, List&lt;Object&gt;&gt;)) generates a core dump.
+     */
+    @Override
+    @SuppressWarnings("unchecked")
+    protected List<Object> findByDerAttrValue(
+            final String table,
+            final Map<String, List<Object>> clauses) {
+
+        if (clauses.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        Set<Object> result = new HashSet<>();
+        AtomicReference<Boolean> first = new AtomicReference<>(Boolean.TRUE);
+        clauses.forEach((clause, parameters) -> {
+            Query query = entityManager().createNativeQuery(StringUtils.replaceIgnoreCase(clause, "DISTINCT", ""));
+            for (int i = 0; i < parameters.size(); i++) {
+                query.setParameter(i + 1, parameters.get(i));
+            }
+
+            Set<Object> local = new HashSet<>(query.getResultList());
+            if (first.get()) {
+                result.addAll(local);
+                first.set(Boolean.FALSE);
+            } else {
+                result.retainAll(local);
+            }
+        });
+
+        return new ArrayList<>(result);
+    }
+}
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnySearchDAO.java
similarity index 63%
copy from core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java
copy to core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnySearchDAO.java
index dd34269..d33701f 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/MyJPAJSONAnySearchDAO.java
@@ -18,15 +18,11 @@
  */
 package org.apache.syncope.core.persistence.jpa.dao;
 
-import java.text.ParseException;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
-import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
 import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
@@ -39,14 +35,7 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr;
 
-public class PGJPAJSONAnySearchDAO extends JPAAnySearchDAO {
-
-    private static final FastDateFormat DATE_FORMAT = FastDateFormat.getInstance(SyncopeConstants.DEFAULT_DATE_PATTERN);
-
-    @Override
-    SearchSupport buildSearchSupport(final AnyTypeKind kind) {
-        return new SearchSupport(kind);
-    }
+public class MyJPAJSONAnySearchDAO extends AbstractJPAJSONAnySearchDAO {
 
     @Override
     protected void processOBS(
@@ -72,12 +61,12 @@ public class PGJPAJSONAnySearchDAO extends JPAAnySearchDAO {
                         } else {
                             attrWhere.append(" OR ");
                         }
-                        attrWhere.append("plainAttrs @> '[{\"schema\":\"").append(field).append("\"}]'::jsonb");
+                        attrWhere.append("JSON_CONTAINS(plainAttrs, '[{\"schema\":\"").append(field).append("\"}]'");
 
                         nullAttrWhere.append(" UNION SELECT DISTINCT any_id,").append(svs.table().alias).append(".*, ").
-                                append("'{\"schema\": \"").
+                                append("JSON('{\"schema\": \"").
                                 append(field).
-                                append("\"}'::jsonb as attrs, '{}'::jsonb as attrValues").
+                                append("\"})' as attrs, JSON('{}') as attrValues").
                                 append(" FROM ").append(svs.table().name).append(" ").append(svs.table().alias).
                                 append(", ").append(svs.field().name).
                                 append(" WHERE ").
@@ -85,7 +74,7 @@ public class PGJPAJSONAnySearchDAO extends JPAAnySearchDAO {
                                 append("(SELECT distinct any_id FROM ").
                                 append(svs.field().name).
                                 append(" WHERE ").append(svs.table().alias).append(".id=any_id AND ").
-                                append("plainAttrs @> '[{\"schema\":\"").append(field).append("\"}]'::jsonb)");
+                                append("JSON_CONTAINS(plainAttrs, '[{\"schema\":\"").append(field).append("\"}]')");
                     });
                     where.append(attrWhere).append(nullAttrWhere);
                 }
@@ -98,36 +87,6 @@ public class PGJPAJSONAnySearchDAO extends JPAAnySearchDAO {
         });
     }
 
-    private String key(final AttrSchemaType schemaType) {
-        String key;
-        switch (schemaType) {
-            case Boolean:
-                key = "booleanValue";
-                break;
-
-            case Date:
-                key = "dateValue";
-                break;
-
-            case Double:
-                key = "doubleValue";
-                break;
-
-            case Long:
-                key = "longValue";
-                break;
-
-            case Binary:
-                key = "binaryValue";
-                break;
-
-            default:
-                key = "stringValue";
-        }
-
-        return key;
-    }
-
     @Override
     protected void parseOrderByForPlainSchema(
             final SearchSupport svs,
@@ -142,8 +101,10 @@ public class PGJPAJSONAnySearchDAO extends JPAAnySearchDAO {
 
         obs.views.add(svs.field());
 
-        item.select = svs.field().alias + ".attrValues ->> '" + key(schema.getType()) + "' AS " + fieldName;
-        item.where = "attrs ->> 'schema' = '" + fieldName + "'";
+        item.select = svs.field().alias + "."
+                + (schema.isUniqueConstraint() ? "attrUniqueValue" : key(schema.getType()))
+                + " AS " + fieldName;
+        item.where = "plainSchema = '" + fieldName + "'";
         item.orderBy = fieldName + " " + clause.getDirection().name();
     }
 
@@ -167,10 +128,6 @@ public class PGJPAJSONAnySearchDAO extends JPAAnySearchDAO {
             fillAttrQuery(anyUtils, query, attrValue, schema, cond, false, parameters, svs);
             query.append(")");
         } else {
-            String key = key(schema.getType());
-            boolean lower = (schema.getType() == AttrSchemaType.String || schema.getType() == AttrSchemaType.Enum)
-                    && (cond.getType() == AttributeCond.Type.IEQ || cond.getType() == AttributeCond.Type.ILIKE);
-
             if (!not && cond.getType() == AttributeCond.Type.EQ) {
                 PlainAttr<?> container = anyUtils.newPlainAttr();
                 container.setSchema(schema);
@@ -180,78 +137,26 @@ public class PGJPAJSONAnySearchDAO extends JPAAnySearchDAO {
                     ((JSONPlainAttr) container).add(attrValue);
                 }
 
-                query.append("plainAttrs @> '").
+                query.append("JSON_CONTAINS(plainAttrs, '").
                         append(POJOHelper.serialize(Arrays.asList(container))).
-                        append("'::jsonb");
+                        append("')");
             } else {
-                query.append("attrs ->> 'schema' = ?").append(setParameter(parameters, cond.getSchema())).
+                String key = key(schema.getType());
+                boolean lower = (schema.getType() == AttrSchemaType.String || schema.getType() == AttrSchemaType.Enum)
+                        && (cond.getType() == AttributeCond.Type.IEQ || cond.getType() == AttributeCond.Type.ILIKE);
+
+                query.append("plainSchema = ?").append(setParameter(parameters, cond.getSchema())).
                         append(" AND ").
                         append(lower ? "LOWER(" : "").
                         append(schema.isUniqueConstraint()
-                                ? "attrs -> 'uniqueValue'" : "attrValues").
-                        append(" ->> '").append(key).append("'").
+                                ? "attrUniqueValue ->> '$." + key + "'"
+                                : key).
                         append(lower ? ")" : "");
 
-                switch (cond.getType()) {
-                    case LIKE:
-                    case ILIKE:
-                        if (not) {
-                            query.append("NOT ");
-                        }
-                        query.append(" LIKE ");
-                        break;
-
-                    case GE:
-                        if (not) {
-                            query.append('<');
-                        } else {
-                            query.append(">=");
-                        }
-                        break;
-
-                    case GT:
-                        if (not) {
-                            query.append("<=");
-                        } else {
-                            query.append('>');
-                        }
-                        break;
+                appendOp(query, cond.getType(), not);
 
-                    case LE:
-                        if (not) {
-                            query.append('>');
-                        } else {
-                            query.append("<=");
-                        }
-                        break;
-
-                    case LT:
-                        if (not) {
-                            query.append(">=");
-                        } else {
-                            query.append('<');
-                        }
-                        break;
-
-                    case EQ:
-                    case IEQ:
-                    default:
-                        if (not) {
-                            query.append('!');
-                        }
-                        query.append('=');
-                }
-
-                String value = cond.getExpression();
-                if (schema.getType() == AttrSchemaType.Date) {
-                    try {
-                        value = String.valueOf(DATE_FORMAT.parse(value).getTime());
-                    } catch (ParseException e) {
-                        LOG.error("Could not parse {} as date", value, e);
-                    }
-                }
                 query.append(lower ? "LOWER(" : "").
-                        append("?").append(setParameter(parameters, value)).
+                        append("?").append(setParameter(parameters, cond.getExpression())).
                         append(lower ? ")" : "");
             }
         }
@@ -284,17 +189,15 @@ public class PGJPAJSONAnySearchDAO extends JPAAnySearchDAO {
                 new StringBuilder("SELECT DISTINCT any_id FROM ").append(svs.field().name).append(" WHERE ");
         switch (cond.getType()) {
             case ISNOTNULL:
-                query.append("plainAttrs @> '[{\"schema\":\"").
+                query.append("JSON_SEARCH(plainAttrs, 'one', '").
                         append(checked.getLeft().getKey()).
-                        append("\"}]'::jsonb");
+                        append("', NULL, '$[*].schema') IS NOT NULL");
                 break;
 
             case ISNULL:
-                query.append("any_id NOT IN (").
-                        append("SELECT any_id FROM ").append(svs.field().name).
-                        append(" WHERE plainAttrs @> '[{\"schema\":\"").
+                query.append("JSON_SEARCH(plainAttrs, 'one', '").
                         append(checked.getLeft().getKey()).
-                        append("\"}]'::jsonb)");
+                        append("', NULL, '$[*].schema') IS NULL");
                 break;
 
             default:
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java
index 94bb72a..ed1664b 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnyDAO.java
@@ -18,100 +18,49 @@
  */
 package org.apache.syncope.core.persistence.jpa.dao;
 
-import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
+import java.util.Map;
 import java.util.StringJoiner;
-import java.util.regex.Pattern;
 import javax.persistence.Query;
-import org.apache.commons.jexl3.parser.Parser;
-import org.apache.commons.jexl3.parser.ParserConstants;
-import org.apache.commons.jexl3.parser.Token;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
-import org.apache.syncope.core.persistence.api.dao.DuplicateException;
-import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
 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.jpa.entity.AbstractEntity;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
-import org.apache.syncope.core.spring.security.AuthContextUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Repository;
-import org.springframework.transaction.annotation.Transactional;
 import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr;
-import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO;
 
-@Repository
-public class PGJPAJSONAnyDAO extends AbstractDAO<AbstractEntity> implements JPAJSONAnyDAO {
+public class PGJPAJSONAnyDAO extends AbstractJPAJSONAnyDAO {
 
-    @Autowired
-    private PlainSchemaDAO plainSchemaDAO;
-
-    @Autowired
-    private DerSchemaDAO derSchemaDAO;
-
-    private String queryBegin(final String table) {
+    @Override
+    protected String queryBegin(final String table) {
         return "SELECT DISTINCT id FROM " + table + " u,"
                 + "jsonb_array_elements(u.plainAttrs) attrs,"
                 + "jsonb_array_elements(COALESCE(attrs -> 'values', '[{}]'::jsonb)) attrValues ";
     }
 
-    private String attrValueMatch(
+    @Override
+    protected String attrValueMatch(
             final AnyUtils anyUtils,
             final PlainSchema schema,
             final PlainAttrValue attrValue,
             final boolean ignoreCaseMatch) {
 
-        String key;
-        boolean lower = false;
-
-        switch (schema.getType()) {
-            case Boolean:
-                key = "booleanValue";
-                break;
-
-            case Date:
-                key = "dateValue";
-                break;
-
-            case Double:
-                key = "doubleValue";
-                break;
-
-            case Long:
-                key = "longValue";
-                break;
-
-            case Binary:
-                key = "binaryValue";
-                break;
-
-            default:
-                lower = ignoreCaseMatch;
-                key = "stringValue";
-        }
-
-        if (lower) {
+        Pair<String, Boolean> schemaInfo = schemaInfo(schema.getType(), ignoreCaseMatch);
+        if (schemaInfo.getRight()) {
             return "attrs ->> 'schema' = ? "
                     + "AND "
-                    + (lower ? "LOWER(" : "")
-                    + (schema.isUniqueConstraint() ? "attrs -> 'uniqueValue'" : "attrValues") + " ->> '" + key
-                    + "'" + (lower ? ")" : "")
+                    + (schemaInfo.getRight() ? "LOWER(" : "")
+                    + (schema.isUniqueConstraint() ? "attrs -> 'uniqueValue'" : "attrValues")
+                    + " ->> '" + schemaInfo.getLeft()
+                    + "'" + (schemaInfo.getRight() ? ")" : "")
                     + " = "
-                    + (lower ? "LOWER(" : "")
+                    + (schemaInfo.getRight() ? "LOWER(" : "")
                     + "?"
-                    + (lower ? ")" : "");
+                    + (schemaInfo.getRight() ? ")" : "");
         } else {
             PlainAttr<?> container = anyUtils.newPlainAttr();
             container.setSchema(schema);
@@ -124,232 +73,26 @@ public class PGJPAJSONAnyDAO extends AbstractDAO<AbstractEntity> implements JPAJ
         }
     }
 
-    private <A extends Any<?>> List<A> buildResult(final AnyUtils anyUtils, final List<Object> queryResult) {
-        List<A> result = new ArrayList<>();
-        queryResult.forEach(anyKey -> {
-            A any = anyUtils.<A>dao().find(anyKey.toString());
-            if (any == null) {
-                LOG.error("Could not find any for key {}", anyKey);
-            } else {
-                result.add(any);
-            }
-        });
-        return result;
-    }
-
-    @SuppressWarnings("unchecked")
-    @Transactional(readOnly = true)
     @Override
-    public <A extends Any<?>> List<A> findByPlainAttrValue(
-            final String table,
-            final AnyUtils anyUtils,
-            final String schemaKey,
-            final PlainAttrValue attrValue,
-            final boolean ignoreCaseMatch) {
-
-        PlainSchema schema = plainSchemaDAO.find(schemaKey);
-        if (schema == null) {
-            LOG.error("Invalid schema '{}'", schemaKey);
-            return Collections.<A>emptyList();
-        }
-
-        Query query = entityManager().createNativeQuery(
-                queryBegin(table)
-                + "WHERE " + attrValueMatch(anyUtils, schema, attrValue, ignoreCaseMatch));
-        query.setParameter(1, schemaKey);
-        query.setParameter(2, attrValue.getValue());
-
-        return buildResult(anyUtils, query.getResultList());
-    }
-
-    @Transactional(readOnly = true)
-    @Override
-    public <A extends Any<?>> A findByPlainAttrUniqueValue(
-            final String table,
-            final AnyUtils anyUtils,
-            final String schemaKey,
-            final PlainAttrValue attrUniqueValue,
-            final boolean ignoreCaseMatch) {
-
-        PlainSchema schema = plainSchemaDAO.find(schemaKey);
-        if (schema == null) {
-            LOG.error("Invalid schema '{}'", schemaKey);
-            return null;
-        }
-        if (!schema.isUniqueConstraint()) {
-            LOG.error("This schema has not unique constraint: '{}'", schemaKey);
-            return null;
-        }
-
-        List<A> result = findByPlainAttrValue(table, anyUtils, schemaKey, attrUniqueValue, ignoreCaseMatch);
-        return result.isEmpty()
-                ? null
-                : result.get(0);
-    }
-
-    /**
-     * Split an attribute value recurring on provided literals/tokens.
-     *
-     * @param attrValue value to be split
-     * @param literals literals/tokens
-     * @return split value
-     */
-    private List<String> split(final String attrValue, final List<String> literals) {
-        final List<String> attrValues = new ArrayList<>();
-
-        if (literals.isEmpty()) {
-            attrValues.add(attrValue);
-        } else {
-            for (String token : attrValue.split(Pattern.quote(literals.get(0)))) {
-                if (!token.isEmpty()) {
-                    attrValues.addAll(split(token, literals.subList(1, literals.size())));
-                }
-            }
-        }
-
-        return attrValues;
-    }
-
     @SuppressWarnings("unchecked")
-    @Transactional(readOnly = true)
-    @Override
-    public <A extends Any<?>> List<A> findByDerAttrValue(
+    protected List<Object> findByDerAttrValue(
             final String table,
-            final AnyUtils anyUtils,
-            final String schemaKey,
-            final String value,
-            final boolean ignoreCaseMatch) {
-
-        DerSchema derSchema = derSchemaDAO.find(schemaKey);
-        if (derSchema == null) {
-            LOG.error("Invalid schema '{}'", schemaKey);
-            return Collections.<A>emptyList();
-        }
-
-        Parser parser = new Parser(new StringReader(derSchema.getExpression()));
-
-        // Schema keys
-        List<String> identifiers = new ArrayList<>();
-
-        // Literals
-        List<String> literals = new ArrayList<>();
-
-        // Get schema keys and literals
-        for (Token token = parser.getNextToken(); token != null && StringUtils.isNotBlank(token.toString());
-                token = parser.getNextToken()) {
-
-            if (token.kind == ParserConstants.STRING_LITERAL) {
-                literals.add(token.toString().substring(1, token.toString().length() - 1));
-            }
-
-            if (token.kind == ParserConstants.IDENTIFIER) {
-                identifiers.add(token.toString());
-            }
-        }
-
-        // Sort literals in order to process later literals included into others
-        Collections.sort(literals, (l1, l2) -> {
-            if (l1 == null && l2 == null) {
-                return 0;
-            } else if (l1 != null && l2 == null) {
-                return -1;
-            } else if (l1 == null && l2 != null) {
-                return 1;
-            } else if (l1.length() == l2.length()) {
-                return 0;
-            } else if (l1.length() > l2.length()) {
-                return -1;
-            } else {
-                return 1;
-            }
-        });
-
-        // Split value on provided literals
-        List<String> attrValues = split(value, literals);
-
-        if (attrValues.size() != identifiers.size()) {
-            LOG.error("Ambiguous JEXL expression resolution: literals and values have different size");
-            return Collections.emptyList();
-        }
-
-        StringJoiner clauses = new StringJoiner(" AND id IN ");
-
-        // builder to build the clauses
-        StringBuilder bld = new StringBuilder();
-
-        // Contains used identifiers in order to avoid replications
-        Set<String> used = new HashSet<>();
+            final Map<String, List<Object>> clauses) {
 
+        StringJoiner actualClauses = new StringJoiner(" AND id IN ");
         List<Object> queryParams = new ArrayList<>();
 
-        // Create several clauses: one for eanch identifiers
-        for (int i = 0; i < identifiers.size(); i++) {
-            if (!used.contains(identifiers.get(i))) {
-                // verify schema existence and get schema type
-                PlainSchema schema = plainSchemaDAO.find(identifiers.get(i));
-                if (schema == null) {
-                    LOG.error("Invalid schema '{}', ignoring", identifiers.get(i));
-                } else {
-                    // clear builder
-                    bld.delete(0, bld.length());
-
-                    PlainAttrValue attrValue;
-                    if (schema.isUniqueConstraint()) {
-                        attrValue = anyUtils.newPlainAttrUniqueValue();
-                    } else {
-                        attrValue = anyUtils.newPlainAttrValue();
-                    }
-                    attrValue.setStringValue(attrValues.get(i));
-
-                    bld.append('(').
-                            append(queryBegin(table)).
-                            append("WHERE ").
-                            append(attrValueMatch(anyUtils, schema, attrValue, ignoreCaseMatch)).
-                            append(')');
-                    queryParams.add(schema.getKey());
-                    queryParams.add(attrValues.get(i));
-
-                    used.add(identifiers.get(i));
-
-                    clauses.add(bld.toString());
-                }
-            }
-        }
-
-        LOG.debug("Generated where clauses {}", clauses);
+        clauses.forEach((clause, parameters) -> {
+            actualClauses.add(clause);
+            queryParams.addAll(parameters);
+        });
 
         Query query = entityManager().createNativeQuery(
-                "SELECT DISTINCT id FROM " + table + " u WHERE id IN " + clauses.toString());
+                "SELECT DISTINCT id FROM " + table + " u WHERE id IN " + actualClauses.toString());
         for (int i = 0; i < queryParams.size(); i++) {
             query.setParameter(i + 1, queryParams.get(i));
         }
 
-        return buildResult(anyUtils, query.getResultList());
-    }
-
-    @Transactional
-    @Override
-    public <A extends Any<?>> void checkBeforeSave(final String table, final AnyUtils anyUtils, final A any) {
-        // check UNIQUE constraints
-        any.getPlainAttrs().stream().
-                filter(attr -> attr.getUniqueValue() != null).
-                map(JSONPlainAttr.class::cast).
-                forEach(attr -> {
-                    String schemaKey = attr.getSchemaKey();
-                    List<A> others = findByPlainAttrValue(table, anyUtils, schemaKey, attr.getUniqueValue(), false);
-                    if (others.isEmpty() || (others.size() == 1 && others.get(0).getKey().equals(any.getKey()))) {
-                        LOG.debug("No duplicate value found for {}", attr.getUniqueValue().getValueAsString());
-                    } else {
-                        throw new DuplicateException(
-                                "Value " + attr.getUniqueValue().getValueAsString() + " existing for " + schemaKey);
-                    }
-                });
-
-        // update sysInfo - as org.apache.syncope.core.persistence.jpa.entity.PlainAttrListener is not invoked
-        Date now = new Date();
-        String username = AuthContextUtils.getUsername();
-        LOG.debug("Set last change date '{}' and modifier '{}' for '{}'", now, username, any);
-        any.setLastModifier(username);
-        any.setLastChangeDate(now);
+        return query.getResultList();
     }
 }
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java
index dd34269..bd29bf3 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/dao/PGJPAJSONAnySearchDAO.java
@@ -23,10 +23,7 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
-import org.apache.commons.lang3.time.FastDateFormat;
 import org.apache.commons.lang3.tuple.Pair;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
 import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
@@ -39,14 +36,7 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.entity.JSONPlainAttr;
 
-public class PGJPAJSONAnySearchDAO extends JPAAnySearchDAO {
-
-    private static final FastDateFormat DATE_FORMAT = FastDateFormat.getInstance(SyncopeConstants.DEFAULT_DATE_PATTERN);
-
-    @Override
-    SearchSupport buildSearchSupport(final AnyTypeKind kind) {
-        return new SearchSupport(kind);
-    }
+public class PGJPAJSONAnySearchDAO extends AbstractJPAJSONAnySearchDAO {
 
     @Override
     protected void processOBS(
@@ -98,36 +88,6 @@ public class PGJPAJSONAnySearchDAO extends JPAAnySearchDAO {
         });
     }
 
-    private String key(final AttrSchemaType schemaType) {
-        String key;
-        switch (schemaType) {
-            case Boolean:
-                key = "booleanValue";
-                break;
-
-            case Date:
-                key = "dateValue";
-                break;
-
-            case Double:
-                key = "doubleValue";
-                break;
-
-            case Long:
-                key = "longValue";
-                break;
-
-            case Binary:
-                key = "binaryValue";
-                break;
-
-            default:
-                key = "stringValue";
-        }
-
-        return key;
-    }
-
     @Override
     protected void parseOrderByForPlainSchema(
             final SearchSupport svs,
@@ -192,55 +152,7 @@ public class PGJPAJSONAnySearchDAO extends JPAAnySearchDAO {
                         append(" ->> '").append(key).append("'").
                         append(lower ? ")" : "");
 
-                switch (cond.getType()) {
-                    case LIKE:
-                    case ILIKE:
-                        if (not) {
-                            query.append("NOT ");
-                        }
-                        query.append(" LIKE ");
-                        break;
-
-                    case GE:
-                        if (not) {
-                            query.append('<');
-                        } else {
-                            query.append(">=");
-                        }
-                        break;
-
-                    case GT:
-                        if (not) {
-                            query.append("<=");
-                        } else {
-                            query.append('>');
-                        }
-                        break;
-
-                    case LE:
-                        if (not) {
-                            query.append('>');
-                        } else {
-                            query.append("<=");
-                        }
-                        break;
-
-                    case LT:
-                        if (not) {
-                            query.append(">=");
-                        } else {
-                            query.append('<');
-                        }
-                        break;
-
-                    case EQ:
-                    case IEQ:
-                    default:
-                        if (not) {
-                            query.append('!');
-                        }
-                        query.append('=');
-                }
+                appendOp(query, cond.getType(), not);
 
                 String value = cond.getExpression();
                 if (schema.getType() == AttrSchemaType.Date) {
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAJSONEntityFactory.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAJSONEntityFactory.java
index bcd046d..a27e5e3 100644
--- a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAJSONEntityFactory.java
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAJSONEntityFactory.java
@@ -140,6 +140,7 @@ public abstract class JPAJSONEntityFactory extends JPAEntityFactory implements I
 
     @Override
     public void afterPropertiesSet() throws Exception {
-        beanFactory.createBean(jpaJSONAnyDAOClass(), AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
+        beanFactory.registerSingleton("jpaJSONAnyDAO",
+                beanFactory.createBean(jpaJSONAnyDAOClass(), AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false));
     }
 }
diff --git a/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MyJPAJSONEntityFactory.java b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MyJPAJSONEntityFactory.java
new file mode 100644
index 0000000..ca17f7b
--- /dev/null
+++ b/core/persistence-jpa-json/src/main/java/org/apache/syncope/core/persistence/jpa/entity/MyJPAJSONEntityFactory.java
@@ -0,0 +1,37 @@
+/*
+ * 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.entity;
+
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.JPAJSONAnyDAO;
+import org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAnyDAO;
+import org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAnySearchDAO;
+
+public class MyJPAJSONEntityFactory extends JPAJSONEntityFactory {
+
+    @Override
+    public Class<? extends AnySearchDAO> anySearchDAOClass() {
+        return MyJPAJSONAnySearchDAO.class;
+    }
+
+    @Override
+    protected Class<? extends JPAJSONAnyDAO> jpaJSONAnyDAOClass() {
+        return MyJPAJSONAnyDAO.class;
+    }
+}
diff --git a/core/persistence-jpa-json/src/main/resources/META-INF/spring-orm-myjson.xml b/core/persistence-jpa-json/src/main/resources/META-INF/spring-orm-myjson.xml
new file mode 100644
index 0000000..1c397a0
--- /dev/null
+++ b/core/persistence-jpa-json/src/main/resources/META-INF/spring-orm-myjson.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
+                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm 
+                                     http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
+                 version="2.0">
+  
+  <persistence-unit-metadata>
+    <persistence-unit-defaults>
+      <entity-listeners>
+        <entity-listener class="org.apache.syncope.core.persistence.jpa.validation.entity.EntityValidationListener">
+          <pre-persist method-name="validate"/>
+          <pre-update method-name="validate"/>
+        </entity-listener>
+      </entity-listeners>
+    </persistence-unit-defaults>
+  </persistence-unit-metadata>
+ 
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAJSONAnyObject">
+    <attributes>
+      <basic name="plainAttrs">
+        <column column-definition="json"/>
+        <lob/>
+      </basic>
+    </attributes>
+  </entity>
+    
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAJSONGroup">
+    <attributes>
+      <basic name="plainAttrs">
+        <column column-definition="json"/>
+        <lob/>
+      </basic>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONUser">
+    <attributes>
+      <basic name="plainAttrs">
+        <column column-definition="json"/>
+        <lob/>
+      </basic>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.conf.JPAJSONConf">
+    <attributes>
+      <basic name="plainAttrs">
+        <column column-definition="json"/>
+        <lob/>
+      </basic>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup">
+    <attributes>
+      <many-to-one name="userOwner" target-entity="org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONUser"/>
+      <many-to-one name="groupOwner" target-entity="org.apache.syncope.core.persistence.jpa.entity.group.JPAJSONGroup"/>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPATypeExtension">
+    <attributes>
+      <many-to-one name="group" target-entity="org.apache.syncope.core.persistence.jpa.entity.group.JPAJSONGroup"/>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUMembership">
+    <attributes>
+      <many-to-one name="leftEnd" target-entity="org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONUser">
+        <join-column name="user_id"/>
+      </many-to-one>
+      <many-to-one name="rightEnd" target-entity="org.apache.syncope.core.persistence.jpa.entity.group.JPAJSONGroup">
+        <join-column name="group_id"/>
+      </many-to-one>        
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership">
+    <attributes>
+      <one-to-one name="group" target-entity="org.apache.syncope.core.persistence.jpa.entity.group.JPAJSONGroup"/>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship">
+    <attributes>
+      <many-to-one name="leftEnd" target-entity="org.apache.syncope.core.persistence.jpa.entity.user.JPAJSONUser">
+        <join-column name="user_id"/>
+      </many-to-one>
+      <many-to-one name="rightEnd" target-entity="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAJSONAnyObject">
+        <join-column name="anyObject_id"/>
+      </many-to-one>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership">
+    <attributes>
+      <many-to-one name="leftEnd" target-entity="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAJSONAnyObject">
+        <join-column name="anyObject_id"/>
+      </many-to-one>
+      <many-to-one name="rightEnd" target-entity="org.apache.syncope.core.persistence.jpa.entity.group.JPAJSONGroup">
+        <join-column name="group_id"/>
+      </many-to-one>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership">
+    <attributes>
+      <one-to-one name="group" target-entity="org.apache.syncope.core.persistence.jpa.entity.group.JPAJSONGroup"/>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAARelationship">
+    <attributes>
+      <many-to-one name="leftEnd" target-entity="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAJSONAnyObject">
+        <join-column name="left_anyObject_id"/>
+      </many-to-one>
+      <many-to-one name="rightEnd" target-entity="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAJSONAnyObject">
+        <join-column name="right_anyObject_id"/>
+      </many-to-one>
+    </attributes>
+  </entity>
+</entity-mappings>
diff --git a/fit/core-reference/src/main/resources/mysql/domains/Master.properties b/core/persistence-jpa-json/src/main/resources/myjson/domains/Master.properties
similarity index 80%
copy from fit/core-reference/src/main/resources/mysql/domains/Master.properties
copy to core/persistence-jpa-json/src/main/resources/myjson/domains/Master.properties
index a4abb99..d945b5a 100644
--- a/fit/core-reference/src/main/resources/mysql/domains/Master.properties
+++ b/core/persistence-jpa-json/src/main/resources/myjson/domains/Master.properties
@@ -14,15 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-Master.driverClassName=com.mysql.jdbc.Driver
-Master.url=jdbc:mysql://localhost:3306/syncope?characterEncoding=UTF-8&relaxAutoCommit=true
+Master.driverClassName=com.mysql.cj.jdbc.Driver
+Master.url=jdbc:mysql://localhost:3306/syncope?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8
 Master.schema=
 Master.username=syncope
 Master.password=syncope
 Master.databasePlatform=org.apache.openjpa.jdbc.sql.MySQLDictionary(blobTypeName=LONGBLOB,timestampTypeName=DATETIME(3))
-Master.orm=META-INF/spring-orm.xml
+Master.orm=META-INF/spring-orm-myjson.xml
 
 Master.pool.maxActive=10
 Master.pool.minIdle=2
 
-Master.audit.sql=audit.sql
+Master.audit.sql=audit_mysql_innodb.sql
diff --git a/core/persistence-jpa-json/src/main/resources/myjson/indexes.xml b/core/persistence-jpa-json/src/main/resources/myjson/indexes.xml
new file mode 100644
index 0000000..b16004d
--- /dev/null
+++ b/core/persistence-jpa-json/src/main/resources/myjson/indexes.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+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.
+-->
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+  <comment>Additional indexes (in respect to JPA's)</comment>
+
+  <entry key="UDynGroupMembers_any_id">CREATE INDEX UDynGroupMembers_any_id ON UDynGroupMembers(any_id)</entry>
+  <entry key="UDynGroupMembers_group_id">CREATE INDEX UDynGroupMembers_group_id ON UDynGroupMembers(group_id)</entry>
+  <entry key="ADynGroupMembers_any_id">CREATE INDEX ADynGroupMembers_any_id ON ADynGroupMembers(any_id)</entry>
+  <entry key="ADynGroupMembers_group_id">CREATE INDEX ADynGroupMembers_group_id ON ADynGroupMembers(group_id)</entry>
+
+  <entry key="DynRoleMembers_any_id">CREATE INDEX DynRoleMembers_any_id ON DynRoleMembers(any_id)</entry>
+  <entry key="DynRoleMembers_role_id">CREATE INDEX DynRoleMembers_role_id ON DynRoleMembers(role_id)</entry>
+
+  <entry key="DynRealmMembers_any_id">CREATE INDEX DynRealmMembers_any_id ON DynRealmMembers(any_id)</entry>
+  <entry key="DynRealmMembers_realm_id">CREATE INDEX DynRealmMembers_dynRealm_id ON DynRealmMembers(dynRealm_id)</entry>
+
+  <entry key="CPlainAttrValue_stringvalueIndex">CREATE INDEX CAttrValue_stringvalueIndex ON CPlainAttrValue(stringvalue)</entry>
+  <entry key="CPlainAttrValue_datevalueIndex">CREATE INDEX CAttrValue_datevalueIndex ON CPlainAttrValue(datevalue)</entry>
+  <entry key="CPlainAttrValue_longvalueIndex">CREATE INDEX CAttrValue_longvalueIndex ON CPlainAttrValue(longvalue)</entry>
+  <entry key="CPlainAttrValue_doublevalueIndex">CREATE INDEX CAttrValue_doublevalueIndex ON CPlainAttrValue(doublevalue)</entry>
+  <entry key="CPlainAttrValue_booleanvalueIndex">CREATE INDEX CAttrValue_booleanvalueIndex ON CPlainAttrValue(booleanvalue)</entry>
+
+  <entry key="UMembership_GroupIndex">CREATE INDEX UMembership_GroupIndex ON UMembership(group_id)</entry>
+  <entry key="UMembership_UserIndex">CREATE INDEX UMembership_UserIndex ON UMembership(user_id)</entry>
+  <entry key="AMembership_GroupIndex">CREATE INDEX AMembership_GroupIndex ON AMembership(group_id)</entry>
+  <entry key="AMembership_AnyObjectIndex">CREATE INDEX AMembership_AnyObjectIndex ON AMembership(anyObject_id)</entry>
+
+  <entry key="URelationship_RightIndex">CREATE INDEX URelationship_RightIndex ON URelationship(anyObject_id)</entry>
+  <entry key="URelationship_LeftIndex">CREATE INDEX URelationship_LeftIndex ON URelationship(user_id)</entry>
+  <entry key="ARelationship_RightIndex">CREATE INDEX ARelationship_RightIndex ON ARelationship(right_anyObject_id)</entry>
+  <entry key="ARelationship_AnyObjectIndex">CREATE INDEX ARelationship_AnyObjectIndex ON ARelationship(left_anyObject_id)</entry>
+
+  <entry key="CPlainAttrValue_attrIndex">CREATE INDEX CPlainAttrValue_attrIndex on CPlainAttrValue(attribute_id)</entry>
+  <entry key="CPAttrUniqueValue_attrIndex">CREATE INDEX CPAttrUniqueValue_attrIndex on CPlainAttrUniqueValue(attribute_id)</entry>
+
+  <entry key="CPlainAttr_owner_Index">CREATE INDEX CPlainAttr_owner_Index on CPlainAttr(owner_id)</entry>
+  <entry key="CPlainAttr_schema_Index">CREATE INDEX CPlainAttr_schema_Index on CPlainAttr(schema_id)</entry>
+
+  <entry key="Task_executedIndex">CREATE INDEX Task_executedIndex ON Task(executed)</entry>
+</properties>
diff --git a/fit/core-reference/src/main/resources/mysql/domains/Master.properties b/core/persistence-jpa-json/src/main/resources/myjson/persistence.properties
similarity index 50%
copy from fit/core-reference/src/main/resources/mysql/domains/Master.properties
copy to core/persistence-jpa-json/src/main/resources/myjson/persistence.properties
index a4abb99..31a2dd8 100644
--- a/fit/core-reference/src/main/resources/mysql/domains/Master.properties
+++ b/core/persistence-jpa-json/src/main/resources/myjson/persistence.properties
@@ -14,15 +14,14 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-Master.driverClassName=com.mysql.jdbc.Driver
-Master.url=jdbc:mysql://localhost:3306/syncope?characterEncoding=UTF-8&relaxAutoCommit=true
-Master.schema=
-Master.username=syncope
-Master.password=syncope
-Master.databasePlatform=org.apache.openjpa.jdbc.sql.MySQLDictionary(blobTypeName=LONGBLOB,timestampTypeName=DATETIME(3))
-Master.orm=META-INF/spring-orm.xml
-
-Master.pool.maxActive=10
-Master.pool.minIdle=2
-
-Master.audit.sql=audit.sql
+content.directory=${conf.directory}
+entity.factory=org.apache.syncope.core.persistence.jpa.entity.MyJPAJSONEntityFactory
+plainSchema.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONPlainSchemaDAO
+plainAttr.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONPlainAttrDAO
+plainAttrValue.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONPlainAttrValueDAO
+any.search.dao=org.apache.syncope.core.persistence.jpa.dao.MyJPAJSONAnySearchDAO
+user.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONUserDAO
+group.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONGroupDAO
+anyObject.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONAnyObjectDAO
+conf.dao=org.apache.syncope.core.persistence.jpa.dao.JPAJSONConfDAO
+openjpa.RemoteCommitProvider=sjvm
diff --git a/core/persistence-jpa-json/src/main/resources/myjson/views.xml b/core/persistence-jpa-json/src/main/resources/myjson/views.xml
new file mode 100644
index 0000000..aa0e3c0
--- /dev/null
+++ b/core/persistence-jpa-json/src/main/resources/myjson/views.xml
@@ -0,0 +1,181 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+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.
+-->
+<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+<properties>
+  
+  <entry key="UDynGroupMembers">
+    CREATE TABLE UDynGroupMembers(
+    any_id CHAR(36),
+    group_id CHAR(36),
+    UNIQUE(any_id, group_id))
+  </entry>
+  <entry key="ADynGroupMembers">
+    CREATE TABLE ADynGroupMembers(
+    anyType_id VARCHAR(255),
+    any_id CHAR(36),
+    group_id CHAR(36),
+    UNIQUE(anyType_id, any_id, group_id))
+  </entry>
+  <entry key="DynRoleMembers">
+    CREATE TABLE DynRoleMembers(
+    any_id CHAR(36),
+    role_id VARCHAR(255),
+    UNIQUE(any_id, role_id))
+  </entry>
+  <entry key="DynRealmMembers">
+    CREATE TABLE DynRealmMembers(
+    any_id CHAR(36),
+    dynRealm_id VARCHAR(255),
+    UNIQUE(any_id, dynRealm_id))
+  </entry>
+
+  <!-- user -->
+  <entry key="user_search">
+    CREATE VIEW user_search AS
+
+    SELECT u.id as any_id, u.*, attrs.*
+    FROM SyncopeUser u, JSON_TABLE(COALESCE(plainAttrs, '[{}]'), '$[*]' COLUMNS (
+    plainSchema VARCHAR(255) PATH '$.schema',
+    NESTED PATH '$.values[*]' COLUMNS (
+    binaryValue LONGBLOB PATH '$.binaryValue',
+    booleanValue INT PATH '$.booleanValue',
+    dateValue BIGINT(20) PATH '$.dateValue',
+    doubleValue DOUBLE PATH '$.doubleValue',
+    longValue BIGINT(20) PATH '$.longValue',
+    stringValue VARCHAR(255) PATH '$.stringValue'),
+    attrUniqueValue JSON PATH '$.uniqueValue')
+    ) AS attrs
+  </entry>
+  <entry key="user_search_urelationship">
+    CREATE VIEW user_search_urelationship AS
+
+    SELECT m.user_id AS any_id, m.anyObject_id AS right_any_id, m.type_id AS type
+    FROM URelationship m
+  </entry>
+  <entry key="user_search_umembership">
+    CREATE VIEW user_search_umembership AS
+
+    SELECT m.user_id AS any_id, g.id AS group_id, g.name AS group_name
+    FROM UMembership m, SyncopeGroup g
+    WHERE m.group_id = g.id
+  </entry>
+  <entry key="user_search_role">
+    CREATE VIEW user_search_role AS
+
+    SELECT ss.user_id AS any_id, ss.role_id AS role_id
+    FROM SyncopeUser_SyncopeRole ss
+  </entry>
+  <entry key="user_search_priv">
+    CREATE VIEW user_search_priv AS
+
+    SELECT ss.user_id AS any_id, sp.privilege_id AS privilege_id
+    FROM SyncopeUser_SyncopeRole ss, SyncopeRole_Privilege sp
+    WHERE ss.role_id = sp.role_id
+  </entry>
+  <entry key="user_search_dynpriv">
+    CREATE VIEW user_search_dynpriv AS
+
+    SELECT any_id, privilege_id
+    FROM DynRoleMembers drm, SyncopeRole_Privilege rp
+    WHERE drm.role_id = rp.role_id
+  </entry>
+  <entry key="user_search_resource">
+    CREATE VIEW user_search_resource AS
+
+    SELECT st.user_id AS any_id, st.resource_id AS resource_id
+    FROM SyncopeUser_ExternalResource st
+  </entry>
+  <entry key="user_search_group_res">
+    CREATE VIEW user_search_group_res AS
+
+    SELECT m.user_id AS any_id, st.resource_id AS resource_id
+    FROM UMembership m, SyncopeGroup r, SyncopeGroup_ExternalResource st
+    WHERE m.group_id = r.id AND st.group_id = r.id
+  </entry>
+
+  <!-- anyObject -->
+  <entry key="anyObject_search">
+    CREATE VIEW anyObject_search AS
+ 
+    SELECT a.id as any_id, a.*, attrs.*
+    FROM AnyObject a, JSON_TABLE(COALESCE(plainAttrs, '[{}]'), '$[*]' COLUMNS (
+    plainSchema VARCHAR(255) PATH '$.schema',
+    NESTED PATH '$.values[*]' COLUMNS (
+    binaryValue LONGBLOB PATH '$.binaryValue',
+    booleanValue INT PATH '$.booleanValue',
+    dateValue BIGINT(20) PATH '$.dateValue',
+    doubleValue DOUBLE PATH '$.doubleValue',
+    longValue BIGINT(20) PATH '$.longValue',
+    stringValue VARCHAR(255) PATH '$.stringValue'),
+    attrUniqueValue JSON PATH '$.uniqueValue')
+    ) AS attrs
+  </entry>
+  <entry key="anyObject_search_arelationship">
+    CREATE VIEW anyObject_search_arelationship AS
+
+    SELECT m.left_anyObject_id AS any_id, m.right_anyObject_id AS right_any_id, m.type_id AS type
+    FROM ARelationship m
+  </entry>
+  <entry key="anyObject_search_amembership">
+    CREATE VIEW anyObject_search_amembership AS
+
+    SELECT m.anyObject_id AS any_id, g.id AS group_id, g.name AS group_name
+    FROM AMembership m, SyncopeGroup g
+    WHERE m.group_id = g.id
+  </entry>
+  <entry key="anyObject_search_resource">
+    CREATE VIEW anyObject_search_resource AS
+
+    SELECT st.anyObject_id AS any_id, st.resource_id AS resource_id
+    FROM AnyObject_ExternalResource st
+  </entry>
+  <entry key="anyObject_search_group_res">
+    CREATE VIEW anyObject_search_group_res AS
+
+    SELECT m.anyObject_id AS any_id, st.resource_id AS resource_id
+    FROM AMembership m, SyncopeGroup r, SyncopeGroup_ExternalResource st
+    WHERE m.group_id = r.id AND st.group_id = r.id
+  </entry>
+
+  <!-- group -->
+  <entry key="group_search">
+    CREATE VIEW group_search AS
+ 
+    SELECT g.id as any_id, g.*, attrs.*
+    FROM SyncopeGroup g, JSON_TABLE(COALESCE(plainAttrs, '[{}]'), '$[*]' COLUMNS (
+    plainSchema VARCHAR(255) PATH '$.schema',
+    NESTED PATH '$.values[*]' COLUMNS (
+    binaryValue LONGBLOB PATH '$.binaryValue',
+    booleanValue INT PATH '$.booleanValue',
+    dateValue BIGINT(20) PATH '$.dateValue',
+    doubleValue DOUBLE PATH '$.doubleValue',
+    longValue BIGINT(20) PATH '$.longValue',
+    stringValue VARCHAR(255) PATH '$.stringValue'),
+    attrUniqueValue JSON PATH '$.uniqueValue')
+    ) AS attrs
+  </entry>
+  <entry key="group_search_resource">
+    CREATE VIEW group_search_resource AS
+
+    SELECT st.group_id AS any_id, st.resource_id AS resource_id
+    FROM SyncopeGroup_ExternalResource st
+  </entry>
+
+</properties>
diff --git a/core/persistence-jpa-json/src/test/resources/pgjsonb/domains/MasterContent.xml b/core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
similarity index 100%
rename from core/persistence-jpa-json/src/test/resources/pgjsonb/domains/MasterContent.xml
rename to core/persistence-jpa-json/src/test/resources/domains/MasterContent.xml
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 d0b958b..449285b 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
@@ -172,6 +172,8 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
 
             StringBuilder queryString = queryInfo.getLeft();
 
+            LOG.debug("Query: {}, parameters: {}", queryString, parameters);
+
             // 2. take into account realms and ordering
             OrderBySupport obs = parseOrderBy(kind, svs, orderBy);
             if (queryString.charAt(0) == '(') {
@@ -185,6 +187,8 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
                     append(filter.getLeft()).
                     append(buildOrderBy(obs));
 
+            LOG.debug("Query with auth and order by statements: {}, parameters: {}", queryString, parameters);
+
             // 3. prepare the search query
             Query query = entityManager().createNativeQuery(queryString.toString());
 
@@ -326,6 +330,36 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
         return orderBy;
     }
 
+    protected String key(final AttrSchemaType schemaType) {
+        String key;
+        switch (schemaType) {
+            case Boolean:
+                key = "booleanValue";
+                break;
+
+            case Date:
+                key = "dateValue";
+                break;
+
+            case Double:
+                key = "doubleValue";
+                break;
+
+            case Long:
+                key = "longValue";
+                break;
+
+            case Binary:
+                key = "binaryValue";
+                break;
+
+            default:
+                key = "stringValue";
+        }
+
+        return key;
+    }
+
     protected void parseOrderByForPlainSchema(
             final SearchSupport svs,
             final OrderBySupport obs,
@@ -342,7 +376,7 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
 
             item.select = new StringBuilder().
                     append(svs.asSearchViewSupport().uniqueAttr().alias).append('.').
-                    append(svs.fieldName(schema.getType())).
+                    append(key(schema.getType())).
                     append(" AS ").append(fieldName).toString();
             item.where = new StringBuilder().
                     append(svs.asSearchViewSupport().uniqueAttr().alias).
@@ -352,7 +386,7 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
             obs.views.add(svs.asSearchViewSupport().attr());
 
             item.select = new StringBuilder().
-                    append(svs.asSearchViewSupport().attr().alias).append('.').append(svs.fieldName(schema.getType())).
+                    append(svs.asSearchViewSupport().attr().alias).append('.').append(key(schema.getType())).
                     append(" AS ").append(fieldName).toString();
             item.where = new StringBuilder().
                     append(svs.asSearchViewSupport().attr().alias).
@@ -853,7 +887,7 @@ public class JPAAnySearchDAO extends AbstractAnySearchDAO {
             // activate ignoreCase only for EQ and LIKE operators
             boolean ignoreCase = AttributeCond.Type.ILIKE == cond.getType() || AttributeCond.Type.IEQ == cond.getType();
 
-            String column = (cond instanceof AnyCond) ? cond.getSchema() : svs.fieldName(schema.getType());
+            String column = (cond instanceof AnyCond) ? cond.getSchema() : key(schema.getType());
             if ((schema.getType() == AttrSchemaType.String || schema.getType() == AttrSchemaType.Enum) && ignoreCase) {
                 column = "LOWER (" + column + ")";
             }
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 f10b29a..84c1c91 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
@@ -21,7 +21,6 @@ package org.apache.syncope.core.persistence.jpa.dao;
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
@@ -74,38 +73,6 @@ public class SearchSupport {
         this.anyTypeKind = anyTypeKind;
     }
 
-    public String fieldName(final AttrSchemaType attrSchemaType) {
-        String result;
-
-        switch (attrSchemaType) {
-            case Boolean:
-                result = "booleanvalue";
-                break;
-
-            case Date:
-                result = "datevalue";
-                break;
-
-            case Double:
-                result = "doublevalue";
-                break;
-
-            case Long:
-                result = "longvalue";
-                break;
-
-            case String:
-            case Enum:
-                result = "stringvalue";
-                break;
-
-            default:
-                result = null;
-        }
-
-        return result;
-    }
-
     public SearchView table() {
         String result;
 
diff --git a/core/persistence-jpa/src/main/resources/audit/audit_mysql_innodb.sql b/core/persistence-jpa/src/main/resources/audit/audit_mysql_innodb.sql
index ff753fa..4d8426c 100644
--- a/core/persistence-jpa/src/main/resources/audit/audit_mysql_innodb.sql
+++ b/core/persistence-jpa/src/main/resources/audit/audit_mysql_innodb.sql
@@ -21,4 +21,4 @@ CREATE TABLE IF NOT EXISTS SYNCOPEAUDIT (
   LOGGER VARCHAR(255) NOT NULL,
   MESSAGE TEXT NOT NULL,
   THROWABLE TEXT
-) ENGINE=InnoDB
+) ENGINE=InnoDB;
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyTypeTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyTypeTest.java
index 1db62d8..26b1da9 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyTypeTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/AnyTypeTest.java
@@ -90,6 +90,7 @@ public class AnyTypeTest extends AbstractTest {
             newType.setKey("new type");
             newType.setKind(AnyTypeKind.USER);
             anyTypeDAO.save(newType);
+            entityManager().flush();
         });
     }
 
@@ -100,6 +101,7 @@ public class AnyTypeTest extends AbstractTest {
             newType.setKey("group");
             newType.setKind(AnyTypeKind.ANY_OBJECT);
             anyTypeDAO.save(newType);
+            entityManager().flush();
         });
     }
 
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 05679b3..4494f46 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -724,7 +724,7 @@ under the License.
             <filtering>true</filtering>
           </resource>
           <resource>
-            <directory>${basedir}/../../core/persistence-jpa-json/src/test/resources/pgjsonb/domains</directory>
+            <directory>${basedir}/../../core/persistence-jpa-json/src/test/resources/domains</directory>
             <targetPath>${project.build.directory}/classes/domains</targetPath>
             <filtering>true</filtering>
           </resource>
@@ -851,7 +851,165 @@ under the License.
         </testResources>
       </build>
     </profile>
+
+    <profile>
+      <id>myjson-it</id>
+
+      <properties>
+        <jdbcdriver.groupId>mysql</jdbcdriver.groupId>
+        <jdbcdriver.artifactId>mysql-connector-java</jdbcdriver.artifactId>
+      </properties>
+
+      <dependencies>
+        <dependency>
+          <groupId>org.apache.syncope.core</groupId>
+          <artifactId>syncope-core-persistence-jpa-json</artifactId>
+          <version>${project.version}</version>
+        </dependency>
     
+        <dependency>
+          <groupId>mysql</groupId>
+          <artifactId>mysql-connector-java</artifactId>
+          <version>${jdbc.mysql.version}</version>
+          <scope>test</scope>
+        </dependency>
+      </dependencies>
+
+      <build>
+        <defaultGoal>clean verify</defaultGoal>
+
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-war-plugin</artifactId>
+            <configuration>
+              <packagingExcludes>WEB-INF/classes/domains/Two*</packagingExcludes>
+            </configuration>
+          </plugin>
+
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-antrun-plugin</artifactId>
+            <inherited>true</inherited>
+            <executions>
+              <execution>
+                <id>remove-domain-Two</id>
+                <phase>prepare-package</phase>
+                <configuration>
+                  <target>
+                    <delete>
+                      <fileset dir="${project.build.directory}/classes/domains" includes="Two*"/>
+                    </delete>
+                  </target>
+                </configuration>
+                <goals>
+                  <goal>run</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+
+          <plugin>
+            <groupId>io.fabric8</groupId>
+            <artifactId>docker-maven-plugin</artifactId>
+            <configuration>
+              <images>
+                <image>
+                  <name>mysql/mysql-server:${docker.mysql.version}</name>
+                  <run>
+                    <cmd>--skip-log-bin --server-id=1</cmd>
+                    <env>
+                      <MYSQL_ROOT_PASSWORD>password</MYSQL_ROOT_PASSWORD>
+                      <MYSQL_DATABASE>syncope</MYSQL_DATABASE>
+                      <MYSQL_USER>syncope</MYSQL_USER>
+                      <MYSQL_PASSWORD>syncope</MYSQL_PASSWORD>
+                    </env>
+                    <ports>
+                      <port>3306:3306</port>
+                    </ports>
+                    <wait>
+                      <log>MySQL init process done. Ready for start up.</log>
+                      <time>30000</time>
+                    </wait>
+                  </run>
+                </image>
+              </images>
+            </configuration>
+            <executions>
+              <execution>
+                <id>start-mysql</id>
+                <phase>pre-integration-test</phase>
+                <goals>
+                  <goal>start</goal>
+                </goals>
+              </execution>
+              <execution>
+                <id>stop-mysql</id>
+                <phase>post-integration-test</phase>
+                <goals>
+                  <goal>stop</goal>
+                  <goal>remove</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+
+          <plugin>
+            <groupId>org.codehaus.cargo</groupId>
+            <artifactId>cargo-maven2-plugin</artifactId>
+            <inherited>true</inherited>
+            <executions>
+              <execution>
+                <id>start-container</id>
+                <phase>pre-integration-test</phase>
+                <goals>
+                  <goal>start</goal>
+                </goals>
+              </execution>
+              <execution>
+                <id>stop-container</id>
+                <phase>post-integration-test</phase>
+                <goals>
+                  <goal>stop</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+
+        <resources>
+          <resource>
+            <directory>src/main/resources</directory>
+            <filtering>true</filtering>
+            <excludes>
+              <exclude>provisioning.properties</exclude>
+              <exclude>indexes.xml</exclude>
+              <exclude>views.xml</exclude>
+            </excludes>
+          </resource>
+          <resource>
+            <directory>src/main/resources/myjson</directory>
+            <filtering>true</filtering>
+          </resource>
+          <resource>
+            <directory>${basedir}/../../core/persistence-jpa-json/src/test/resources/domains</directory>
+            <targetPath>${project.build.directory}/classes/domains</targetPath>
+            <filtering>true</filtering>
+          </resource>
+        </resources>
+        <testResources>
+          <testResource>
+            <directory>${basedir}/../../core/persistence-jpa-json/src/main/resources/myjson</directory>
+            <includes>
+              <include>persistence.properties</include>
+              <include>indexes.xml</include>
+              <include>views.xml</include>
+            </includes>            
+          </testResource>
+        </testResources>
+      </build>
+    </profile>
+
     <profile>
       <id>mysql-it</id>
 
@@ -879,9 +1037,11 @@ under the License.
             <configuration>
               <images>
                 <image>
-                  <name>mysql/mysql-server:5.7</name>
+                  <name>mysql/mysql-server:${docker.mysql.version}</name>
                   <run>
+                    <cmd>--skip-log-bin --server-id=1</cmd>
                     <env>
+                      <MYSQL_ROOT_PASSWORD>password</MYSQL_ROOT_PASSWORD>
                       <MYSQL_DATABASE>syncope</MYSQL_DATABASE>
                       <MYSQL_USER>syncope</MYSQL_USER>
                       <MYSQL_PASSWORD>syncope</MYSQL_PASSWORD>
@@ -889,6 +1049,10 @@ under the License.
                     <ports>
                       <port>3306:3306</port>
                     </ports>
+                    <wait>
+                      <log>MySQL init process done. Ready for start up.</log>
+                      <time>30000</time>
+                    </wait>
                   </run>
                 </image>
               </images>
diff --git a/fit/core-reference/src/main/resources/mysql/domains/Master.properties b/fit/core-reference/src/main/resources/myjson/domains/Master.properties
similarity index 80%
copy from fit/core-reference/src/main/resources/mysql/domains/Master.properties
copy to fit/core-reference/src/main/resources/myjson/domains/Master.properties
index a4abb99..d945b5a 100644
--- a/fit/core-reference/src/main/resources/mysql/domains/Master.properties
+++ b/fit/core-reference/src/main/resources/myjson/domains/Master.properties
@@ -14,15 +14,15 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-Master.driverClassName=com.mysql.jdbc.Driver
-Master.url=jdbc:mysql://localhost:3306/syncope?characterEncoding=UTF-8&relaxAutoCommit=true
+Master.driverClassName=com.mysql.cj.jdbc.Driver
+Master.url=jdbc:mysql://localhost:3306/syncope?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8
 Master.schema=
 Master.username=syncope
 Master.password=syncope
 Master.databasePlatform=org.apache.openjpa.jdbc.sql.MySQLDictionary(blobTypeName=LONGBLOB,timestampTypeName=DATETIME(3))
-Master.orm=META-INF/spring-orm.xml
+Master.orm=META-INF/spring-orm-myjson.xml
 
 Master.pool.maxActive=10
 Master.pool.minIdle=2
 
-Master.audit.sql=audit.sql
+Master.audit.sql=audit_mysql_innodb.sql
diff --git a/fit/core-reference/src/main/resources/mysql/provisioning.properties b/fit/core-reference/src/main/resources/myjson/provisioning.properties
similarity index 89%
copy from fit/core-reference/src/main/resources/mysql/provisioning.properties
copy to fit/core-reference/src/main/resources/myjson/provisioning.properties
index 271a589..3883cb5 100644
--- a/fit/core-reference/src/main/resources/mysql/provisioning.properties
+++ b/fit/core-reference/src/main/resources/myjson/provisioning.properties
@@ -25,10 +25,8 @@ userProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultUserPro
 groupProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultGroupProvisioningManager
 anyObjectProvisioningManager=org.apache.syncope.core.provisioning.java.DefaultAnyObjectProvisioningManager
 virAttrCache=org.apache.syncope.core.provisioning.java.cache.MemoryVirAttrCache
-notificationManager=org.apache.syncope.core.provisioning.java.notification.DefaultNotificationManager
-auditManager=org.apache.syncope.core.provisioning.java.DefaultAuditManager
 
 quartz.jobstore=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
-quartz.sql=tables_mysql.sql
+quartz.sql=tables_mysql_innodb.sql
 quartz.scheduler.idleWaitTime=5000
 quartz.disableInstance=false
diff --git a/fit/core-reference/src/main/resources/mysql/domains/Master.properties b/fit/core-reference/src/main/resources/mysql/domains/Master.properties
index a4abb99..e36e370 100644
--- a/fit/core-reference/src/main/resources/mysql/domains/Master.properties
+++ b/fit/core-reference/src/main/resources/mysql/domains/Master.properties
@@ -14,8 +14,8 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-Master.driverClassName=com.mysql.jdbc.Driver
-Master.url=jdbc:mysql://localhost:3306/syncope?characterEncoding=UTF-8&relaxAutoCommit=true
+Master.driverClassName=com.mysql.cj.jdbc.Driver
+Master.url=jdbc:mysql://localhost:3306/syncope?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8
 Master.schema=
 Master.username=syncope
 Master.password=syncope
@@ -25,4 +25,4 @@ Master.orm=META-INF/spring-orm.xml
 Master.pool.maxActive=10
 Master.pool.minIdle=2
 
-Master.audit.sql=audit.sql
+Master.audit.sql=audit_mysql_innodb.sql
diff --git a/fit/core-reference/src/main/resources/mysql/provisioning.properties b/fit/core-reference/src/main/resources/mysql/provisioning.properties
index 271a589..191693c 100644
--- a/fit/core-reference/src/main/resources/mysql/provisioning.properties
+++ b/fit/core-reference/src/main/resources/mysql/provisioning.properties
@@ -29,6 +29,6 @@ notificationManager=org.apache.syncope.core.provisioning.java.notification.Defau
 auditManager=org.apache.syncope.core.provisioning.java.DefaultAuditManager
 
 quartz.jobstore=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
-quartz.sql=tables_mysql.sql
+quartz.sql=tables_mysql_innodb.sql
 quartz.scheduler.idleWaitTime=5000
 quartz.disableInstance=false
diff --git a/pom.xml b/pom.xml
index a6579f2..df66b7d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -396,7 +396,7 @@ under the License.
     <spring.version>5.1.4.RELEASE</spring.version>
     <spring-security.version>5.1.2.RELEASE</spring-security.version>
 
-    <openjpa.version>3.0.0</openjpa.version>
+    <openjpa.version>3.0.1-SNAPSHOT</openjpa.version>
     <hikaricp.version>3.3.0</hikaricp.version>
     <hibernate-validator.version>6.0.13.Final</hibernate-validator.version>
 
@@ -518,10 +518,11 @@ under the License.
     <protractor.version>5.4.0</protractor.version>    
 
     <docker.postgresql.version>11.1</docker.postgresql.version>
+    <docker.mysql.version>8.0</docker.mysql.version>
     <docker.mariadb.version>10.4</docker.mariadb.version>
 
     <jdbc.postgresql.version>42.2.5</jdbc.postgresql.version>
-    <jdbc.mysql.version>5.1.47</jdbc.mysql.version>
+    <jdbc.mysql.version>8.0.13</jdbc.mysql.version>
     <jdbc.mariadb.version>2.3.0</jdbc.mariadb.version>
     <jdbc.mssql.version>6.4.0.jre</jdbc.mssql.version>