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 2015/01/23 17:41:30 UTC

[08/15] syncope git commit: FIT server integration tests

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LoggerLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LoggerLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LoggerLogic.java
index 47db825..3c9a614 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LoggerLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LoggerLogic.java
@@ -80,9 +80,9 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
 
     private List<LoggerTO> list(final LoggerType type) {
         List<LoggerTO> result = new ArrayList<>();
-        for (Logger syncopeLogger : loggerDAO.findAll(type)) {
+        for (Logger logger : loggerDAO.findAll(type)) {
             LoggerTO loggerTO = new LoggerTO();
-            BeanUtils.copyProperties(syncopeLogger, loggerTO);
+            BeanUtils.copyProperties(logger, loggerTO);
             result.add(loggerTO);
         }
 
@@ -102,9 +102,9 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
 
         for (LoggerTO logger : list(LoggerType.AUDIT)) {
             try {
-                result.add(AuditLoggerName.fromLoggerName(logger.getName()));
+                result.add(AuditLoggerName.fromLoggerName(logger.getKey()));
             } catch (Exception e) {
-                LOG.warn("Unexpected audit logger name: {}", logger.getName(), e);
+                LOG.warn("Unexpected audit logger name: {}", logger.getKey(), e);
             }
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ReportLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ReportLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ReportLogic.java
index bb369ab..e8502ec 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ReportLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ReportLogic.java
@@ -55,7 +55,7 @@ import org.apache.syncope.server.persistence.api.entity.ReportExec;
 import org.apache.syncope.server.provisioning.api.data.ReportDataBinder;
 import org.apache.syncope.server.provisioning.api.job.JobNamer;
 import org.apache.syncope.server.logic.init.ImplementationClassNamesLoader;
-import org.apache.syncope.server.logic.init.JobInstanceLoader;
+import org.apache.syncope.server.provisioning.api.job.JobInstanceLoader;
 import org.apache.syncope.server.logic.report.Reportlet;
 import org.apache.syncope.server.logic.report.ReportletConfClass;
 import org.apache.syncope.server.logic.report.TextSerializer;
@@ -206,20 +206,20 @@ public class ReportLogic extends AbstractTransactionalLogic<ReportTO> {
     }
 
     @PreAuthorize("hasRole('REPORT_READ')")
-    public ReportTO read(final Long reportId) {
-        Report report = reportDAO.find(reportId);
+    public ReportTO read(final Long reportKey) {
+        Report report = reportDAO.find(reportKey);
         if (report == null) {
-            throw new NotFoundException("Report " + reportId);
+            throw new NotFoundException("Report " + reportKey);
         }
         return binder.getReportTO(report);
     }
 
     @PreAuthorize("hasRole('REPORT_READ')")
     @Transactional(readOnly = true)
-    public ReportExecTO readExecution(final Long executionId) {
-        ReportExec reportExec = reportExecDAO.find(executionId);
+    public ReportExecTO readExecution(final Long executionKey) {
+        ReportExec reportExec = reportExecDAO.find(executionKey);
         if (reportExec == null) {
-            throw new NotFoundException("Report execution " + executionId);
+            throw new NotFoundException("Report execution " + executionKey);
         }
         return binder.getReportExecTO(reportExec);
     }
@@ -291,10 +291,10 @@ public class ReportLogic extends AbstractTransactionalLogic<ReportTO> {
     }
 
     @PreAuthorize("hasRole('REPORT_READ')")
-    public ReportExec getAndCheckReportExec(final Long executionId) {
-        ReportExec reportExec = reportExecDAO.find(executionId);
+    public ReportExec getAndCheckReportExec(final Long executionKey) {
+        ReportExec reportExec = reportExecDAO.find(executionKey);
         if (reportExec == null) {
-            throw new NotFoundException("Report execution " + executionId);
+            throw new NotFoundException("Report execution " + executionKey);
         }
         if (!ReportExecStatus.SUCCESS.name().equals(reportExec.getStatus()) || reportExec.getExecResult() == null) {
             SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidReportExec);
@@ -307,10 +307,10 @@ public class ReportLogic extends AbstractTransactionalLogic<ReportTO> {
     }
 
     @PreAuthorize("hasRole('REPORT_EXECUTE')")
-    public ReportExecTO execute(final Long reportId) {
-        Report report = reportDAO.find(reportId);
+    public ReportExecTO execute(final Long reportKey) {
+        Report report = reportDAO.find(reportKey);
         if (report == null) {
-            throw new NotFoundException("Report " + reportId);
+            throw new NotFoundException("Report " + reportKey);
         }
 
         try {
@@ -327,7 +327,7 @@ public class ReportLogic extends AbstractTransactionalLogic<ReportTO> {
         }
 
         ReportExecTO result = new ReportExecTO();
-        result.setReport(reportId);
+        result.setReport(reportKey);
         result.setStartDate(new Date());
         result.setStatus(ReportExecStatus.STARTED.name());
         result.setMessage("Job fired; waiting for results...");
@@ -336,10 +336,10 @@ public class ReportLogic extends AbstractTransactionalLogic<ReportTO> {
     }
 
     @PreAuthorize("hasRole('REPORT_DELETE')")
-    public ReportTO delete(final Long reportId) {
-        Report report = reportDAO.find(reportId);
+    public ReportTO delete(final Long reportKey) {
+        Report report = reportDAO.find(reportKey);
         if (report == null) {
-            throw new NotFoundException("Report " + reportId);
+            throw new NotFoundException("Report " + reportKey);
         }
 
         ReportTO deletedReport = binder.getReportTO(report);
@@ -349,10 +349,10 @@ public class ReportLogic extends AbstractTransactionalLogic<ReportTO> {
     }
 
     @PreAuthorize("hasRole('REPORT_DELETE')")
-    public ReportExecTO deleteExecution(final Long executionId) {
-        ReportExec reportExec = reportExecDAO.find(executionId);
+    public ReportExecTO deleteExecution(final Long executionKey) {
+        ReportExec reportExec = reportExecDAO.find(executionKey);
         if (reportExec == null) {
-            throw new NotFoundException("Report execution " + executionId);
+            throw new NotFoundException("Report execution " + executionKey);
         }
 
         ReportExecTO reportExecToDelete = binder.getReportExecTO(reportExec);

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SpringBeanJobFactory.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SpringBeanJobFactory.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SpringBeanJobFactory.java
deleted file mode 100644
index 9eccaea..0000000
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SpringBeanJobFactory.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.server.logic;
-
-import org.apache.syncope.server.provisioning.api.job.JobNamer;
-import org.apache.syncope.server.logic.init.JobInstanceLoader;
-import org.quartz.SchedulerContext;
-import org.quartz.spi.TriggerFiredBundle;
-import org.springframework.beans.BeanWrapper;
-import org.springframework.beans.MutablePropertyValues;
-import org.springframework.beans.PropertyAccessorFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ConfigurableApplicationContext;
-
-public class SpringBeanJobFactory extends org.springframework.scheduling.quartz.SpringBeanJobFactory {
-
-    private String[] ignoredUnknownProperties;
-
-    private SchedulerContext schedulerContext;
-
-    @Override
-    public void setIgnoredUnknownProperties(final String[] ignoredUnknownProperties) {
-        String[] defensiveCopy = ignoredUnknownProperties.clone();
-        super.setIgnoredUnknownProperties(defensiveCopy);
-        this.ignoredUnknownProperties = defensiveCopy;
-    }
-
-    @Override
-    public void setSchedulerContext(final SchedulerContext schedulerContext) {
-        super.setSchedulerContext(schedulerContext);
-        this.schedulerContext = schedulerContext;
-    }
-
-    /**
-     * An implementation of SpringBeanJobFactory that retrieves the bean from the Spring context so that autowiring and
-     * transactions work.
-     *
-     * {@inheritDoc}
-     */
-    @Override
-    protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
-        final ApplicationContext ctx = ((ConfigurableApplicationContext) schedulerContext.get("applicationContext"));
-
-        // Try to re-create job bean from underlying task (useful for managing failover scenarios)
-        if (!ctx.containsBean(bundle.getJobDetail().getKey().getName())) {
-            Long taskId = JobNamer.getTaskIdFromJobName(bundle.getJobDetail().getKey().getName());
-            if (taskId != null) {
-                JobInstanceLoader jobInstanceLoader = ctx.getBean(JobInstanceLoader.class);
-                jobInstanceLoader.registerTaskJob(taskId);
-            }
-
-            Long reportId = JobNamer.getReportIdFromJobName(bundle.getJobDetail().getKey().getName());
-            if (reportId != null) {
-                JobInstanceLoader jobInstanceLoader = ctx.getBean(JobInstanceLoader.class);
-                jobInstanceLoader.registerReportJob(reportId);
-            }
-        }
-
-        final Object job = ctx.getBean(bundle.getJobDetail().getKey().getName());
-        final BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(job);
-        if (isEligibleForPropertyPopulation(wrapper.getWrappedInstance())) {
-            final MutablePropertyValues pvs = new MutablePropertyValues();
-            if (this.schedulerContext != null) {
-                pvs.addPropertyValues(this.schedulerContext);
-            }
-            pvs.addPropertyValues(bundle.getJobDetail().getJobDataMap());
-            pvs.addPropertyValues(bundle.getTrigger().getJobDataMap());
-            if (this.ignoredUnknownProperties == null) {
-                wrapper.setPropertyValues(pvs, true);
-            } else {
-                for (String propName : this.ignoredUnknownProperties) {
-                    if (pvs.contains(propName) && !wrapper.isWritableProperty(propName)) {
-                        pvs.removePropertyValue(propName);
-                    }
-                }
-                wrapper.setPropertyValues(pvs);
-            }
-        }
-        return job;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/TaskLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/TaskLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/TaskLogic.java
index 683cda6..f97bc83 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/TaskLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/TaskLogic.java
@@ -51,7 +51,7 @@ import org.apache.syncope.server.provisioning.api.job.JobNamer;
 import org.apache.syncope.server.provisioning.api.job.TaskJob;
 import org.apache.syncope.server.provisioning.api.propagation.PropagationTaskExecutor;
 import org.apache.syncope.server.logic.init.ImplementationClassNamesLoader;
-import org.apache.syncope.server.logic.init.JobInstanceLoader;
+import org.apache.syncope.server.provisioning.api.job.JobInstanceLoader;
 import org.apache.syncope.server.logic.notification.NotificationJob;
 import org.quartz.JobDataMap;
 import org.quartz.JobKey;
@@ -305,6 +305,7 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
         if (TaskType.SCHEDULED == taskUtil.getType()
                 || TaskType.SYNCHRONIZATION == taskUtil.getType()
                 || TaskType.PUSH == taskUtil.getType()) {
+
             jobInstanceLoader.unregisterJob(task);
         }
 
@@ -373,9 +374,6 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
         return res;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
     protected AbstractTaskTO resolveReference(final Method method, final Object... args)
             throws UnresolvedReferenceException {

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/UserLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/UserLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/UserLogic.java
index c3b01f6..3e0de7e 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/UserLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/UserLogic.java
@@ -339,7 +339,7 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
     public UserTO delete(final Long key) {
         List<Role> ownedRoles = roleDAO.findOwnedByUser(key);
         if (!ownedRoles.isEmpty()) {
-            List<String> owned = new ArrayList<String>(ownedRoles.size());
+            List<String> owned = new ArrayList<>(ownedRoles.size());
             for (Role role : ownedRoles) {
                 owned.add(role.getKey() + " " + role.getName());
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoader.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoader.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoader.java
deleted file mode 100644
index 3f6f753..0000000
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoader.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.server.logic.init;
-
-import java.text.ParseException;
-import org.apache.syncope.server.persistence.api.entity.Report;
-import org.apache.syncope.server.persistence.api.entity.task.Task;
-import org.quartz.SchedulerException;
-
-public interface JobInstanceLoader {
-
-    void registerJob(Task task, String jobClassName, String cronExpression)
-            throws ClassNotFoundException, SchedulerException, ParseException;
-
-    void registerJob(Report report) throws SchedulerException, ParseException;
-
-    void registerReportJob(Long reportKey) throws SchedulerException, ParseException;
-
-    void registerTaskJob(Long taskKey) throws ClassNotFoundException, SchedulerException, ParseException;
-
-    void unregisterJob(Task task);
-
-    void unregisterJob(Report report);
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoaderImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoaderImpl.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoaderImpl.java
index 48e7db4..e1d4c7d 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoaderImpl.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoaderImpl.java
@@ -35,6 +35,7 @@ import org.apache.syncope.server.persistence.api.entity.task.PushTask;
 import org.apache.syncope.server.persistence.api.entity.task.SchedTask;
 import org.apache.syncope.server.persistence.api.entity.task.SyncTask;
 import org.apache.syncope.server.persistence.api.entity.task.Task;
+import org.apache.syncope.server.provisioning.api.job.JobInstanceLoader;
 import org.apache.syncope.server.provisioning.api.job.JobNamer;
 import org.apache.syncope.server.provisioning.api.job.SyncJob;
 import org.apache.syncope.server.provisioning.api.job.TaskJob;

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/RoleReportlet.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/RoleReportlet.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/RoleReportlet.java
index 756f817..a6f698a 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/RoleReportlet.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/RoleReportlet.java
@@ -110,7 +110,7 @@ public class RoleReportlet extends AbstractReportlet<RoleReportletConf> {
 
         AttributesImpl atts = new AttributesImpl();
         if (!attrs.isEmpty()) {
-            Map<String, AttrTO> attrMap = attributableTO.getAttrMap();
+            Map<String, AttrTO> attrMap = attributableTO.getPlainAttrMap();
 
             handler.startElement("", "", "attributes", null);
             for (String attrName : attrs) {
@@ -233,7 +233,7 @@ public class RoleReportlet extends AbstractReportlet<RoleReportletConf> {
             // values to String is already encapsulated there
             RoleTO roleTO = roleDataBinder.getRoleTO(role);
 
-            doExtractAttributes(handler, roleTO, conf.getAttrs(), conf.getDerAttrs(), conf.getVirAttrs());
+            doExtractAttributes(handler, roleTO, conf.getPlainAttrs(), conf.getDerAttrs(), conf.getVirAttrs());
 
             if (conf.getFeatures().contains(Feature.entitlements)) {
                 handler.startElement("", "", "entitlements", null);
@@ -292,7 +292,7 @@ public class RoleReportlet extends AbstractReportlet<RoleReportletConf> {
             handler.endElement("", "", "feature");
         }
 
-        for (String attr : conf.getAttrs()) {
+        for (String attr : conf.getPlainAttrs()) {
             atts.clear();
             handler.startElement("", "", "attribute", atts);
             handler.characters(attr.toCharArray(), 0, attr.length());

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/UserReportlet.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/UserReportlet.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/UserReportlet.java
index ebdad43..61b7cd8 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/UserReportlet.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/UserReportlet.java
@@ -117,7 +117,7 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
 
         AttributesImpl atts = new AttributesImpl();
         if (!attrs.isEmpty()) {
-            Map<String, AttrTO> attrMap = attributableTO.getAttrMap();
+            Map<String, AttrTO> attrMap = attributableTO.getPlainAttrMap();
 
             handler.startElement("", "", "attributes", null);
             for (String attrName : attrs) {
@@ -271,7 +271,7 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
             // values to String is already encapsulated there
             UserTO userTO = userDataBinder.getUserTO(user);
 
-            doExtractAttributes(handler, userTO, conf.getAttrs(), conf.getDerAttrs(), conf.getVirAttrs());
+            doExtractAttributes(handler, userTO, conf.getPlainAttrs(), conf.getDerAttrs(), conf.getVirAttrs());
 
             if (conf.getFeatures().contains(Feature.memberships)) {
                 handler.startElement("", "", "memberships", null);
@@ -284,7 +284,7 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
                     atts.addAttribute("", "", "roleName", ReportXMLConst.XSD_STRING, String.valueOf(memb.getRoleName()));
                     handler.startElement("", "", "membership", atts);
 
-                    doExtractAttributes(handler, memb, memb.getAttrMap().keySet(), memb.getDerAttrMap()
+                    doExtractAttributes(handler, memb, memb.getPlainAttrMap().keySet(), memb.getDerAttrMap()
                             .keySet(), memb.getVirAttrMap().keySet());
 
                     if (conf.getFeatures().contains(Feature.resources)) {
@@ -324,7 +324,7 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
             handler.endElement("", "", "feature");
         }
 
-        for (String attr : conf.getAttrs()) {
+        for (String attr : conf.getPlainAttrs()) {
             atts.clear();
             handler.startElement("", "", "attribute", atts);
             handler.characters(attr.toCharArray(), 0, attr.length());

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/test/java/org/apache/syncope/server/logic/NotificationTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/test/java/org/apache/syncope/server/logic/NotificationTest.java b/syncope620/server/logic/src/test/java/org/apache/syncope/server/logic/NotificationTest.java
index de655d8..83a238f 100644
--- a/syncope620/server/logic/src/test/java/org/apache/syncope/server/logic/NotificationTest.java
+++ b/syncope620/server/logic/src/test/java/org/apache/syncope/server/logic/NotificationTest.java
@@ -262,7 +262,7 @@ public class NotificationTest {
         notification.setSelfAsRecipient(true);
 
         notification.setRecipientAttrName("email");
-        notification.setRecipientAttrType(IntMappingType.UserSchema);
+        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
 
         Random random = new Random(System.currentTimeMillis());
         String sender = "syncopetest-" + random.nextLong() + "@syncope.apache.org";
@@ -320,7 +320,7 @@ public class NotificationTest {
         notification.setSelfAsRecipient(true);
 
         notification.setRecipientAttrName("email");
-        notification.setRecipientAttrType(IntMappingType.UserSchema);
+        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
 
         Random random = new Random(System.currentTimeMillis());
         String sender = "syncope192-" + random.nextLong() + "@syncope.apache.org";
@@ -372,7 +372,7 @@ public class NotificationTest {
         notification.setSelfAsRecipient(true);
 
         notification.setRecipientAttrName("email");
-        notification.setRecipientAttrType(IntMappingType.UserSchema);
+        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
 
         Random random = new Random(System.currentTimeMillis());
         String sender = "syncopetest-" + random.nextLong() + "@syncope.apache.org";
@@ -422,7 +422,7 @@ public class NotificationTest {
         notification.setSelfAsRecipient(true);
 
         notification.setRecipientAttrName("email");
-        notification.setRecipientAttrType(IntMappingType.UserSchema);
+        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
 
         Random random = new Random(System.currentTimeMillis());
         String sender = "syncopetest-" + random.nextLong() + "@syncope.apache.org";
@@ -491,7 +491,7 @@ public class NotificationTest {
         notification.setSelfAsRecipient(true);
 
         notification.setRecipientAttrName("email");
-        notification.setRecipientAttrType(IntMappingType.UserSchema);
+        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
 
         notification.getStaticRecipients().add("syncope445@syncope.apache.org");
 
@@ -549,7 +549,7 @@ public class NotificationTest {
         notification.setSelfAsRecipient(true);
 
         notification.setRecipientAttrName("email");
-        notification.setRecipientAttrType(IntMappingType.UserSchema);
+        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
 
         notification.getStaticRecipients().add("syncope492@syncope.apache.org");
 
@@ -593,7 +593,7 @@ public class NotificationTest {
         notification.setSelfAsRecipient(false);
 
         notification.setRecipientAttrName("email");
-        notification.setRecipientAttrType(IntMappingType.UserSchema);
+        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
 
         notification.getStaticRecipients().add(MAIL_ADDRESS);
 
@@ -635,7 +635,7 @@ public class NotificationTest {
 
         assertNotNull(taskId);
         assertNotNull(textBody);
-        assertTrue(recipients.contains(MAIL_ADDRESS));
+        assertTrue(recipients != null && recipients.contains(MAIL_ADDRESS));
 
         // 5. execute Notification task and verify e-mail
         taskLogic.execute(taskId, false);

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/test/resources/logicTest.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/test/resources/logicTest.xml b/syncope620/server/logic/src/test/resources/logicTest.xml
index d3b1bd8..afb8730 100644
--- a/syncope620/server/logic/src/test/resources/logicTest.xml
+++ b/syncope620/server/logic/src/test/resources/logicTest.xml
@@ -41,5 +41,5 @@ under the License.
     <property name="primary" value="file:${conf.directory}/content.xml"/>
     <property name="fallback" value="classpath:content.xml"/>
   </bean>
-  
+
 </beans>

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/ConnObjectUtil.java
----------------------------------------------------------------------
diff --git a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/ConnObjectUtil.java b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/ConnObjectUtil.java
index 831a981..592cd0c 100644
--- a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/ConnObjectUtil.java
+++ b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/ConnObjectUtil.java
@@ -304,8 +304,8 @@ public class ConnObjectUtil {
                     }
                     break;
 
-                case UserSchema:
-                case RoleSchema:
+                case UserPlainSchema:
+                case RolePlainSchema:
                     attributeTO = new AttrTO();
                     attributeTO.setSchema(item.getIntAttrName());
 
@@ -446,7 +446,7 @@ public class ConnObjectUtil {
 
                 ((RoleTO) subjectTO).setInheritOwner(((RoleTO) template).isInheritOwner());
                 ((RoleTO) subjectTO).setInheritTemplates(((RoleTO) template).isInheritTemplates());
-                ((RoleTO) subjectTO).setInheritAttrs(((RoleTO) template).isInheritAttrs());
+                ((RoleTO) subjectTO).setInheritPlainAttrs(((RoleTO) template).isInheritPlainAttrs());
                 ((RoleTO) subjectTO).setInheritDerAttrs(((RoleTO) template).isInheritDerAttrs());
                 ((RoleTO) subjectTO).setInheritVirAttrs(((RoleTO) template).isInheritVirAttrs());
                 ((RoleTO) subjectTO).setInheritPasswordPolicy(((RoleTO) template).isInheritPasswordPolicy());
@@ -700,7 +700,7 @@ public class ConnObjectUtil {
     }
 
     private void fillFromTemplate(final AbstractAttributableTO attributableTO, final AbstractAttributableTO template) {
-        Map<String, AttrTO> currentAttrMap = attributableTO.getAttrMap();
+        Map<String, AttrTO> currentAttrMap = attributableTO.getPlainAttrMap();
         for (AttrTO templateAttr : template.getPlainAttrs()) {
             if (templateAttr.getValues() != null && !templateAttr.getValues().isEmpty()
                     && (!currentAttrMap.containsKey(templateAttr.getSchema())

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/MappingUtil.java
----------------------------------------------------------------------
diff --git a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/MappingUtil.java b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/MappingUtil.java
index 7ae586f..209c800 100644
--- a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/MappingUtil.java
+++ b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/MappingUtil.java
@@ -303,9 +303,9 @@ public final class MappingUtil {
         final Map.Entry<String, Attribute> result;
 
         switch (mapItem.getIntMappingType()) {
-            case UserSchema:
-            case RoleSchema:
-            case MembershipSchema:
+            case UserPlainSchema:
+            case RolePlainSchema:
+            case MembershipPlainSchema:
                 final PlainSchemaDAO plainSchemaDAO = context.getBean(PlainSchemaDAO.class);
                 schema = plainSchemaDAO.find(mapItem.getIntAttrName(),
                         MappingUtil.getIntMappingTypeClass(mapItem.getIntMappingType()));
@@ -487,9 +487,9 @@ public final class MappingUtil {
         List<PlainAttrValue> values = new ArrayList<>();
         PlainAttrValue attrValue;
         switch (mappingItem.getIntMappingType()) {
-            case UserSchema:
-            case RoleSchema:
-            case MembershipSchema:
+            case UserPlainSchema:
+            case RolePlainSchema:
+            case MembershipPlainSchema:
                 for (Attributable<?, ?, ?> attributable : attributables) {
                     final PlainAttr attr = attributable.getPlainAttr(mappingItem.getIntAttrName());
                     if (attr != null) {
@@ -687,15 +687,15 @@ public final class MappingUtil {
         Class result;
 
         switch (intMappingType) {
-            case UserSchema:
+            case UserPlainSchema:
                 result = UPlainSchema.class;
                 break;
 
-            case RoleSchema:
+            case RolePlainSchema:
                 result = RPlainSchema.class;
                 break;
 
-            case MembershipSchema:
+            case MembershipPlainSchema:
                 result = MPlainSchema.class;
                 break;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/AccountPolicyEnforcer.java
----------------------------------------------------------------------
diff --git a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/AccountPolicyEnforcer.java b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/AccountPolicyEnforcer.java
index f850b98..002a588 100644
--- a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/AccountPolicyEnforcer.java
+++ b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/AccountPolicyEnforcer.java
@@ -22,6 +22,7 @@ import java.util.regex.Pattern;
 import org.apache.syncope.common.lib.types.AccountPolicySpec;
 import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.provisioning.api.UserSuspender;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/PasswordPolicyEnforcer.java
----------------------------------------------------------------------
diff --git a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/PasswordPolicyEnforcer.java b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/PasswordPolicyEnforcer.java
index ac8513d..8bbc734 100644
--- a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/PasswordPolicyEnforcer.java
+++ b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/PasswordPolicyEnforcer.java
@@ -26,11 +26,6 @@ import org.springframework.stereotype.Component;
 @Component
 public class PasswordPolicyEnforcer implements PolicyEnforcer<PasswordPolicySpec, User> {
 
-    /* (non-Javadoc)
-     * @see
-     * org.apache.syncope.core.policy.PasswordPolicyEnforcer#enforce(org.apache.syncope.common.types.PasswordPolicySpec,
-     * org.apache.syncope.common.types.PolicyType, java.lang.String)
-     */
     @Override
     public void enforce(final PasswordPolicySpec policy, final PolicyType type, final User user)
             throws PasswordPolicyException, PolicyEnforceException {
@@ -43,7 +38,7 @@ public class PasswordPolicyEnforcer implements PolicyEnforcer<PasswordPolicySpec
         }
 
         if (password == null && !policy.isAllowNullPassword()) {
-            throw new PolicyEnforceException("Password must not be null and must be stored internally");
+            throw new PolicyEnforceException("Password mandatory");
         } else if (password != null && clearPassword != null) {
             // check length
             if (policy.getMinLength() > 0 && policy.getMinLength() > clearPassword.length()) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/UserSuspender.java
----------------------------------------------------------------------
diff --git a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/UserSuspender.java b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/UserSuspender.java
deleted file mode 100644
index 1fbf6f6..0000000
--- a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/UserSuspender.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.server.misc.policy;
-
-import org.apache.syncope.server.persistence.api.entity.user.User;
-
-public interface UserSuspender {
-
-    void suspend(User user, boolean propagateSuspension);
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/security/AuthContextUtil.java
----------------------------------------------------------------------
diff --git a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/security/AuthContextUtil.java b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/security/AuthContextUtil.java
index e58a157..870b444 100644
--- a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/security/AuthContextUtil.java
+++ b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/security/AuthContextUtil.java
@@ -59,7 +59,7 @@ public final class AuthContextUtil {
      */
     public static void extendAuthContext(final Long roleKey, final String roleEntitlement) {
         Authentication auth = SecurityContextHolder.getContext().getAuthentication();
-        List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(auth.getAuthorities());
+        List<GrantedAuthority> authorities = new ArrayList<>(auth.getAuthorities());
         authorities.add(new SimpleGrantedAuthority(roleEntitlement));
         Authentication newAuth = new UsernamePasswordAuthenticationToken(
                 auth.getPrincipal(), auth.getCredentials(), authorities);

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java
index 90bbbee..3456431 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java
@@ -86,6 +86,9 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
                 JPAMDerAttr.TABLE, JPAMVirAttr.TABLE
             }));
 
+    protected final static Set<String> TABLE_SUFFIXES_TO_BE_INCLUDED =
+            new HashSet<>(Arrays.asList(new String[] { "TEMPLATE" }));
+
     protected static final Map<String, String> TABLES_TO_BE_FILTERED =
             Collections.singletonMap("TASK", "DTYPE <> 'PropagationTask'");
 
@@ -96,7 +99,11 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
         boolean allowed = true;
         for (String prefix : TABLE_PREFIXES_TO_BE_EXCLUDED) {
             if (tableName.toUpperCase().startsWith(prefix)) {
-                allowed = false;
+                for (String suffix : TABLE_SUFFIXES_TO_BE_INCLUDED) {
+                    if (!tableName.toUpperCase().endsWith(suffix)) {
+                        allowed = false;
+                    }
+                }
             }
         }
         return allowed;

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPASubjectSearchDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPASubjectSearchDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPASubjectSearchDAO.java
index f4475f8..36d48e7 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPASubjectSearchDAO.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPASubjectSearchDAO.java
@@ -20,6 +20,7 @@ package org.apache.syncope.server.persistence.jpa.dao;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
@@ -31,6 +32,7 @@ import javax.persistence.TemporalType;
 import javax.validation.ValidationException;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
+import org.apache.commons.lang3.ClassUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.common.lib.types.SubjectType;
@@ -50,7 +52,6 @@ import org.apache.syncope.server.persistence.api.entity.AttributableUtilFactory;
 import org.apache.syncope.server.persistence.api.entity.PlainAttrValue;
 import org.apache.syncope.server.persistence.api.entity.PlainSchema;
 import org.apache.syncope.server.persistence.api.entity.Subject;
-import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 import org.springframework.util.ReflectionUtils;
@@ -652,6 +653,11 @@ public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> imp
 
         final AttributableUtil attrUtil = attrUtilFactory.getInstance(type.asAttributableType());
 
+        // Keeps track of difference between entity's getKey() and JPA @Id fields
+        if ("key".equals(cond.getSchema())) {
+            cond.setSchema("id");
+        }
+
         Field subjectField = ReflectionUtils.findField(attrUtil.attributableClass(), cond.getSchema());
         if (subjectField == null) {
             LOG.warn("Ignoring invalid schema '{}'", cond.getSchema());
@@ -685,13 +691,22 @@ public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> imp
 
         // Deal with subject fields representing relationships to other entities
         if (subjectField.getType().getAnnotation(Entity.class) != null) {
-            if (BeanUtils.findDeclaredMethodWithMinimalParameters(subjectField.getType(), "getId") != null) {
-                cond.setSchema(cond.getSchema() + "_id");
-                schema.setType(AttrSchemaType.Long);
+            Method relMethod = null;
+            try {
+                relMethod = ClassUtils.getPublicMethod(subjectField.getType(), "getKey", new Class[0]);
+            } catch (Exception e) {
+                LOG.error("Could not find {}#getKey", subjectField.getType(), e);
             }
-            if (BeanUtils.findDeclaredMethodWithMinimalParameters(subjectField.getType(), "getName") != null) {
-                cond.setSchema(cond.getSchema() + "_name");
-                schema.setType(AttrSchemaType.String);
+
+            if (relMethod != null) {
+                if (Long.class.isAssignableFrom(relMethod.getReturnType())) {
+                    cond.setSchema(cond.getSchema() + "_id");
+                    schema.setType(AttrSchemaType.Long);
+                }
+                if (String.class.isAssignableFrom(relMethod.getReturnType())) {
+                    cond.setSchema(cond.getSchema() + "_name");
+                    schema.setType(AttrSchemaType.String);
+                }
             }
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPATaskDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPATaskDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPATaskDAO.java
index 954697c..e0d2313 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPATaskDAO.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPATaskDAO.java
@@ -144,7 +144,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
     @Override
     public int count(final TaskType type) {
         Query countQuery = entityManager.createNativeQuery("SELECT COUNT(id) FROM Task WHERE TYPE=?1");
-        countQuery.setParameter(1, type.toString());
+        countQuery.setParameter(1, type.name());
         return ((Number) countQuery.getSingleResult()).intValue();
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAUserDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAUserDAO.java
index 30fdca5..2a45ad3 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAUserDAO.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAUserDAO.java
@@ -51,6 +51,7 @@ import org.apache.syncope.server.misc.security.AuthContextUtil;
 import org.apache.syncope.server.misc.security.UnauthorizedRoleException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
 
 @Repository
 public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAttr> implements UserDAO {
@@ -249,6 +250,7 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
         }
     }
 
+    @Transactional(readOnly = true)
     @Override
     public User authFetch(final Long key) {
         if (key == null) {
@@ -265,6 +267,7 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
         return user;
     }
 
+    @Transactional(readOnly = true)
     @Override
     public User authFetch(final String username) {
         if (username == null) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractAttrTemplate.java
index 3c79c92..fe78889 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractAttrTemplate.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractAttrTemplate.java
@@ -18,25 +18,11 @@
  */
 package org.apache.syncope.server.persistence.jpa.entity;
 
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.MappedSuperclass;
 import org.apache.syncope.server.persistence.api.entity.AttrTemplate;
 import org.apache.syncope.server.persistence.api.entity.Schema;
 
-@MappedSuperclass
 public abstract class AbstractAttrTemplate<S extends Schema> extends AbstractEntity<Long> implements AttrTemplate<S> {
 
     private static final long serialVersionUID = 4829112252713766666L;
 
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    protected Long id;
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractDerAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractDerAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractDerAttrTemplate.java
new file mode 100644
index 0000000..2dec16a
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractDerAttrTemplate.java
@@ -0,0 +1,41 @@
+/*
+ * 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.server.persistence.jpa.entity;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+import org.apache.syncope.server.persistence.api.entity.DerSchema;
+
+@MappedSuperclass
+public abstract class AbstractDerAttrTemplate<D extends DerSchema> extends AbstractAttrTemplate<D> {
+
+    private static final long serialVersionUID = 8871895736733379865L;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    protected Long id;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainAttrTemplate.java
new file mode 100644
index 0000000..f8b0150
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainAttrTemplate.java
@@ -0,0 +1,27 @@
+/*
+ * 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.server.persistence.jpa.entity;
+
+import org.apache.syncope.server.persistence.api.entity.PlainSchema;
+
+public abstract class AbstractPlainAttrTemplate<P extends PlainSchema> extends AbstractAttrTemplate<P> {
+
+    private static final long serialVersionUID = -943169893494860655L;
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainSchema.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainSchema.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainSchema.java
index ecc6fd5..78356bf 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainSchema.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainSchema.java
@@ -29,6 +29,7 @@ import javax.persistence.MappedSuperclass;
 import javax.persistence.Transient;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 import org.apache.syncope.server.persistence.api.attrvalue.validation.Validator;
@@ -231,7 +232,7 @@ public abstract class AbstractPlainSchema extends AbstractEntity<String> impleme
 
     @Override
     public void setConversionPattern(final String conversionPattern) {
-        if (!getType().isConversionPatternNeeded()) {
+        if (StringUtils.isNotBlank(conversionPattern) && !getType().isConversionPatternNeeded()) {
             LOG.warn("Conversion pattern will be ignored: this attribute type is {}", getType());
         }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractVirAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractVirAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractVirAttrTemplate.java
new file mode 100644
index 0000000..5a3b2e4
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractVirAttrTemplate.java
@@ -0,0 +1,41 @@
+/*
+ * 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.server.persistence.jpa.entity;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+import org.apache.syncope.server.persistence.api.entity.VirSchema;
+
+@MappedSuperclass
+public abstract class AbstractVirAttrTemplate<V extends VirSchema> extends AbstractAttrTemplate<V> {
+
+    private static final long serialVersionUID = -943169893494860655L;
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    protected Long id;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAAttributableUtil.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAAttributableUtil.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAAttributableUtil.java
index bf468ce..94f95a8 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAAttributableUtil.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAAttributableUtil.java
@@ -744,15 +744,15 @@ public class JPAAttributableUtil implements AttributableUtil {
 
         switch (type) {
             case ROLE:
-                result = IntMappingType.RoleSchema;
+                result = IntMappingType.RolePlainSchema;
                 break;
 
             case MEMBERSHIP:
-                result = IntMappingType.MembershipSchema;
+                result = IntMappingType.MembershipPlainSchema;
                 break;
 
             case USER:
-                result = IntMappingType.UserSchema;
+                result = IntMappingType.UserPlainSchema;
                 break;
 
             case CONFIGURATION:
@@ -768,15 +768,15 @@ public class JPAAttributableUtil implements AttributableUtil {
 
         switch (type) {
             case ROLE:
-                result = IntMappingType.RoleSchema;
+                result = IntMappingType.RoleDerivedSchema;
                 break;
 
             case MEMBERSHIP:
-                result = IntMappingType.MembershipSchema;
+                result = IntMappingType.MembershipDerivedSchema;
                 break;
 
             case USER:
-                result = IntMappingType.UserSchema;
+                result = IntMappingType.UserDerivedSchema;
                 break;
 
             case CONFIGURATION:

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAConnInstance.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAConnInstance.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAConnInstance.java
index 2c1e956..28e1c87 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAConnInstance.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAConnInstance.java
@@ -186,7 +186,7 @@ public class JPAConnInstance extends AbstractEntity<Long> implements ConnInstanc
         if (!StringUtils.isBlank(jsonConf)) {
             ConnConfProperty[] deserialized = POJOHelper.deserialize(jsonConf, ConnConfProperty[].class);
             if (ArrayUtils.isNotEmpty(deserialized)) {
-                configuration = new HashSet<ConnConfProperty>(Arrays.asList(deserialized));
+                configuration = new HashSet<>(Arrays.asList(deserialized));
             }
         }
 
@@ -195,7 +195,7 @@ public class JPAConnInstance extends AbstractEntity<Long> implements ConnInstanc
 
     @Override
     public void setConfiguration(final Set<ConnConfProperty> configuration) {
-        jsonConf = POJOHelper.serialize(new HashSet<ConnConfProperty>(configuration));
+        jsonConf = POJOHelper.serialize(new HashSet<>(configuration));
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAReport.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAReport.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAReport.java
index d045bcf..8b01c60 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAReport.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAReport.java
@@ -113,8 +113,6 @@ public class JPAReport extends AbstractEntity<Long> implements Report {
             return false;
         }
 
-        checkType(reportletConf, JPAReportletConfInstance.class);
-
         JPAReportletConfInstance found = null;
         for (JPAReportletConfInstance instance : reportletConfs) {
             if (reportletConf.equals(instance.getInstance())) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMDerAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMDerAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMDerAttrTemplate.java
index a106453..f52627c 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMDerAttrTemplate.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMDerAttrTemplate.java
@@ -25,12 +25,12 @@ import javax.persistence.Table;
 import org.apache.syncope.server.persistence.api.entity.membership.MDerAttrTemplate;
 import org.apache.syncope.server.persistence.api.entity.membership.MDerSchema;
 import org.apache.syncope.server.persistence.api.entity.role.Role;
-import org.apache.syncope.server.persistence.jpa.entity.AbstractAttrTemplate;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractDerAttrTemplate;
 import org.apache.syncope.server.persistence.jpa.entity.role.JPARole;
 
 @Entity
 @Table(name = JPAMDerAttrTemplate.TABLE)
-public class JPAMDerAttrTemplate extends AbstractAttrTemplate<MDerSchema> implements MDerAttrTemplate {
+public class JPAMDerAttrTemplate extends AbstractDerAttrTemplate<MDerSchema> implements MDerAttrTemplate {
 
     private static final long serialVersionUID = -4465930976210263434L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMPlainAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMPlainAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMPlainAttrTemplate.java
index 5fdf9ec..5f33b8c 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMPlainAttrTemplate.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMPlainAttrTemplate.java
@@ -19,23 +19,27 @@
 package org.apache.syncope.server.persistence.jpa.entity.membership;
 
 import javax.persistence.Entity;
+import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
 import org.apache.syncope.server.persistence.api.entity.membership.MPlainAttrTemplate;
 import org.apache.syncope.server.persistence.api.entity.membership.MPlainSchema;
 import org.apache.syncope.server.persistence.api.entity.role.Role;
-import org.apache.syncope.server.persistence.jpa.entity.AbstractAttrTemplate;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractPlainAttrTemplate;
 import org.apache.syncope.server.persistence.jpa.entity.role.JPARole;
 
 @Entity
 @Table(name = JPAMPlainAttrTemplate.TABLE)
-public class JPAMPlainAttrTemplate extends AbstractAttrTemplate<MPlainSchema> implements MPlainAttrTemplate {
+public class JPAMPlainAttrTemplate extends AbstractPlainAttrTemplate<MPlainSchema> implements MPlainAttrTemplate {
 
     private static final long serialVersionUID = -8768086609963244514L;
 
     public static final String TABLE = "MPlainAttrTemplate";
 
+    @Id
+    private Long id;
+
     @ManyToOne
     private JPARole owner;
 
@@ -44,6 +48,11 @@ public class JPAMPlainAttrTemplate extends AbstractAttrTemplate<MPlainSchema> im
     private JPAMPlainSchema schema;
 
     @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
     public MPlainSchema getSchema() {
         return schema;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMVirAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMVirAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMVirAttrTemplate.java
index 241d28c..1d7e184 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMVirAttrTemplate.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMVirAttrTemplate.java
@@ -25,12 +25,12 @@ import javax.persistence.Table;
 import org.apache.syncope.server.persistence.api.entity.membership.MVirAttrTemplate;
 import org.apache.syncope.server.persistence.api.entity.membership.MVirSchema;
 import org.apache.syncope.server.persistence.api.entity.role.Role;
-import org.apache.syncope.server.persistence.jpa.entity.AbstractAttrTemplate;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractVirAttrTemplate;
 import org.apache.syncope.server.persistence.jpa.entity.role.JPARole;
 
 @Entity
 @Table(name = JPAMVirAttrTemplate.TABLE)
-public class JPAMVirAttrTemplate extends AbstractAttrTemplate<MVirSchema> implements MVirAttrTemplate {
+public class JPAMVirAttrTemplate extends AbstractVirAttrTemplate<MVirSchema> implements MVirAttrTemplate {
 
     private static final long serialVersionUID = 6618560912535667392L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARDerAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARDerAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARDerAttrTemplate.java
index 3686f48..7ddc20f 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARDerAttrTemplate.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARDerAttrTemplate.java
@@ -25,11 +25,11 @@ import javax.persistence.Table;
 import org.apache.syncope.server.persistence.api.entity.role.RDerAttrTemplate;
 import org.apache.syncope.server.persistence.api.entity.role.RDerSchema;
 import org.apache.syncope.server.persistence.api.entity.role.Role;
-import org.apache.syncope.server.persistence.jpa.entity.AbstractAttrTemplate;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractDerAttrTemplate;
 
 @Entity
 @Table(name = JPARDerAttrTemplate.TABLE)
-public class JPARDerAttrTemplate extends AbstractAttrTemplate<RDerSchema> implements RDerAttrTemplate {
+public class JPARDerAttrTemplate extends AbstractDerAttrTemplate<RDerSchema> implements RDerAttrTemplate {
 
     private static final long serialVersionUID = 624868884107016649L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainAttrTemplate.java
index 9c0e603..fa6e8ee 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainAttrTemplate.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainAttrTemplate.java
@@ -19,25 +19,34 @@
 package org.apache.syncope.server.persistence.jpa.entity.role;
 
 import javax.persistence.Entity;
+import javax.persistence.Id;
 import javax.persistence.JoinColumn;
 import javax.persistence.ManyToOne;
 import javax.persistence.Table;
 import org.apache.syncope.server.persistence.api.entity.role.RPlainAttrTemplate;
 import org.apache.syncope.server.persistence.api.entity.role.RPlainSchema;
 import org.apache.syncope.server.persistence.api.entity.role.Role;
-import org.apache.syncope.server.persistence.jpa.entity.AbstractAttrTemplate;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractPlainAttrTemplate;
 
 @Entity
 @Table(name = JPARPlainAttrTemplate.TABLE)
-public class JPARPlainAttrTemplate extends AbstractAttrTemplate<RPlainSchema> implements RPlainAttrTemplate {
+public class JPARPlainAttrTemplate extends AbstractPlainAttrTemplate<RPlainSchema> implements RPlainAttrTemplate {
 
     private static final long serialVersionUID = 6943917051517266268L;
 
     public static final String TABLE = "RPlainAttrTemplate";
 
+    @Id
+    private Long id;
+
     @ManyToOne
     private JPARole owner;
 
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
     @ManyToOne
     @JoinColumn(name = "schema_name")
     private JPARPlainSchema schema;

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirAttrTemplate.java
index 1de733a..74200db 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirAttrTemplate.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirAttrTemplate.java
@@ -25,11 +25,11 @@ import javax.persistence.Table;
 import org.apache.syncope.server.persistence.api.entity.role.RVirAttrTemplate;
 import org.apache.syncope.server.persistence.api.entity.role.RVirSchema;
 import org.apache.syncope.server.persistence.api.entity.role.Role;
-import org.apache.syncope.server.persistence.jpa.entity.AbstractAttrTemplate;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractVirAttrTemplate;
 
 @Entity
 @Table(name = JPARVirAttrTemplate.TABLE)
-public class JPARVirAttrTemplate extends AbstractAttrTemplate<RVirSchema> implements RVirAttrTemplate {
+public class JPARVirAttrTemplate extends AbstractVirAttrTemplate<RVirSchema> implements RVirAttrTemplate {
 
     private static final long serialVersionUID = 4896495904794493479L;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskUtil.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskUtil.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskUtil.java
index 4086018..178d2b0 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskUtil.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskUtil.java
@@ -80,12 +80,33 @@ public final class JPATaskUtil implements TaskUtil {
 
     @Override
     public <T extends Task> T newTask() {
-        final Class<T> taskClass = taskClass();
-        try {
-            return taskClass == null ? null : taskClass.newInstance();
-        } catch (Exception e) {
-            return null;
+        T result = null;
+
+        switch (type) {
+            case PROPAGATION:
+                result = (T) new JPAPropagationTask();
+                break;
+
+            case SCHEDULED:
+                result = (T) new JPASchedTask();
+                break;
+
+            case SYNCHRONIZATION:
+                result = (T) new JPASyncTask();
+                break;
+
+            case PUSH:
+                result = (T) new JPAPushTask();
+                break;
+
+            case NOTIFICATION:
+                result = (T) new JPANotificationTask();
+                break;
+
+            default:
         }
+
+        return result;
     }
 
     @Override
@@ -119,7 +140,6 @@ public final class JPATaskUtil implements TaskUtil {
         return result;
     }
 
-    @SuppressWarnings("unchecked")
     @Override
     public <T extends AbstractTaskTO> T newTaskTO() {
         final Class<T> taskClass = taskTOClass();

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/EntityValidationListener.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/EntityValidationListener.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/EntityValidationListener.java
index bd40a4c..5f8c89d 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/EntityValidationListener.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/EntityValidationListener.java
@@ -23,8 +23,17 @@ import javax.persistence.PrePersist;
 import javax.persistence.PreUpdate;
 import javax.validation.ConstraintViolation;
 import javax.validation.Validator;
+import org.apache.commons.lang3.ClassUtils;
 import org.apache.syncope.server.persistence.api.attrvalue.validation.InvalidEntityException;
 import org.apache.syncope.server.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.server.persistence.api.entity.AnnotatedEntity;
+import org.apache.syncope.server.persistence.api.entity.Attr;
+import org.apache.syncope.server.persistence.api.entity.Attributable;
+import org.apache.syncope.server.persistence.api.entity.Entity;
+import org.apache.syncope.server.persistence.api.entity.Policy;
+import org.apache.syncope.server.persistence.api.entity.Schema;
+import org.apache.syncope.server.persistence.api.entity.Subject;
+import org.apache.syncope.server.persistence.api.entity.task.Task;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -45,7 +54,24 @@ public class EntityValidationListener {
         Set<ConstraintViolation<Object>> violations = validator.validate(object);
         if (!violations.isEmpty()) {
             LOG.warn("Bean validation errors found: {}", violations);
-            throw new InvalidEntityException(object.getClass().getSimpleName(), violations);
+
+            Class<?> entityInt = null;
+            for (Class<?> interf : ClassUtils.getAllInterfaces(object.getClass())) {
+                if (!Entity.class.equals(interf)
+                        && !AnnotatedEntity.class.equals(interf)
+                        && !Schema.class.equals(interf)
+                        && !Attr.class.equals(interf)
+                        && !Task.class.equals(interf)
+                        && !Policy.class.equals(interf)
+                        && !Attributable.class.equals(interf)
+                        && !Subject.class.equals(interf)
+                        && Entity.class.isAssignableFrom(interf)) {
+
+                    entityInt = interf;
+                }
+            }
+
+            throw new InvalidEntityException(entityInt == null ? "Entity" : entityInt.getSimpleName(), violations);
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/resources/META-INF/orm.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/resources/META-INF/orm.xml b/syncope620/server/persistence-jpa/src/main/resources/META-INF/orm.xml
index 9a828d4..93bc24d 100644
--- a/syncope620/server/persistence-jpa/src/main/resources/META-INF/orm.xml
+++ b/syncope620/server/persistence-jpa/src/main/resources/META-INF/orm.xml
@@ -124,11 +124,27 @@ under the License.
       </id>
     </attributes>
   </entity>
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.role.JPARPlainAttrTemplate">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_RPlainAttrTemplate" strategy="TABLE"/>
+        <table-generator name="SEQ_RPlainAttrTemplate" pk-column-value="SEQ_RPlainAttrTemplate" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
   <entity class="org.apache.syncope.server.persistence.jpa.entity.membership.JPAMPlainAttr">
     <attributes>
       <id name="id">
-        <generated-value generator="SEQ_MAttrPlain" strategy="TABLE"/>
-        <table-generator name="SEQ_MAttrPlain" pk-column-value="SEQ_MAttrPlain" initial-value="1000"/>
+        <generated-value generator="SEQ_MPlainAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_MPlainAttr" pk-column-value="SEQ_MPlainAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.membership.JPAMPlainAttrTemplate">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_MPlainAttrTemplate" strategy="TABLE"/>
+        <table-generator name="SEQ_MPlainAttrTemplate" pk-column-value="SEQ_MPlainAttrTemplate" initial-value="1000"/>
       </id>
     </attributes>
   </entity>

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/AttributableSearchTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/AttributableSearchTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/AttributableSearchTest.java
index 4b6345b..9eaa312 100644
--- a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/AttributableSearchTest.java
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/AttributableSearchTest.java
@@ -131,7 +131,7 @@ public class AttributableSearchTest extends AbstractTest {
         assertNotNull(users);
         assertEquals(4, users.size());
 
-        Set<Long> ids = new HashSet<Long>(users.size());
+        Set<Long> ids = new HashSet<>(users.size());
         for (User user : users) {
             ids.add(user.getKey());
         }
@@ -254,16 +254,30 @@ public class AttributableSearchTest extends AbstractTest {
     }
 
     @Test
-    public void searchByUsernameAndId() {
-        SubjectCond usernameLeafCond = new SubjectCond(SubjectCond.Type.EQ);
+    public void searchByBooleanSubjectCond() {
+        SubjectCond booleanCond = new SubjectCond(SubjectCond.Type.EQ);
+        booleanCond.setSchema("inheritPlainAttrs");
+        booleanCond.setExpression("true");
+
+        SearchCond searchCondition = SearchCond.getLeafCond(booleanCond);
+
+        List<Role> matchingRoles = searchDAO.search(RoleEntitlementUtil.getRoleKeys(entitlementDAO.findAll()),
+                searchCondition, SubjectType.ROLE);
+        assertNotNull(matchingRoles);
+        assertFalse(matchingRoles.isEmpty());
+    }
+
+    @Test
+    public void searchByUsernameAndKey() {
+        SubjectCond usernameLeafCond = new SubjectCond(SubjectCond.Type.LIKE);
         usernameLeafCond.setSchema("username");
-        usernameLeafCond.setExpression("rossini");
+        usernameLeafCond.setExpression("%ini");
 
         SubjectCond idRightCond = new SubjectCond(SubjectCond.Type.LT);
-        idRightCond.setSchema("id");
+        idRightCond.setSchema("key");
         idRightCond.setExpression("2");
 
-        SearchCond searchCondition = SearchCond.getOrCond(SearchCond.getLeafCond(usernameLeafCond),
+        SearchCond searchCondition = SearchCond.getAndCond(SearchCond.getLeafCond(usernameLeafCond),
                 SearchCond.getLeafCond(idRightCond));
 
         List<User> matchingUsers = searchDAO.search(RoleEntitlementUtil.getRoleKeys(entitlementDAO.findAll()),
@@ -276,13 +290,13 @@ public class AttributableSearchTest extends AbstractTest {
     }
 
     @Test
-    public void searchByRolenameAndId() {
+    public void searchByRolenameAndKey() {
         SubjectCond rolenameLeafCond = new SubjectCond(SubjectCond.Type.EQ);
         rolenameLeafCond.setSchema("name");
         rolenameLeafCond.setExpression("root");
 
         SubjectCond idRightCond = new SubjectCond(SubjectCond.Type.LT);
-        idRightCond.setSchema("id");
+        idRightCond.setSchema("key");
         idRightCond.setExpression("2");
 
         SearchCond searchCondition = SearchCond.getAndCond(SearchCond.getLeafCond(rolenameLeafCond),

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/NotificationTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/NotificationTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/NotificationTest.java
index 7cd9eae..91ad890 100644
--- a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/NotificationTest.java
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/NotificationTest.java
@@ -65,7 +65,7 @@ public class NotificationTest extends AbstractTest {
         notification.setRecipients("fake search condition");
 
         notification.setRecipientAttrName("email");
-        notification.setRecipientAttrType(IntMappingType.UserSchema);
+        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
 
         notification.setSender("syncope@syncope.apache.org");
         notification.setSubject("Test notification");
@@ -92,7 +92,7 @@ public class NotificationTest extends AbstractTest {
         notification.setRecipients("fake search condition");
 
         notification.setRecipientAttrName("email");
-        notification.setRecipientAttrType(IntMappingType.UserSchema);
+        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
 
         notification.addStaticRecipient("syncope445@syncope.apache.org");
 
@@ -115,7 +115,7 @@ public class NotificationTest extends AbstractTest {
         notification.setRoleAbout("fake search condition");
 
         notification.setRecipientAttrName("email");
-        notification.setRecipientAttrType(IntMappingType.UserSchema);
+        notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
 
         notification.addStaticRecipient("syncope446@syncope.apache.org");
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ResourceTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ResourceTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ResourceTest.java
index c1c2355..68d1516 100644
--- a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ResourceTest.java
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ResourceTest.java
@@ -133,7 +133,7 @@ public class ResourceTest extends AbstractTest {
 
         UMappingItem accountId = entityFactory.newEntity(UMappingItem.class);
         accountId.setAccountid(true);
-        accountId.setIntMappingType(IntMappingType.UserSchema);
+        accountId.setIntMappingType(IntMappingType.UserPlainSchema);
         mapping.addItem(accountId);
 
         // save the resource
@@ -176,12 +176,12 @@ public class ResourceTest extends AbstractTest {
         UMappingItem item = entityFactory.newEntity(UMappingItem.class);
         item.setAccountid(true);
         item.setIntAttrName("fullname");
-        item.setIntMappingType(IntMappingType.UserSchema);
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
         mapping.addItem(item);
 
         item = entityFactory.newEntity(UMappingItem.class);
         item.setIntAttrName("userId");
-        item.setIntMappingType(IntMappingType.UserSchema);
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
         mapping.addItem(item);
 
         ExternalResource actual = resourceDAO.save(resource);
@@ -202,14 +202,14 @@ public class ResourceTest extends AbstractTest {
         UMappingItem item = entityFactory.newEntity(UMappingItem.class);
         item.setIntAttrName("fullname");
         item.setExtAttrName("fullname");
-        item.setIntMappingType(IntMappingType.UserSchema);
+        item.setIntMappingType(IntMappingType.UserPlainSchema);
         item.setPurpose(MappingPurpose.BOTH);
         mapping.setAccountIdItem(item);
 
         item = entityFactory.newEntity(UMappingItem.class);
         item.setIntAttrName("icon");
         item.setExtAttrName("icon");
-        item.setIntMappingType(IntMappingType.RoleSchema);
+        item.setIntMappingType(IntMappingType.RolePlainSchema);
         item.setPurpose(MappingPurpose.BOTH);
         mapping.addItem(item);