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/01 19:12:16 UTC

[21/32] syncope git commit: [SYNCOPE-620] JPA entities + basic tests

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PlainSchemaValidator.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PlainSchemaValidator.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PlainSchemaValidator.java
new file mode 100644
index 0000000..5267785
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PlainSchemaValidator.java
@@ -0,0 +1,61 @@
+/*
+ * 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.persistence.jpa.validation.entity;
+
+import javax.validation.ConstraintValidatorContext;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.persistence.api.entity.PlainSchema;
+
+public class PlainSchemaValidator extends AbstractValidator<PlainSchemaCheck, PlainSchema> {
+
+    @Override
+    public boolean isValid(final PlainSchema schema, final ConstraintValidatorContext context) {
+        boolean isValid = schema.getType() != AttrSchemaType.Enum
+                || StringUtils.isNotBlank(schema.getEnumerationValues());
+        if (!isValid) {
+            context.disableDefaultConstraintViolation();
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidSchemaEnum, "Enumeration values missing")).
+                    addPropertyNode("enumerationValues").addConstraintViolation();
+        } else {
+            isValid = schema.getType() != AttrSchemaType.Encrypted
+                    || (schema.getSecretKey() != null && schema.getCipherAlgorithm() != null);
+            if (!isValid) {
+                context.disableDefaultConstraintViolation();
+                context.buildConstraintViolationWithTemplate(
+                        getTemplate(EntityViolationType.InvalidSchemaEncrypted,
+                                "SecretKey or CipherAlgorithm missing")).
+                        addPropertyNode("secretKey").addPropertyNode("cipherAlgorithm").addConstraintViolation();
+            } else {
+                isValid = !schema.isMultivalue() || !schema.isUniqueConstraint();
+                if (!isValid) {
+                    context.disableDefaultConstraintViolation();
+                    context.buildConstraintViolationWithTemplate(
+                            getTemplate(EntityViolationType.InvalidSchemaMultivalueUnique,
+                                    "Cannot contemporary be multivalue and have unique constraint")).
+                            addPropertyNode("multiValue").addConstraintViolation();
+                }
+            }
+        }
+
+        return isValid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PolicyCheck.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PolicyCheck.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PolicyCheck.java
new file mode 100644
index 0000000..e67b662
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PolicyCheck.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.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = PolicyValidator.class)
+@Documented
+public @interface PolicyCheck {
+
+    String message() default "{org.apache.syncope.persistence.validation.policy}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PolicyValidator.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PolicyValidator.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PolicyValidator.java
new file mode 100644
index 0000000..551bc6f
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PolicyValidator.java
@@ -0,0 +1,59 @@
+/*
+ * 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.persistence.jpa.validation.entity;
+
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.types.AccountPolicySpec;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.PasswordPolicySpec;
+import org.apache.syncope.common.lib.types.SyncPolicySpec;
+import org.apache.syncope.persistence.api.entity.AccountPolicy;
+import org.apache.syncope.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.persistence.api.entity.Policy;
+import org.apache.syncope.persistence.api.entity.SyncPolicy;
+
+public class PolicyValidator extends AbstractValidator<PolicyCheck, Policy> {
+
+    @Override
+    public boolean isValid(final Policy object, final ConstraintValidatorContext context) {
+        context.disableDefaultConstraintViolation();
+
+        EntityViolationType violationType =
+                object instanceof PasswordPolicy
+                && !(object.getSpecification(PasswordPolicySpec.class) instanceof PasswordPolicySpec)
+                        ? EntityViolationType.InvalidPasswordPolicy
+                        : object instanceof AccountPolicy
+                        && !(object.getSpecification(AccountPolicySpec.class) instanceof AccountPolicySpec)
+                                ? EntityViolationType.InvalidAccountPolicy
+                                : object instanceof SyncPolicy
+                                && !(object.getSpecification(SyncPolicySpec.class) instanceof SyncPolicySpec)
+                                        ? EntityViolationType.InvalidSyncPolicy
+                                        : null;
+
+        if (violationType != null) {
+            context.buildConstraintViolationWithTemplate(getTemplate(violationType,
+                    "Invalid policy specification")).addPropertyNode("specification").
+                    addConstraintViolation();
+
+            return false;
+        }
+
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PropagationTaskCheck.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PropagationTaskCheck.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PropagationTaskCheck.java
new file mode 100644
index 0000000..f6d374f
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PropagationTaskCheck.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.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = PropagationTaskValidator.class)
+@Documented
+public @interface PropagationTaskCheck {
+
+    String message() default "{org.apache.syncope.persistence.validation.propagationtask}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PropagationTaskValidator.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PropagationTaskValidator.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PropagationTaskValidator.java
new file mode 100644
index 0000000..8e53c47
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/PropagationTaskValidator.java
@@ -0,0 +1,65 @@
+/*
+ * 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.persistence.jpa.validation.entity;
+
+import java.util.List;
+
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.persistence.api.entity.task.TaskExec;
+
+public class PropagationTaskValidator extends AbstractValidator<PropagationTaskCheck, PropagationTask> {
+
+    @Override
+    public boolean isValid(final PropagationTask task, final ConstraintValidatorContext context) {
+        boolean isValid;
+
+        if (task == null) {
+            isValid = true;
+        } else {
+            isValid = task.getPropagationMode() != null
+                    && task.getPropagationOperation() != null
+                    && !task.getAttributes().isEmpty()
+                    && task.getResource() != null;
+
+            if (isValid) {
+                List<? extends TaskExec> executions = task.getExecs();
+                for (TaskExec execution : executions) {
+                    try {
+                        PropagationTaskExecStatus.valueOf(execution.getStatus());
+                    } catch (IllegalArgumentException e) {
+                        LOG.error("Invalid execution status '" + execution.getStatus() + "'", e);
+                        isValid = false;
+                    }
+                }
+            }
+
+            if (!isValid) {
+                context.disableDefaultConstraintViolation();
+                context.buildConstraintViolationWithTemplate(
+                        getTemplate(EntityViolationType.InvalidPropagationTask, "Invalid task")).
+                        addPropertyNode(task.getClass().getSimpleName()).addConstraintViolation();
+            }
+        }
+
+        return isValid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/ProvisioningTaskCheck.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/ProvisioningTaskCheck.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/ProvisioningTaskCheck.java
new file mode 100644
index 0000000..affc52a
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/ProvisioningTaskCheck.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.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = ProvisioningTaskValidator.class)
+@Documented
+public @interface ProvisioningTaskCheck {
+
+    String message() default "{org.apache.syncope.persistence.validation.abstractsynctask}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/ProvisioningTaskValidator.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
new file mode 100644
index 0000000..01d1d5d
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
@@ -0,0 +1,84 @@
+/*
+ * 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.persistence.jpa.validation.entity;
+
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.persistence.jpa.entity.task.JPAPushTask;
+import org.apache.syncope.persistence.jpa.entity.task.JPASyncTask;
+import org.apache.syncope.provisioning.api.sync.PushActions;
+import org.apache.syncope.provisioning.api.sync.SyncActions;
+
+public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTaskCheck, ProvisioningTask> {
+
+    private final SchedTaskValidator schedV;
+
+    public ProvisioningTaskValidator() {
+        super();
+
+        schedV = new SchedTaskValidator();
+    }
+
+    @Override
+    public boolean isValid(final ProvisioningTask object, final ConstraintValidatorContext context) {
+        boolean isValid = schedV.isValid(object, context);
+
+        if (isValid) {
+            isValid = object.getResource() != null;
+            if (!isValid) {
+                LOG.error("Resource is null");
+
+                context.disableDefaultConstraintViolation();
+                context.buildConstraintViolationWithTemplate(
+                        getTemplate(EntityViolationType.InvalidSyncTask, "Resource cannot be null")).
+                        addPropertyNode("resource").addConstraintViolation();
+            }
+
+            if (!object.getActionsClassNames().isEmpty()) {
+                for (String className : object.getActionsClassNames()) {
+                    Class<?> actionsClass = null;
+                    boolean isAssignable = false;
+                    try {
+                        actionsClass = Class.forName(className);
+                        isAssignable = object instanceof JPASyncTask
+                                ? SyncActions.class.isAssignableFrom(actionsClass)
+                                : object instanceof JPAPushTask
+                                        ? PushActions.class.isAssignableFrom(actionsClass)
+                                        : false;
+                    } catch (Exception e) {
+                        LOG.error("Invalid SyncActions specified", e);
+                        isValid = false;
+                    }
+
+                    if (actionsClass == null || !isAssignable) {
+                        isValid = false;
+
+                        context.disableDefaultConstraintViolation();
+                        context.buildConstraintViolationWithTemplate(
+                                getTemplate(EntityViolationType.InvalidSyncTask, "Invalid class name")).
+                                addPropertyNode("actionsClassName").addConstraintViolation();
+                    }
+                }
+            }
+        }
+
+        return isValid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/ReportCheck.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/ReportCheck.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/ReportCheck.java
new file mode 100644
index 0000000..7b18e8c
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/ReportCheck.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.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = ReportValidator.class)
+@Documented
+public @interface ReportCheck {
+
+    String message() default "{org.apache.syncope.persistence.validation.report}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/ReportValidator.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/ReportValidator.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/ReportValidator.java
new file mode 100644
index 0000000..7d2aa74
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/ReportValidator.java
@@ -0,0 +1,67 @@
+/*
+ * 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.persistence.jpa.validation.entity;
+
+import java.text.ParseException;
+import java.util.HashSet;
+import java.util.Set;
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.report.ReportletConf;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.persistence.api.entity.Report;
+import org.quartz.CronExpression;
+
+public class ReportValidator extends AbstractValidator<ReportCheck, Report> {
+
+    @Override
+    @SuppressWarnings("ResultOfObjectAllocationIgnored")
+    public boolean isValid(final Report object, final ConstraintValidatorContext context) {
+        boolean isValid = true;
+
+        if (object.getCronExpression() != null) {
+            try {
+                new CronExpression(object.getCronExpression());
+            } catch (ParseException e) {
+                LOG.error("Invalid cron expression '" + object.getCronExpression() + "'", e);
+                isValid = false;
+
+                context.disableDefaultConstraintViolation();
+                context.buildConstraintViolationWithTemplate(
+                        getTemplate(EntityViolationType.InvalidReport, "Invalid cron expression")).
+                        addPropertyNode("cronExpression").addConstraintViolation();
+            }
+        }
+
+        Set<String> reportletNames = new HashSet<String>();
+        for (ReportletConf conf : object.getReportletConfs()) {
+            reportletNames.add(conf.getName());
+        }
+        if (reportletNames.size() != object.getReportletConfs().size()) {
+            LOG.error("Reportlet name must be unique");
+            isValid = false;
+
+            context.disableDefaultConstraintViolation();
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidReport, "Reportlet name must be unique")).
+                    addPropertyNode("reportletConfs").addConstraintViolation();
+        }
+
+        return isValid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/RoleCheck.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/RoleCheck.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/RoleCheck.java
new file mode 100644
index 0000000..fc9d958
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/RoleCheck.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.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = RoleValidator.class)
+@Documented
+public @interface RoleCheck {
+
+    String message() default "{org.apache.syncope.persistence.validation.syncoperole}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/RoleValidator.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/RoleValidator.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/RoleValidator.java
new file mode 100644
index 0000000..a946b30
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/RoleValidator.java
@@ -0,0 +1,44 @@
+/*
+ * 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.persistence.jpa.validation.entity;
+
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.persistence.api.entity.role.Role;
+
+public class RoleValidator extends AbstractValidator<RoleCheck, Role> {
+
+    @Override
+    public boolean isValid(final Role object, final ConstraintValidatorContext context) {
+        context.disableDefaultConstraintViolation();
+
+        boolean isValid = true;
+
+        if (object.getUserOwner() != null && object.getRoleOwner() != null) {
+            isValid = false;
+
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidRoleOwner,
+                            "A role must either be owned by an user or a role, not both")).
+                    addPropertyNode("owner").addConstraintViolation();
+        }
+
+        return isValid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/SchedTaskCheck.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/SchedTaskCheck.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/SchedTaskCheck.java
new file mode 100644
index 0000000..2b67e4b
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/SchedTaskCheck.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.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = SchedTaskValidator.class)
+@Documented
+public @interface SchedTaskCheck {
+
+    String message() default "{org.apache.syncope.persistence.validation.schedtask}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/SchedTaskValidator.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/SchedTaskValidator.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/SchedTaskValidator.java
new file mode 100644
index 0000000..2591b94
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/SchedTaskValidator.java
@@ -0,0 +1,68 @@
+/*
+ * 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.persistence.jpa.validation.entity;
+
+import java.text.ParseException;
+
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.persistence.api.entity.task.SchedTask;
+import org.quartz.CronExpression;
+import org.quartz.Job;
+
+public class SchedTaskValidator extends AbstractValidator<SchedTaskCheck, SchedTask> {
+
+    @Override
+    public boolean isValid(final SchedTask object, final ConstraintValidatorContext context) {
+        boolean isValid;
+
+        Class<?> jobClass = null;
+        try {
+            jobClass = Class.forName(object.getJobClassName());
+            isValid = Job.class.isAssignableFrom(jobClass);
+        } catch (Exception e) {
+            LOG.error("Invalid Job class specified", e);
+            isValid = false;
+        }
+        if (jobClass == null || !isValid) {
+            isValid = false;
+
+            context.disableDefaultConstraintViolation();
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidSchedTask, "Invalid job class name")).
+                    addPropertyNode("jobClassName").addConstraintViolation();
+        }
+
+        if (isValid && object.getCronExpression() != null) {
+            try {
+                new CronExpression(object.getCronExpression());
+            } catch (ParseException e) {
+                LOG.error("Invalid cron expression '" + object.getCronExpression() + "'", e);
+                isValid = false;
+
+                context.disableDefaultConstraintViolation();
+                context.buildConstraintViolationWithTemplate(
+                        getTemplate(EntityViolationType.InvalidSchedTask, "Invalid cron expression")).
+                        addPropertyNode("cronExpression").addConstraintViolation();
+            }
+        }
+
+        return isValid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/SchemaNameCheck.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/SchemaNameCheck.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/SchemaNameCheck.java
new file mode 100644
index 0000000..b445c79
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/SchemaNameCheck.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.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = SchemaNameValidator.class)
+@Documented
+public @interface SchemaNameCheck {
+
+    String message() default "{org.apache.syncope.persistence.validation.schema}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/SchemaNameValidator.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/SchemaNameValidator.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/SchemaNameValidator.java
new file mode 100644
index 0000000..eda316d
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/SchemaNameValidator.java
@@ -0,0 +1,133 @@
+/*
+ * 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.persistence.jpa.validation.entity;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import javax.validation.ConstraintValidatorContext;
+import org.apache.commons.lang3.ClassUtils;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.persistence.api.entity.conf.CPlainSchema;
+import org.apache.syncope.persistence.api.entity.membership.MDerSchema;
+import org.apache.syncope.persistence.api.entity.membership.MPlainSchema;
+import org.apache.syncope.persistence.api.entity.membership.MVirSchema;
+import org.apache.syncope.persistence.api.entity.role.RDerSchema;
+import org.apache.syncope.persistence.api.entity.role.RPlainSchema;
+import org.apache.syncope.persistence.api.entity.role.RVirSchema;
+import org.apache.syncope.persistence.api.entity.user.UDerSchema;
+import org.apache.syncope.persistence.api.entity.user.UPlainSchema;
+import org.apache.syncope.persistence.api.entity.user.UVirSchema;
+import org.apache.syncope.persistence.jpa.entity.conf.JPAConf;
+import org.apache.syncope.persistence.jpa.entity.membership.JPAMembership;
+import org.apache.syncope.persistence.jpa.entity.role.JPARole;
+import org.apache.syncope.persistence.jpa.entity.user.JPAUser;
+
+public class SchemaNameValidator extends AbstractValidator<SchemaNameCheck, Object> {
+
+    private static final List<String> UNALLOWED_USCHEMA_NAMES = new ArrayList<>();
+
+    private static final List<String> UNALLOWED_MSCHEMA_NAMES = new ArrayList<>();
+
+    private static final List<String> UNALLOWED_RSCHEMA_NAMES = new ArrayList<>();
+
+    private static final List<String> UNALLOWED_CSCHEMA_NAMES = new ArrayList<>();
+
+    static {
+        initUnallowedSchemaNames(JPAUser.class, UNALLOWED_USCHEMA_NAMES);
+        initUnallowedSchemaNames(JPAMembership.class, UNALLOWED_MSCHEMA_NAMES);
+        initUnallowedSchemaNames(JPARole.class, UNALLOWED_RSCHEMA_NAMES);
+        initUnallowedSchemaNames(JPAConf.class, UNALLOWED_CSCHEMA_NAMES);
+    }
+
+    private static void initUnallowedSchemaNames(final Class<?> entityClass, final List<String> names) {
+        List<Class<?>> classes = ClassUtils.getAllSuperclasses(entityClass);
+        classes.add(JPAUser.class);
+        for (Class<?> clazz : classes) {
+            for (Field field : clazz.getDeclaredFields()) {
+                if (!Collection.class.isAssignableFrom(field.getType())
+                        && !Map.class.isAssignableFrom(field.getType())) {
+
+                    names.add(field.getName());
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean isValid(final Object object, final ConstraintValidatorContext context) {
+        final String schemaName;
+        final List<String> unallowedNames;
+
+        if (object instanceof UPlainSchema) {
+            schemaName = ((UPlainSchema) object).getKey();
+            unallowedNames = UNALLOWED_USCHEMA_NAMES;
+        } else if (object instanceof UDerSchema) {
+            schemaName = ((UDerSchema) object).getKey();
+            unallowedNames = UNALLOWED_USCHEMA_NAMES;
+        } else if (object instanceof UVirSchema) {
+            schemaName = ((UVirSchema) object).getKey();
+            unallowedNames = UNALLOWED_USCHEMA_NAMES;
+        } else if (object instanceof MPlainSchema) {
+            schemaName = ((MPlainSchema) object).getKey();
+            unallowedNames = UNALLOWED_MSCHEMA_NAMES;
+        } else if (object instanceof MDerSchema) {
+            schemaName = ((MDerSchema) object).getKey();
+            unallowedNames = UNALLOWED_MSCHEMA_NAMES;
+        } else if (object instanceof MVirSchema) {
+            schemaName = ((MVirSchema) object).getKey();
+            unallowedNames = UNALLOWED_MSCHEMA_NAMES;
+        } else if (object instanceof RPlainSchema) {
+            schemaName = ((RPlainSchema) object).getKey();
+            unallowedNames = UNALLOWED_RSCHEMA_NAMES;
+        } else if (object instanceof RDerSchema) {
+            schemaName = ((RDerSchema) object).getKey();
+            unallowedNames = UNALLOWED_RSCHEMA_NAMES;
+        } else if (object instanceof RVirSchema) {
+            schemaName = ((RVirSchema) object).getKey();
+            unallowedNames = UNALLOWED_RSCHEMA_NAMES;
+        } else if (object instanceof CPlainSchema) {
+            schemaName = ((CPlainSchema) object).getKey();
+            unallowedNames = UNALLOWED_CSCHEMA_NAMES;
+        } else {
+            schemaName = null;
+            unallowedNames = Collections.emptyList();
+        }
+
+        boolean isValid = NAME_PATTERN.matcher(schemaName).matches();
+        if (!isValid) {
+            context.disableDefaultConstraintViolation();
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidName, "Invalid Schema name")).
+                    addPropertyNode("name").addConstraintViolation();
+        } else if (unallowedNames.contains(schemaName)) {
+            context.disableDefaultConstraintViolation();
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidName, "Schema name not allowed: " + schemaName)).
+                    addPropertyNode("name").addConstraintViolation();
+
+            return false;
+        }
+
+        return isValid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/UserCheck.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/UserCheck.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/UserCheck.java
new file mode 100644
index 0000000..854d4dd
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/UserCheck.java
@@ -0,0 +1,42 @@
+/*
+ * 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.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+
+@Target( { ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = UserValidator.class)
+@Documented
+public @interface UserCheck {
+
+    String message() default "{org.apache.syncope.persistence.validation.syncopeuser}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/UserValidator.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/UserValidator.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/UserValidator.java
new file mode 100644
index 0000000..5ef6917
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/persistence/jpa/validation/entity/UserValidator.java
@@ -0,0 +1,194 @@
+/*
+ * 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.persistence.jpa.validation.entity;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Resource;
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.types.AccountPolicySpec;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.PasswordPolicySpec;
+import org.apache.syncope.persistence.api.dao.PolicyDAO;
+import org.apache.syncope.persistence.api.entity.AccountPolicy;
+import org.apache.syncope.persistence.api.entity.ExternalResource;
+import org.apache.syncope.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.persistence.api.entity.Policy;
+import org.apache.syncope.persistence.api.entity.role.Role;
+import org.apache.syncope.persistence.api.entity.user.User;
+import org.apache.syncope.server.utils.policy.AccountPolicyEnforcer;
+import org.apache.syncope.server.utils.policy.AccountPolicyException;
+import org.apache.syncope.server.utils.policy.PasswordPolicyEnforcer;
+import org.apache.syncope.server.utils.policy.PolicyEvaluator;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class UserValidator extends AbstractValidator<UserCheck, User> {
+
+    @Resource(name = "adminUser")
+    private String adminUser;
+
+    @Resource(name = "anonymousUser")
+    private String anonymousUser;
+
+    @Autowired
+    private PolicyDAO policyDAO;
+
+    @Autowired
+    private PolicyEvaluator evaluator;
+
+    @Autowired
+    private PasswordPolicyEnforcer ppEnforcer;
+
+    @Autowired
+    private AccountPolicyEnforcer apEnforcer;
+
+    @Override
+    public boolean isValid(final User user, final ConstraintValidatorContext context) {
+        context.disableDefaultConstraintViolation();
+
+        // ------------------------------
+        // Verify password policies
+        // ------------------------------
+        LOG.debug("Password Policy enforcement");
+
+        try {
+            int maxPPSpecHistory = 0;
+            for (Policy policy : getPasswordPolicies(user)) {
+                // evaluate policy
+                final PasswordPolicySpec ppSpec = evaluator.evaluate(policy, user);
+                // enforce policy
+                ppEnforcer.enforce(ppSpec, policy.getType(), user);
+
+                if (ppSpec.getHistoryLength() > maxPPSpecHistory) {
+                    maxPPSpecHistory = ppSpec.getHistoryLength();
+                }
+            }
+
+            // update user's password history with encrypted password
+            if (maxPPSpecHistory > 0 && user.getPassword() != null) {
+                user.getPasswordHistory().add(user.getPassword());
+            }
+            // keep only the last maxPPSpecHistory items in user's password history
+            if (maxPPSpecHistory < user.getPasswordHistory().size()) {
+                for (int i = 0; i < user.getPasswordHistory().size() - maxPPSpecHistory; i++) {
+                    user.getPasswordHistory().remove(i);
+                }
+            }
+        } catch (Exception e) {
+            LOG.debug("Invalid password");
+
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidPassword, e.getMessage())).
+                    addPropertyNode("password").addConstraintViolation();
+
+            return false;
+        } finally {
+            // password has been validated, let's remove its clear version
+            user.removeClearPassword();
+        }
+        // ------------------------------
+
+        // ------------------------------
+        // Verify account policies
+        // ------------------------------
+        LOG.debug("Account Policy enforcement");
+
+        try {
+            if (adminUser.equals(user.getUsername()) || anonymousUser.equals(user.getUsername())) {
+                throw new AccountPolicyException("Not allowed: " + user.getUsername());
+            }
+
+            // invalid username
+            for (Policy policy : getAccountPolicies(user)) {
+                // evaluate policy
+                final AccountPolicySpec accountPolicy = evaluator.evaluate(policy, user);
+
+                // enforce policy
+                apEnforcer.enforce(accountPolicy, policy.getType(), user);
+            }
+        } catch (Exception e) {
+            LOG.debug("Invalid username");
+
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidUsername, e.getMessage())).
+                    addPropertyNode("username").addConstraintViolation();
+
+            return false;
+        }
+        // ------------------------------
+
+        return true;
+    }
+
+    private List<PasswordPolicy> getPasswordPolicies(final User user) {
+        final List<PasswordPolicy> policies = new ArrayList<>();
+
+        // Add global policy
+        PasswordPolicy policy = policyDAO.getGlobalPasswordPolicy();
+        if (policy != null) {
+            policies.add(policy);
+        }
+
+        // add resource policies
+        for (ExternalResource resource : user.getResources()) {
+            policy = resource.getPasswordPolicy();
+            if (policy != null) {
+                policies.add(policy);
+            }
+        }
+
+        // add role policies
+        for (Role role : user.getRoles()) {
+            policy = role.getPasswordPolicy();
+            if (policy != null) {
+                policies.add(policy);
+            }
+        }
+
+        return policies;
+    }
+
+    private List<AccountPolicy> getAccountPolicies(final User user) {
+        final List<AccountPolicy> policies = new ArrayList<>();
+
+        // add global policy
+        AccountPolicy policy = policyDAO.getGlobalAccountPolicy();
+        if (policy != null) {
+            policies.add(policy);
+        }
+
+        // add resource policies
+        for (ExternalResource resource : user.getResources()) {
+            policy = resource.getAccountPolicy();
+            if (policy != null) {
+                policies.add(policy);
+            }
+        }
+
+        // add role policies
+        for (Role role : user.getRoles()) {
+            policy = role.getAccountPolicy();
+            if (policy != null) {
+                policies.add(policy);
+            }
+        }
+
+        return policies;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/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
new file mode 100644
index 0000000..4ea467f
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/resources/META-INF/orm.xml
@@ -0,0 +1,355 @@
+<?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.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>
+  
+  <table-generator name="SEQ_UPlainAttrValue" pk-column-value="SEQ_UPlainAttrValue" initial-value="100"/>
+  <table-generator name="SEQ_RPlainAttrValue" pk-column-value="SEQ_RPlainAttrValue" initial-value="100"/>
+  <table-generator name="SEQ_MAttrPlainValue" pk-column-value="SEQ_MAttrPlainValue" initial-value="100"/>
+  <table-generator name="SEQ_CAttrPlainValue" pk-column-value="SEQ_CAttrPlainValue" initial-value="100"/>
+
+  <entity class="org.apache.syncope.persistence.jpa.entity.user.JPAUser">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_User" strategy="TABLE"/>
+        <table-generator name="SEQ_User" pk-column-value="SEQ_User" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.persistence.jpa.entity.role.JPARole">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_Role" strategy="TABLE"/>
+        <table-generator name="SEQ_Role" pk-column-value="SEQ_Role" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.persistence.jpa.entity.membership.JPAMembership">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_Membership" strategy="TABLE"/>
+        <table-generator name="SEQ_Membership" pk-column-value="SEQ_Membership" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.persistence.jpa.entity.user.JPAUMapping">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_UMapping" strategy="TABLE"/>
+        <table-generator name="SEQ_UMapping" pk-column-value="SEQ_UMapping" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.role.JPARMapping">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_RMapping" strategy="TABLE"/>
+        <table-generator name="SEQ_RMapping" pk-column-value="SEQ_RMapping" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.user.JPAUMappingItem">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_UMappingItem" strategy="TABLE"/>
+        <table-generator name="SEQ_UMappingItem" pk-column-value="SEQ_UMappingItem" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.role.JPARMappingItem">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_RMappingItem" strategy="TABLE"/>
+        <table-generator name="SEQ_RMappingItem" pk-column-value="SEQ_RMappingItem" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.persistence.jpa.entity.JPAConnInstance">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_ConnInstance" strategy="TABLE"/>
+        <table-generator name="SEQ_ConnInstance" pk-column-value="SEQ_ConnInstance" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.persistence.jpa.entity.user.JPAUPlainAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_UPlainAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_UPlainAttr" pk-column-value="SEQ_UPlainAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.role.JPARPlainAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_RPlainAttr" strategy="TABLE"/>
+        <table-generator name="SEQ_RPlainAttr" pk-column-value="SEQ_RPlainAttr" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.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"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.conf.JPACPlainAttr">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_CAttrPlain" strategy="TABLE"/>
+        <table-generator name="SEQ_CAttrPlain" pk-column-value="SEQ_CAttrPlain" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+    
+  <entity class="org.apache.syncope.persistence.jpa.entity.user.JPAUPlainAttrValue">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_UPlainAttrValue" strategy="TABLE"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue">
+    <table>
+      <unique-constraint>
+        <column-name>booleanValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+      <unique-constraint>
+        <column-name>dateValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+      <unique-constraint>
+        <column-name>stringValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+      <unique-constraint>
+        <column-name>doubleValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+      <unique-constraint>
+        <column-name>longValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+    </table>
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_UPlainAttrValue" strategy="TABLE"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.role.JPARPlainAttrValue">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_RPlainAttrValue" strategy="TABLE"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.role.JPARPlainAttrUniqueValue">
+    <table>
+      <unique-constraint>
+        <column-name>booleanValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+      <unique-constraint>
+        <column-name>dateValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+      <unique-constraint>
+        <column-name>stringValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+      <unique-constraint>
+        <column-name>doubleValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+      <unique-constraint>
+        <column-name>longValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+    </table>
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_RPlainAttrValue" strategy="TABLE"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.membership.JPAMPlainAttrValue">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_MAttrPlainValue" strategy="TABLE"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.membership.JPAMPlainAttrUniqueValue">
+    <table>
+      <unique-constraint>
+        <column-name>booleanValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+      <unique-constraint>
+        <column-name>dateValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+      <unique-constraint>
+        <column-name>stringValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+      <unique-constraint>
+        <column-name>doubleValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+      <unique-constraint>
+        <column-name>longValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+    </table>
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_MAttrPlainValue" strategy="TABLE"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.conf.JPACPlainAttrValue">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_CAttrPlainValue" strategy="TABLE"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.conf.JPACPlainAttrUniqueValue">
+    <table>
+      <unique-constraint>
+        <column-name>booleanValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+      <unique-constraint>
+        <column-name>dateValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+      <unique-constraint>
+        <column-name>stringValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+      <unique-constraint>
+        <column-name>doubleValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+      <unique-constraint>
+        <column-name>longValue</column-name>
+        <column-name>schema_name</column-name>
+      </unique-constraint>
+    </table>
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_CAttrPlainValue" strategy="TABLE"/>
+      </id>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.persistence.jpa.entity.task.JPATask">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_Task" strategy="TABLE"/>
+        <table-generator name="SEQ_Task" pk-column-value="SEQ_Task" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.task.JPATaskExec">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_TaskExec" strategy="TABLE"/>
+        <table-generator name="SEQ_TaskExec" pk-column-value="SEQ_TaskExec" initial-value="10"/>
+      </id>
+    </attributes>
+  </entity>
+    
+  <entity class="org.apache.syncope.persistence.jpa.entity.JPAPolicy">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_Policy" strategy="TABLE"/>
+        <table-generator name="SEQ_Policy" pk-column-value="SEQ_Policy" initial-value="1000"/>
+      </id>
+    </attributes>
+  </entity>
+
+  <entity class="org.apache.syncope.persistence.jpa.entity.JPAReport">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_Report" strategy="TABLE"/>
+        <table-generator name="SEQ_Report" pk-column-value="SEQ_Report" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.JPAReportExec">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_ReportExec" strategy="TABLE"/>
+        <table-generator name="SEQ_ReportExec" pk-column-value="SEQ_ReportExec" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.JPAReportletConfInstance">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_ReportletConfInstance" strategy="TABLE"/>
+        <table-generator name="SEQ_ReportletConfInstance" pk-column-value="SEQ_ReportletConfInstance" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.JPANotification">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_Notification" strategy="TABLE"/>
+        <table-generator name="SEQ_Notification" pk-column-value="SEQ_Notification" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+  <entity class="org.apache.syncope.persistence.jpa.entity.JPASecurityQuestion">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_SecurityQuestion" strategy="TABLE"/>
+        <table-generator name="SEQ_SecurityQuestion" pk-column-value="SEQ_SecurityQuestion" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+</entity-mappings>

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/resources/META-INF/spring-persistence.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/resources/META-INF/spring-persistence.xml b/syncope620/server/persistence-jpa/src/main/resources/META-INF/spring-persistence.xml
new file mode 100644
index 0000000..d668353
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/resources/META-INF/spring-persistence.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
+                                 http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
+             version="2.0">
+  
+  <persistence-unit name="syncopePersistenceUnit">
+    <mapping-file>META-INF/orm.xml</mapping-file>
+    <validation-mode>NONE</validation-mode>    
+  </persistence-unit>
+  
+</persistence>

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/resources/audit/audit.sql
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/resources/audit/audit.sql b/syncope620/server/persistence-jpa/src/main/resources/audit/audit.sql
new file mode 100644
index 0000000..faf8c5b
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/resources/audit/audit.sql
@@ -0,0 +1,24 @@
+-- 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.
+
+CREATE TABLE IF NOT EXISTS SYNCOPEAUDIT (
+  EVENT_DATE TIMESTAMP,
+  LOGGER_LEVEL VARCHAR(255) NOT NULL,
+  LOGGER VARCHAR(255) NOT NULL,
+  MESSAGE TEXT NOT NULL,
+  THROWABLE TEXT
+)

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/resources/audit/audit_mysql_innodb.sql
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/resources/audit/audit_mysql_innodb.sql b/syncope620/server/persistence-jpa/src/main/resources/audit/audit_mysql_innodb.sql
new file mode 100644
index 0000000..ff753fa
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/resources/audit/audit_mysql_innodb.sql
@@ -0,0 +1,24 @@
+-- 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.
+
+CREATE TABLE IF NOT EXISTS SYNCOPEAUDIT (
+  EVENT_DATE TIMESTAMP,
+  LOGGER_LEVEL VARCHAR(255) NOT NULL,
+  LOGGER VARCHAR(255) NOT NULL,
+  MESSAGE TEXT NOT NULL,
+  THROWABLE TEXT
+) ENGINE=InnoDB

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/resources/audit/audit_oracle.sql
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/resources/audit/audit_oracle.sql b/syncope620/server/persistence-jpa/src/main/resources/audit/audit_oracle.sql
new file mode 100644
index 0000000..e1b7d81
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/resources/audit/audit_oracle.sql
@@ -0,0 +1,38 @@
+-- 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.
+
+BEGIN
+    BEGIN
+         EXECUTE IMMEDIATE 'DROP TABLE SYNCOPEAUDIT';
+    EXCEPTION
+         WHEN OTHERS THEN
+                IF SQLCODE != -942 THEN
+                     RAISE;
+                END IF;
+    END;
+
+    EXECUTE IMMEDIATE '
+CREATE TABLE SYNCOPEAUDIT (
+  EVENT_DATE TIMESTAMP,
+  LOGGER_LEVEL VARCHAR(255) NOT NULL,
+  LOGGER VARCHAR(255) NOT NULL,
+  MESSAGE CLOB NOT NULL,
+  THROWABLE CLOB
+)
+';
+
+END;

http://git-wip-us.apache.org/repos/asf/syncope/blob/556d5186/syncope620/server/persistence-jpa/src/main/resources/audit/audit_sqlserver.sql
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/resources/audit/audit_sqlserver.sql b/syncope620/server/persistence-jpa/src/main/resources/audit/audit_sqlserver.sql
new file mode 100644
index 0000000..191428a
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/resources/audit/audit_sqlserver.sql
@@ -0,0 +1,28 @@
+-- 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.
+
+IF NOT EXISTS
+(SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[SYNCOPEAUDIT]') AND type in (N'U'))
+BEGIN
+CREATE TABLE SYNCOPEAUDIT (
+  EVENT_DATE DATETIME,
+  LOGGER_LEVEL VARCHAR(255) NOT NULL,
+  LOGGER VARCHAR(255) NOT NULL,
+  MESSAGE TEXT NOT NULL,
+  THROWABLE TEXT
+)
+END