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/12 17:32:01 UTC

[22/52] [abbrv] [partial] syncope git commit: [SYNCOPE-620] Unit tests all in

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainAttrValue.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainAttrValue.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainAttrValue.java
new file mode 100644
index 0000000..31a5bdc
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainAttrValue.java
@@ -0,0 +1,64 @@
+/*
+ * 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.role;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.validation.constraints.NotNull;
+import org.apache.syncope.server.persistence.api.entity.PlainAttr;
+import org.apache.syncope.server.persistence.api.entity.role.RPlainAttr;
+import org.apache.syncope.server.persistence.api.entity.role.RPlainAttrValue;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractPlainAttrValue;
+
+@Entity
+@Table(name = JPARPlainAttrValue.TABLE)
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class JPARPlainAttrValue extends AbstractPlainAttrValue implements RPlainAttrValue {
+
+    private static final long serialVersionUID = -766808291128424707L;
+
+    public static final String TABLE = "RPlainAttrValue";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    @NotNull
+    private JPARPlainAttr attribute;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public RPlainAttr getAttr() {
+        return attribute;
+    }
+
+    @Override
+    public void setAttr(final PlainAttr attr) {
+        checkType(attr, JPARPlainAttr.class);
+        this.attribute = (JPARPlainAttr) attr;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainSchema.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainSchema.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainSchema.java
new file mode 100644
index 0000000..4b417d2
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainSchema.java
@@ -0,0 +1,36 @@
+/*
+ * 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.role;
+
+import javax.persistence.Cacheable;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import org.apache.syncope.server.persistence.api.entity.role.RPlainSchema;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractPlainSchema;
+
+@Entity
+@Table(name = JPARPlainSchema.TABLE)
+@Cacheable
+public class JPARPlainSchema extends AbstractPlainSchema implements RPlainSchema {
+
+    private static final long serialVersionUID = -7417234690221851342L;
+
+    public static final String TABLE = "RPlainSchema";
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirAttr.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirAttr.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirAttr.java
new file mode 100644
index 0000000..1ea1d49
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirAttr.java
@@ -0,0 +1,82 @@
+/*
+ * 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.role;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import org.apache.syncope.server.persistence.api.entity.Attributable;
+import org.apache.syncope.server.persistence.api.entity.VirSchema;
+import org.apache.syncope.server.persistence.api.entity.role.RVirAttr;
+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.AbstractVirAttr;
+
+@Entity
+@Table(name = JPARVirAttr.TABLE)
+public class JPARVirAttr extends AbstractVirAttr implements RVirAttr {
+
+    private static final long serialVersionUID = -1747430556914428649L;
+
+    public static final String TABLE = "RVirAttr";
+
+    @ManyToOne
+    private JPARole owner;
+
+    @Column(nullable = false)
+    @OneToOne(cascade = CascadeType.MERGE)
+    private JPARVirAttrTemplate template;
+
+    @Override
+    public Role getOwner() {
+        return owner;
+    }
+
+    @Override
+    public void setOwner(final Attributable<?, ?, ?> owner) {
+        checkType(owner, JPARole.class);
+        this.owner = (JPARole) owner;
+    }
+
+    @Override
+    public RVirAttrTemplate getTemplate() {
+        return template;
+    }
+
+    @Override
+    public void setTemplate(final RVirAttrTemplate template) {
+        checkType(template, JPARVirAttrTemplate.class);
+        this.template = (JPARVirAttrTemplate) template;
+    }
+
+    @Override
+    public RVirSchema getSchema() {
+        return template == null ? null : template.getSchema();
+    }
+
+    @Override
+    public void setSchema(final VirSchema schema) {
+        LOG.warn("This is role attribute, set template to select schema");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/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
new file mode 100644
index 0000000..1de733a
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirAttrTemplate.java
@@ -0,0 +1,66 @@
+/*
+ * 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.role;
+
+import javax.persistence.Entity;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+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;
+
+@Entity
+@Table(name = JPARVirAttrTemplate.TABLE)
+public class JPARVirAttrTemplate extends AbstractAttrTemplate<RVirSchema> implements RVirAttrTemplate {
+
+    private static final long serialVersionUID = 4896495904794493479L;
+
+    public static final String TABLE = "RVirAttrTemplate";
+
+    @ManyToOne
+    private JPARole owner;
+
+    @ManyToOne
+    @JoinColumn(name = "schema_name")
+    private JPARVirSchema schema;
+
+    @Override
+    public RVirSchema getSchema() {
+        return schema;
+    }
+
+    @Override
+    public void setSchema(final RVirSchema schema) {
+        checkType(schema, JPARVirSchema.class);
+        this.schema = (JPARVirSchema) schema;
+    }
+
+    @Override
+    public Role getOwner() {
+        return owner;
+    }
+
+    @Override
+    public void setOwner(final Role role) {
+        checkType(role, JPARole.class);
+        this.owner = (JPARole) role;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirSchema.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirSchema.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirSchema.java
new file mode 100644
index 0000000..01ec433
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirSchema.java
@@ -0,0 +1,36 @@
+/*
+ * 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.role;
+
+import javax.persistence.Cacheable;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import org.apache.syncope.server.persistence.api.entity.role.RVirSchema;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractVirSchema;
+
+@Entity
+@Table(name = JPARVirSchema.TABLE)
+@Cacheable
+public class JPARVirSchema extends AbstractVirSchema implements RVirSchema {
+
+    private static final long serialVersionUID = -2595041749349652939L;
+
+    public static final String TABLE = "RVirSchema";
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARole.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARole.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARole.java
new file mode 100644
index 0000000..ea8695f
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARole.java
@@ -0,0 +1,593 @@
+/*
+ * 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.role;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.persistence.Basic;
+import javax.persistence.Cacheable;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import javax.validation.Valid;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import org.apache.syncope.server.persistence.api.entity.AccountPolicy;
+import org.apache.syncope.server.persistence.api.entity.AttrTemplate;
+import org.apache.syncope.server.persistence.api.entity.DerSchema;
+import org.apache.syncope.server.persistence.api.entity.Entitlement;
+import org.apache.syncope.server.persistence.api.entity.ExternalResource;
+import org.apache.syncope.server.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.server.persistence.api.entity.PlainSchema;
+import org.apache.syncope.server.persistence.api.entity.Schema;
+import org.apache.syncope.server.persistence.api.entity.VirSchema;
+import org.apache.syncope.server.persistence.api.entity.membership.MDerAttrTemplate;
+import org.apache.syncope.server.persistence.api.entity.membership.MPlainAttrTemplate;
+import org.apache.syncope.server.persistence.api.entity.membership.MVirAttrTemplate;
+import org.apache.syncope.server.persistence.api.entity.role.RDerAttr;
+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.RPlainAttr;
+import org.apache.syncope.server.persistence.api.entity.role.RPlainAttrTemplate;
+import org.apache.syncope.server.persistence.api.entity.role.RVirAttr;
+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.api.entity.user.User;
+import org.apache.syncope.server.persistence.jpa.validation.entity.RoleCheck;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractSubject;
+import org.apache.syncope.server.persistence.jpa.entity.JPAAccountPolicy;
+import org.apache.syncope.server.persistence.jpa.entity.JPAEntitlement;
+import org.apache.syncope.server.persistence.jpa.entity.JPAExternalResource;
+import org.apache.syncope.server.persistence.jpa.entity.JPAPasswordPolicy;
+import org.apache.syncope.server.persistence.jpa.entity.membership.JPAMPlainAttrTemplate;
+import org.apache.syncope.server.persistence.jpa.entity.membership.JPAMDerAttrTemplate;
+import org.apache.syncope.server.persistence.jpa.entity.membership.JPAMVirAttrTemplate;
+import org.apache.syncope.server.persistence.jpa.entity.user.JPAUser;
+
+@Entity
+@Table(name = JPARole.TABLE, uniqueConstraints =
+        @UniqueConstraint(columnNames = { "name", "parent_id" }))
+@Cacheable
+@RoleCheck
+public class JPARole extends AbstractSubject<RPlainAttr, RDerAttr, RVirAttr> implements Role {
+
+    private static final long serialVersionUID = -5281258853142421875L;
+
+    public static final String TABLE = "SyncopeRole";
+
+    @Id
+    private Long id;
+
+    @NotNull
+    private String name;
+
+    @ManyToOne(optional = true)
+    private JPARole parent;
+
+    @ManyToOne(optional = true)
+    private JPAUser userOwner;
+
+    @ManyToOne(optional = true)
+    private JPARole roleOwner;
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "role_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "entitlement_name"))
+    private Set<JPAEntitlement> entitlements;
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
+    @Valid
+    private List<JPARPlainAttrTemplate> rAttrTemplates;
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
+    @Valid
+    private List<JPARDerAttrTemplate> rDerAttrTemplates;
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
+    @Valid
+    private List<JPARVirAttrTemplate> rVirAttrTemplates;
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
+    @Valid
+    private List<JPAMPlainAttrTemplate> mAttrTemplates;
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
+    @Valid
+    private List<JPAMDerAttrTemplate> mDerAttrTemplates;
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
+    @Valid
+    private List<JPAMVirAttrTemplate> mVirAttrTemplates;
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
+    @Valid
+    private List<JPARPlainAttr> plainAttrs;
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
+    @Valid
+    private List<JPARDerAttr> derAttrs;
+
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
+    @Valid
+    private List<JPARVirAttr> virAttrs;
+
+    @Basic(optional = true)
+    @Min(0)
+    @Max(1)
+    private Integer inheritOwner;
+
+    @Basic(optional = true)
+    @Min(0)
+    @Max(1)
+    private Integer inheritTemplates;
+
+    @Basic(optional = true)
+    @Min(0)
+    @Max(1)
+    private Integer inheritPlainAttrs;
+
+    @Basic(optional = true)
+    @Min(0)
+    @Max(1)
+    private Integer inheritDerAttrs;
+
+    @Basic(optional = true)
+    @Min(0)
+    @Max(1)
+    private Integer inheritVirAttrs;
+
+    @Basic(optional = true)
+    @Min(0)
+    @Max(1)
+    private Integer inheritPasswordPolicy;
+
+    @Basic(optional = true)
+    @Min(0)
+    @Max(1)
+    private Integer inheritAccountPolicy;
+
+    @ManyToOne(fetch = FetchType.EAGER, optional = true)
+    private JPAPasswordPolicy passwordPolicy;
+
+    @ManyToOne(fetch = FetchType.EAGER, optional = true)
+    private JPAAccountPolicy accountPolicy;
+
+    /**
+     * Provisioning external resources.
+     */
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "role_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "resource_name"))
+    @Valid
+    private Set<JPAExternalResource> resources;
+
+    public JPARole() {
+        super();
+
+        entitlements = new HashSet<>();
+
+        rAttrTemplates = new ArrayList<>();
+        rDerAttrTemplates = new ArrayList<>();
+        rVirAttrTemplates = new ArrayList<>();
+        mAttrTemplates = new ArrayList<>();
+        mDerAttrTemplates = new ArrayList<>();
+        mVirAttrTemplates = new ArrayList<>();
+
+        plainAttrs = new ArrayList<>();
+        derAttrs = new ArrayList<>();
+        virAttrs = new ArrayList<>();
+
+        inheritOwner = getBooleanAsInteger(false);
+        inheritTemplates = getBooleanAsInteger(false);
+        inheritPlainAttrs = getBooleanAsInteger(false);
+        inheritDerAttrs = getBooleanAsInteger(false);
+        inheritVirAttrs = getBooleanAsInteger(false);
+        inheritPasswordPolicy = getBooleanAsInteger(false);
+        inheritAccountPolicy = getBooleanAsInteger(false);
+
+        resources = new HashSet<>();
+    }
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    protected Set<? extends ExternalResource> internalGetResources() {
+        return resources;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    @Override
+    public Role getParent() {
+        return parent;
+    }
+
+    @Override
+    public void setParent(final Role parent) {
+        checkType(parent, JPARole.class);
+        this.parent = (JPARole) parent;
+    }
+
+    @Override
+    public boolean isInheritOwner() {
+        return isBooleanAsInteger(inheritOwner);
+    }
+
+    @Override
+    public void setInheritOwner(final boolean inheritOwner) {
+        this.inheritOwner = getBooleanAsInteger(inheritOwner);
+    }
+
+    @Override
+    public User getUserOwner() {
+        return userOwner;
+    }
+
+    @Override
+    public void setUserOwner(final User userOwner) {
+        checkType(userOwner, JPAUser.class);
+        this.userOwner = (JPAUser) userOwner;
+    }
+
+    @Override
+    public JPARole getRoleOwner() {
+        return roleOwner;
+    }
+
+    @Override
+    public void setRoleOwner(final Role roleOwner) {
+        checkType(roleOwner, JPARole.class);
+        this.roleOwner = (JPARole) roleOwner;
+    }
+
+    @Override
+    public boolean addEntitlement(final Entitlement entitlement) {
+        checkType(entitlement, JPAEntitlement.class);
+        return entitlements.add((JPAEntitlement) entitlement);
+    }
+
+    @Override
+    public boolean removeEntitlement(final Entitlement entitlement) {
+        checkType(entitlement, JPAEntitlement.class);
+        return entitlements.remove((JPAEntitlement) entitlement);
+    }
+
+    @Override
+    public Set<? extends Entitlement> getEntitlements() {
+        return entitlements;
+    }
+
+    @Override
+    public boolean isInheritTemplates() {
+        return isBooleanAsInteger(inheritTemplates);
+    }
+
+    @Override
+    public void setInheritTemplates(final boolean inheritAttrTemplates) {
+        this.inheritTemplates = getBooleanAsInteger(inheritAttrTemplates);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <T extends AttrTemplate<K>, K extends Schema> List<T> getAttrTemplates(final Class<T> reference) {
+        List<T> result = new ArrayList<>();
+
+        if (RPlainAttrTemplate.class.isAssignableFrom(reference)) {
+            result = (List<T>) rAttrTemplates;
+        } else if (RDerAttrTemplate.class.isAssignableFrom(reference)) {
+            result = (List<T>) rDerAttrTemplates;
+        } else if (RVirAttrTemplate.class.isAssignableFrom(reference)) {
+            result = (List<T>) rVirAttrTemplates;
+        } else if (MPlainAttrTemplate.class.isAssignableFrom(reference)) {
+            result = (List<T>) mAttrTemplates;
+        } else if (MDerAttrTemplate.class.isAssignableFrom(reference)) {
+            result = (List<T>) mDerAttrTemplates;
+        } else if (MVirAttrTemplate.class.isAssignableFrom(reference)) {
+            result = (List<T>) mVirAttrTemplates;
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends AttrTemplate<K>, K extends Schema> T getAttrTemplate(
+            final Class<T> reference, final String schemaName) {
+
+        T result = null;
+
+        for (T template : findInheritedTemplates(reference)) {
+            if (schemaName.equals(template.getSchema().getKey())) {
+                result = template;
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends AttrTemplate<K>, K extends Schema> List<K> getAttrTemplateSchemas(final Class<T> reference) {
+        final List<K> result = new ArrayList<>();
+
+        for (T template : findInheritedTemplates(reference)) {
+            result.add(template.getSchema());
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends AttrTemplate<K>, K extends Schema> List<T> findInheritedTemplates(final Class<T> reference) {
+        final List<T> result = new ArrayList<>(getAttrTemplates(reference));
+
+        if (isInheritTemplates() && getParent() != null) {
+            result.addAll(getParent().findInheritedTemplates(reference));
+        }
+
+        return result;
+    }
+
+    @Override
+    public boolean addPlainAttr(final RPlainAttr attr) {
+        checkType(attr, JPARPlainAttr.class);
+        return plainAttrs.add((JPARPlainAttr) attr);
+    }
+
+    @Override
+    public boolean removePlainAttr(final RPlainAttr attr) {
+        checkType(attr, JPARPlainAttr.class);
+        return plainAttrs.remove((JPARPlainAttr) attr);
+    }
+
+    @Override
+    public List<? extends RPlainAttr> getPlainAttrs() {
+        return plainAttrs;
+    }
+
+    @Override
+    public boolean addDerAttr(final RDerAttr attr) {
+        checkType(attr, JPARDerAttr.class);
+        return derAttrs.add((JPARDerAttr) attr);
+    }
+
+    @Override
+    public boolean removeDerAttr(final RDerAttr attr) {
+        checkType(attr, JPARDerAttr.class);
+        return derAttrs.remove((JPARDerAttr) attr);
+    }
+
+    @Override
+    public List<? extends RDerAttr> getDerAttrs() {
+        return derAttrs;
+    }
+
+    @Override
+    public boolean addVirAttr(final RVirAttr attr) {
+        checkType(attr, JPARVirAttr.class);
+        return virAttrs.add((JPARVirAttr) attr);
+    }
+
+    @Override
+    public boolean removeVirAttr(final RVirAttr attr) {
+        checkType(attr, JPARVirAttr.class);
+        return virAttrs.remove((JPARVirAttr) attr);
+    }
+
+    @Override
+    public List<? extends RVirAttr> getVirAttrs() {
+        return virAttrs;
+    }
+
+    @Override
+    public boolean isInheritPlainAttrs() {
+        return isBooleanAsInteger(inheritPlainAttrs);
+    }
+
+    @Override
+    public void setInheritPlainAttrs(final boolean inheritPlainAttrs) {
+        this.inheritPlainAttrs = getBooleanAsInteger(inheritPlainAttrs);
+    }
+
+    /**
+     * Get all inherited attributes from the ancestors.
+     *
+     * @return a list of inherited and only inherited attributes.
+     */
+    @Override
+    public List<? extends RPlainAttr> findLastInheritedAncestorPlainAttrs() {
+        final Map<JPARPlainSchema, RPlainAttr> result = new HashMap<>();
+
+        if (!isInheritPlainAttrs()) {
+            return plainAttrs;
+        }
+        if (isInheritPlainAttrs() && getParent() != null) {
+            final Map<PlainSchema, RPlainAttr> attrMap = getPlainAttrMap();
+
+            // Add inherit attributes
+            for (RPlainAttr attr : getParent().findLastInheritedAncestorPlainAttrs()) {
+                if (attrMap.containsKey(attr.getSchema())) {
+                    result.remove((JPARPlainSchema) attr.getSchema());
+                }
+                result.put((JPARPlainSchema) attr.getSchema(), attr);
+            }
+        }
+        return new ArrayList<>(result.values());
+    }
+
+    @Override
+    public boolean isInheritDerAttrs() {
+        return isBooleanAsInteger(inheritDerAttrs);
+    }
+
+    @Override
+    public void setInheritDerAttrs(final boolean inheritDerAttrs) {
+        this.inheritDerAttrs = getBooleanAsInteger(inheritDerAttrs);
+
+    }
+
+    /**
+     * Get all inherited derived attributes from the ancestors.
+     *
+     * @return a list of inherited and only inherited attributes.
+     */
+    @Override
+    public List<? extends RDerAttr> findLastInheritedAncestorDerAttrs() {
+        final Map<RDerSchema, RDerAttr> result = new HashMap<>();
+
+        if (!isInheritDerAttrs()) {
+            return derAttrs;
+        }
+        if (isInheritDerAttrs() && getParent() != null) {
+            Map<DerSchema, RDerAttr> derAttrMap = getDerAttrMap();
+
+            // Add inherit derived attributes
+            for (RDerAttr attr : getParent().findLastInheritedAncestorDerAttrs()) {
+                if (derAttrMap.containsKey(attr.getSchema())) {
+                    result.remove(attr.getSchema());
+                }
+                result.put(attr.getSchema(), attr);
+            }
+        }
+        return new ArrayList<>(result.values());
+    }
+
+    @Override
+    public boolean isInheritVirAttrs() {
+        return isBooleanAsInteger(inheritVirAttrs);
+    }
+
+    @Override
+    public void setInheritVirAttrs(final boolean inheritVirAttrs) {
+        this.inheritVirAttrs = getBooleanAsInteger(inheritVirAttrs);
+
+    }
+
+    /**
+     * Get all inherited virtual attributes from the ancestors.
+     *
+     * @return a list of inherited and only inherited attributes.
+     */
+    @Override
+    public List<? extends RVirAttr> findLastInheritedAncestorVirAttrs() {
+        final Map<RVirSchema, RVirAttr> result = new HashMap<>();
+
+        if (!isInheritVirAttrs()) {
+            return virAttrs;
+        }
+
+        if (isInheritVirAttrs() && getParent() != null) {
+            Map<VirSchema, RVirAttr> virAttrMap = getVirAttrMap();
+
+            // Add inherit virtual attributes
+            for (RVirAttr attr : getParent().findLastInheritedAncestorVirAttrs()) {
+                if (virAttrMap.containsKey(attr.getSchema())) {
+                    result.remove(attr.getSchema());
+                }
+                result.put(attr.getSchema(), attr);
+            }
+        }
+        return new ArrayList<>(result.values());
+    }
+
+    /**
+     * Get first valid password policy.
+     *
+     * @return parent password policy if isInheritPasswordPolicy is 'true' and parent is not null, local password policy
+     * otherwise
+     */
+    @Override
+    public PasswordPolicy getPasswordPolicy() {
+        return isInheritPasswordPolicy() && getParent() != null
+                ? getParent().getPasswordPolicy()
+                : passwordPolicy;
+    }
+
+    @Override
+    public void setPasswordPolicy(final PasswordPolicy passwordPolicy) {
+        checkType(passwordPolicy, JPAPasswordPolicy.class);
+        this.passwordPolicy = (JPAPasswordPolicy) passwordPolicy;
+    }
+
+    @Override
+    public boolean isInheritPasswordPolicy() {
+        return isBooleanAsInteger(inheritPasswordPolicy);
+    }
+
+    @Override
+    public void setInheritPasswordPolicy(final boolean inheritPasswordPolicy) {
+        this.inheritPasswordPolicy = getBooleanAsInteger(inheritPasswordPolicy);
+    }
+
+    /**
+     * Get first valid account policy.
+     *
+     * @return parent account policy if isInheritAccountPolicy is 'true' and parent is not null, local account policy
+     * otherwise.
+     */
+    @Override
+    public AccountPolicy getAccountPolicy() {
+        return isInheritAccountPolicy() && getParent() != null
+                ? getParent().getAccountPolicy()
+                : accountPolicy;
+    }
+
+    @Override
+    public void setAccountPolicy(final AccountPolicy accountPolicy) {
+        checkType(accountPolicy, JPAAccountPolicy.class);
+        this.accountPolicy = (JPAAccountPolicy) accountPolicy;
+    }
+
+    @Override
+    public boolean isInheritAccountPolicy() {
+        return isBooleanAsInteger(inheritAccountPolicy);
+    }
+
+    @Override
+    public void setInheritAccountPolicy(boolean inheritAccountPolicy) {
+        this.inheritAccountPolicy = getBooleanAsInteger(inheritAccountPolicy);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/AbstractProvisioningTask.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/AbstractProvisioningTask.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/AbstractProvisioningTask.java
new file mode 100644
index 0000000..8604a5f
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/AbstractProvisioningTask.java
@@ -0,0 +1,168 @@
+/*
+ * 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.task;
+
+import javax.persistence.Basic;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.ManyToOne;
+import javax.persistence.MappedSuperclass;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import org.apache.syncope.common.lib.types.MatchingRule;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.lib.types.UnmatchingRule;
+import org.apache.syncope.server.persistence.api.entity.ExternalResource;
+import org.apache.syncope.server.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.server.persistence.jpa.validation.entity.ProvisioningTaskCheck;
+import org.apache.syncope.server.persistence.jpa.entity.JPAExternalResource;
+
+@MappedSuperclass
+@ProvisioningTaskCheck
+public abstract class AbstractProvisioningTask extends JPASchedTask implements ProvisioningTask {
+
+    private static final long serialVersionUID = -4141057723006682562L;
+
+    /**
+     * ExternalResource to which the sync happens.
+     */
+    @ManyToOne
+    private JPAExternalResource resource;
+
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer performCreate;
+
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer performUpdate;
+
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer performDelete;
+
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer syncStatus;
+
+    /**
+     * @see UnmatchingRule
+     */
+    @NotNull
+    @Enumerated(EnumType.STRING)
+    protected UnmatchingRule unmatchingRule;
+
+    /**
+     * @see MatchingRule
+     */
+    @NotNull
+    @Enumerated(EnumType.STRING)
+    protected MatchingRule matchingRule;
+
+    public AbstractProvisioningTask(final TaskType type, final String jobClassName) {
+        super();
+
+        this.type = type;
+        super.setJobClassName(jobClassName);
+    }
+
+    @Override
+    public void setJobClassName(final String jobClassName) {
+        // fixed to SyncJob, cannot be changed
+    }
+
+    @Override
+    public ExternalResource getResource() {
+        return resource;
+    }
+
+    @Override
+    public void setResource(final ExternalResource resource) {
+        checkType(resource, JPAExternalResource.class);
+        this.resource = (JPAExternalResource) resource;
+    }
+
+    @Override
+    public boolean isPerformCreate() {
+        return isBooleanAsInteger(performCreate);
+    }
+
+    @Override
+
+    public void setPerformCreate(final boolean performCreate) {
+        this.performCreate = getBooleanAsInteger(performCreate);
+    }
+
+    @Override
+
+    public boolean isPerformUpdate() {
+        return isBooleanAsInteger(performUpdate);
+    }
+
+    @Override
+
+    public void setPerformUpdate(final boolean performUpdate) {
+        this.performUpdate = getBooleanAsInteger(performUpdate);
+    }
+
+    @Override
+    public boolean isPerformDelete() {
+        return isBooleanAsInteger(performDelete);
+    }
+
+    @Override
+    public void setPerformDelete(boolean performDelete) {
+        this.performDelete = getBooleanAsInteger(performDelete);
+    }
+
+    @Override
+    public boolean isSyncStatus() {
+        return isBooleanAsInteger(syncStatus);
+    }
+
+    @Override
+    public void setSyncStatus(final boolean syncStatus) {
+        this.syncStatus = getBooleanAsInteger(syncStatus);
+    }
+
+    @Override
+    public UnmatchingRule getUnmatchingRule() {
+        return this.unmatchingRule;
+    }
+
+    @Override
+    public void setUnmatchingRule(final UnmatchingRule unmatchigRule) {
+        this.unmatchingRule = unmatchigRule;
+    }
+
+    @Override
+    public MatchingRule getMatchingRule() {
+        return this.matchingRule;
+    }
+
+    @Override
+    public void setMatchingRule(final MatchingRule matchigRule) {
+        this.matchingRule = matchigRule;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPANotificationTask.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPANotificationTask.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPANotificationTask.java
new file mode 100644
index 0000000..d46cd40
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPANotificationTask.java
@@ -0,0 +1,160 @@
+/*
+ * 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.task;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.persistence.Basic;
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.ElementCollection;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.Lob;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotNull;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.server.persistence.api.entity.task.NotificationTask;
+
+@Entity
+@DiscriminatorValue("NotificationTask")
+public class JPANotificationTask extends JPATask implements NotificationTask {
+
+    private static final long serialVersionUID = 95731573485279180L;
+
+    @ElementCollection(fetch = FetchType.EAGER)
+    @Column(name = "address")
+    @CollectionTable(name = "NotificationTask_recipients",
+            joinColumns =
+            @JoinColumn(name = "NotificationTask_id", referencedColumnName = "id"))
+    private Set<String> recipients;
+
+    @NotNull
+    private String sender;
+
+    @NotNull
+    private String subject;
+
+    @NotNull
+    @Lob
+    private String textBody;
+
+    @NotNull
+    @Lob
+    private String htmlBody;
+
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer executed;
+
+    @Enumerated(EnumType.STRING)
+    @NotNull
+    private TraceLevel traceLevel;
+
+    public JPANotificationTask() {
+        super();
+
+        type = TaskType.NOTIFICATION;
+        recipients = new HashSet<>();
+        executed = getBooleanAsInteger(false);
+    }
+
+    @Override
+    public Set<String> getRecipients() {
+        return recipients;
+    }
+
+    @Override
+    public boolean addRecipient(final String recipient) {
+        return recipients.add(recipient);
+    }
+
+    @Override
+    public boolean removeRecipient(final String recipient) {
+        return recipients.remove(recipient);
+    }
+
+    @Override
+    public String getSender() {
+        return sender;
+    }
+
+    @Override
+    public void setSender(final String sender) {
+        this.sender = sender;
+    }
+
+    @Override
+    public String getSubject() {
+        return subject;
+    }
+
+    @Override
+    public void setSubject(final String subject) {
+        this.subject = subject;
+    }
+
+    @Override
+    public String getTextBody() {
+        return textBody;
+    }
+
+    @Override
+    public void setTextBody(final String textBody) {
+        this.textBody = textBody;
+    }
+
+    @Override
+    public String getHtmlBody() {
+        return htmlBody;
+    }
+
+    @Override
+    public void setHtmlBody(final String htmlBody) {
+        this.htmlBody = htmlBody;
+    }
+
+    @Override
+    public boolean isExecuted() {
+        return isBooleanAsInteger(executed);
+    }
+
+    @Override
+    public void setExecuted(boolean executed) {
+        this.executed = getBooleanAsInteger(executed);
+    }
+
+    @Override
+    public TraceLevel getTraceLevel() {
+        return traceLevel;
+    }
+
+    @Override
+    public void setTraceLevel(final TraceLevel traceLevel) {
+        this.traceLevel = traceLevel;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPAPropagationTask.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPAPropagationTask.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPAPropagationTask.java
new file mode 100644
index 0000000..1c7cc73
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPAPropagationTask.java
@@ -0,0 +1,195 @@
+/*
+ * 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.task;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Lob;
+import javax.persistence.ManyToOne;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.PropagationMode;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.server.persistence.api.entity.ExternalResource;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.server.persistence.jpa.validation.entity.PropagationTaskCheck;
+import org.apache.syncope.server.persistence.jpa.entity.JPAExternalResource;
+import org.apache.syncope.server.misc.serialization.POJOHelper;
+import org.identityconnectors.framework.common.objects.Attribute;
+
+/**
+ * Encapsulate all information about a propagation task.
+ */
+@Entity
+@DiscriminatorValue("PropagationTask")
+@PropagationTaskCheck
+public class JPAPropagationTask extends JPATask implements PropagationTask {
+
+    private static final long serialVersionUID = 7086054884614511210L;
+
+    /**
+     * @see PropagationMode
+     */
+    @Enumerated(EnumType.STRING)
+    private PropagationMode propagationMode;
+
+    /**
+     * @see ResourceOperation
+     */
+    @Enumerated(EnumType.STRING)
+    private ResourceOperation propagationOperation;
+
+    /**
+     * The accountId on the external resource.
+     */
+    private String accountId;
+
+    /**
+     * The (optional) former accountId on the external resource.
+     */
+    private String oldAccountId;
+
+    /**
+     * Attributes to be propagated.
+     */
+    @Lob
+    private String xmlAttributes;
+
+    private String objectClassName;
+
+    @Enumerated(EnumType.STRING)
+    private AttributableType subjectType;
+
+    private Long subjectId;
+
+    public JPAPropagationTask() {
+        super();
+        type = TaskType.PROPAGATION;
+    }
+
+    /**
+     * ExternalResource to which the propagation happens.
+     */
+    @ManyToOne
+    private JPAExternalResource resource;
+
+    @Override
+    public String getAccountId() {
+        return accountId;
+    }
+
+    @Override
+    public void setAccountId(final String accountId) {
+        this.accountId = accountId;
+    }
+
+    @Override
+    public String getOldAccountId() {
+        return oldAccountId;
+    }
+
+    @Override
+    public void setOldAccountId(final String oldAccountId) {
+        this.oldAccountId = oldAccountId;
+    }
+
+    @Override
+    public Set<Attribute> getAttributes() {
+        return StringUtils.isBlank(xmlAttributes)
+                ? Collections.<Attribute>emptySet()
+                : new HashSet<>(Arrays.asList(POJOHelper.deserialize(xmlAttributes, Attribute[].class)));
+    }
+
+    @Override
+    public void setAttributes(final Set<Attribute> attributes) {
+        xmlAttributes = POJOHelper.serialize(attributes);
+    }
+
+    @Override
+
+    public PropagationMode getPropagationMode() {
+        return propagationMode;
+    }
+
+    @Override
+
+    public void setPropagationMode(final PropagationMode propagationMode) {
+        this.propagationMode = propagationMode;
+    }
+
+    @Override
+
+    public ResourceOperation getPropagationOperation() {
+        return propagationOperation;
+    }
+
+    @Override
+
+    public void setPropagationOperation(final ResourceOperation propagationOperation) {
+        this.propagationOperation = propagationOperation;
+    }
+
+    @Override
+    public ExternalResource getResource() {
+        return resource;
+    }
+
+    @Override
+    public void setResource(final ExternalResource resource) {
+        checkType(resource, JPAExternalResource.class);
+        this.resource = (JPAExternalResource) resource;
+    }
+
+    @Override
+    public String getObjectClassName() {
+        return objectClassName;
+    }
+
+    @Override
+    public void setObjectClassName(final String objectClassName) {
+        this.objectClassName = objectClassName;
+    }
+
+    @Override
+    public AttributableType getSubjectType() {
+        return subjectType;
+    }
+
+    @Override
+    public void setSubjectType(final AttributableType subjectType) {
+        this.subjectType = subjectType;
+    }
+
+    @Override
+    public Long getSubjectKey() {
+        return subjectId;
+    }
+
+    @Override
+    public void setSubjectKey(final Long subjectKey) {
+        this.subjectId = subjectKey;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPAPushTask.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPAPushTask.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPAPushTask.java
new file mode 100644
index 0000000..645a604
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPAPushTask.java
@@ -0,0 +1,82 @@
+/*
+ * 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.task;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.ElementCollection;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.server.persistence.api.entity.task.PushTask;
+import org.apache.syncope.server.provisioning.api.job.PushJob;
+
+@Entity
+@DiscriminatorValue("PushTask")
+public class JPAPushTask extends AbstractProvisioningTask implements PushTask {
+
+    private static final long serialVersionUID = -4141057723006682564L;
+
+    @ElementCollection(fetch = FetchType.EAGER)
+    @Column(name = "actionClassName")
+    @CollectionTable(name = "PushTask_actionsClassNames",
+            joinColumns =
+            @JoinColumn(name = "PushTask_id", referencedColumnName = "id"))
+    private List<String> actionsClassNames = new ArrayList<>();
+
+    private String userFilter;
+
+    private String roleFilter;
+
+    /**
+     * Default constructor.
+     */
+    public JPAPushTask() {
+        super(TaskType.PUSH, PushJob.class.getName());
+    }
+
+    @Override
+    public List<String> getActionsClassNames() {
+        return actionsClassNames;
+    }
+
+    @Override
+    public String getUserFilter() {
+        return userFilter;
+    }
+
+    @Override
+    public void setUserFilter(final String filter) {
+        this.userFilter = filter;
+    }
+
+    @Override
+    public String getRoleFilter() {
+        return roleFilter;
+    }
+
+    @Override
+    public void setRoleFilter(final String roleFilter) {
+        this.roleFilter = roleFilter;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPASchedTask.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPASchedTask.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPASchedTask.java
new file mode 100644
index 0000000..064acb8
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPASchedTask.java
@@ -0,0 +1,89 @@
+/*
+ * 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.task;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+import javax.validation.constraints.NotNull;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.server.persistence.api.entity.task.SchedTask;
+import org.apache.syncope.server.persistence.jpa.validation.entity.SchedTaskCheck;
+
+@Entity
+@DiscriminatorValue("SchedTask")
+@SchedTaskCheck
+public class JPASchedTask extends JPATask implements SchedTask {
+
+    private static final long serialVersionUID = 7596236684832602180L;
+
+    protected String cronExpression;
+
+    @NotNull
+    protected String jobClassName;
+
+    @NotNull
+    protected String name;
+
+    protected String description;
+
+    public JPASchedTask() {
+        super();
+        this.type = TaskType.SCHEDULED;
+    }
+
+    @Override
+    public String getCronExpression() {
+        return cronExpression;
+    }
+
+    @Override
+    public void setCronExpression(final String cronExpression) {
+        this.cronExpression = cronExpression;
+    }
+
+    @Override
+    public String getJobClassName() {
+        return jobClassName;
+    }
+
+    @Override
+    public void setJobClassName(final String jobClassName) {
+        this.jobClassName = jobClassName;
+    }
+
+    @Override
+    public String getDescription() {
+        return description;
+    }
+
+    @Override
+    public void setDescription(final String description) {
+        this.description = description;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public void setName(final String name) {
+        this.name = name;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPASyncTask.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPASyncTask.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPASyncTask.java
new file mode 100644
index 0000000..2ca09e1
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPASyncTask.java
@@ -0,0 +1,110 @@
+/*
+ * 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.task;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Basic;
+import javax.persistence.CollectionTable;
+import javax.persistence.Column;
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.ElementCollection;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.Lob;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.server.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.server.provisioning.api.job.SyncJob;
+import org.apache.syncope.server.misc.serialization.POJOHelper;
+
+@Entity
+@DiscriminatorValue("SyncTask")
+public class JPASyncTask extends AbstractProvisioningTask implements SyncTask {
+
+    private static final long serialVersionUID = -4141057723006682563L;
+
+    @ElementCollection(fetch = FetchType.EAGER)
+    @Column(name = "actionClassName")
+    @CollectionTable(name = "SyncTask_actionsClassNames",
+            joinColumns =
+            @JoinColumn(name = "SyncTask_id", referencedColumnName = "id"))
+    private List<String> actionsClassNames = new ArrayList<>();
+
+    @Lob
+    private String userTemplate;
+
+    @Lob
+    private String roleTemplate;
+
+    @Basic
+    @Min(0)
+    @Max(1)
+    private Integer fullReconciliation;
+
+    /**
+     * Default constructor.
+     */
+    public JPASyncTask() {
+        super(TaskType.SYNCHRONIZATION, SyncJob.class.getName());
+    }
+
+    @Override
+    public List<String> getActionsClassNames() {
+        return actionsClassNames;
+    }
+
+    @Override
+    public UserTO getUserTemplate() {
+        return userTemplate == null
+                ? new UserTO()
+                : POJOHelper.deserialize(userTemplate, UserTO.class);
+    }
+
+    @Override
+    public void setUserTemplate(final UserTO userTemplate) {
+        this.userTemplate = POJOHelper.serialize(userTemplate);
+    }
+
+    @Override
+    public RoleTO getRoleTemplate() {
+        return userTemplate == null
+                ? new RoleTO()
+                : POJOHelper.deserialize(roleTemplate, RoleTO.class);
+    }
+
+    @Override
+    public void setRoleTemplate(final RoleTO roleTemplate) {
+        this.roleTemplate = POJOHelper.serialize(roleTemplate);
+    }
+
+    @Override
+    public boolean isFullReconciliation() {
+        return isBooleanAsInteger(fullReconciliation);
+    }
+
+    @Override
+    public void setFullReconciliation(final boolean fullReconciliation) {
+        this.fullReconciliation = getBooleanAsInteger(fullReconciliation);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATask.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATask.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATask.java
new file mode 100644
index 0000000..e4ad25a
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATask.java
@@ -0,0 +1,96 @@
+/*
+ * 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.task;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.DiscriminatorColumn;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Id;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.validation.constraints.NotNull;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.server.persistence.api.entity.task.Task;
+import org.apache.syncope.server.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractEntity;
+
+@Entity
+@Table(name = JPATask.TABLE)
+@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
+@DiscriminatorColumn(name = "DTYPE")
+public abstract class JPATask extends AbstractEntity<Long> implements Task {
+
+    private static final long serialVersionUID = 5837401178128177511L;
+
+    public static final String TABLE = "Task";
+
+    /**
+     * Id.
+     */
+    @Id
+    private Long id;
+
+    @NotNull
+    @Enumerated(EnumType.STRING)
+    protected TaskType type;
+
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "task")
+    private List<JPATaskExec> executions;
+
+    public JPATask() {
+        super();
+
+        executions = new ArrayList<>();
+    }
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public TaskType getType() {
+        return type;
+    }
+
+    @Override
+    public boolean addExec(final TaskExec exec) {
+        checkType(exec, JPATaskExec.class);
+        return exec != null && !executions.contains((JPATaskExec) exec) && executions.add((JPATaskExec) exec);
+    }
+
+    @Override
+    public boolean removeExec(final TaskExec exec) {
+        checkType(exec, JPATaskExec.class);
+        return exec != null && executions.remove((JPATaskExec) exec);
+    }
+
+    @Override
+    public List<? extends TaskExec> getExecs() {
+        return executions;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskExec.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskExec.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskExec.java
new file mode 100644
index 0000000..0f16943
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskExec.java
@@ -0,0 +1,82 @@
+/*
+ * 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.task;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.apache.syncope.server.persistence.api.entity.task.Task;
+import org.apache.syncope.server.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractExec;
+
+/**
+ * An execution (with result) of a Task.
+ *
+ * @see JPATask
+ */
+@Entity
+@Table(name = JPATaskExec.TABLE)
+public class JPATaskExec extends AbstractExec implements TaskExec {
+
+    private static final long serialVersionUID = 1909033231464074554L;
+
+    public static final String TABLE = "TaskExec";
+
+    /**
+     * Id.
+     */
+    @Id
+    private Long id;
+
+    /**
+     * The referred task.
+     */
+    @ManyToOne(optional = false)
+    private JPATask task;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public Task getTask() {
+        return task;
+    }
+
+    @Override
+    public void setTask(final Task task) {
+        checkType(task, JPATask.class);
+        this.task = (JPATask) task;
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder(getClass().getSimpleName()).append('{').
+                append("id=").append(id).append(", ").
+                append("startDate=").append(startDate).append(", ").
+                append("endDate=").append(endDate).append(", ").
+                append("task=").append(task).append(", ").
+                append("status=").append(status).append(", ").
+                append("message=").append(message).
+                append('}').
+                toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/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
new file mode 100644
index 0000000..4086018
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskUtil.java
@@ -0,0 +1,132 @@
+/*
+ * 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.task;
+
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.NotificationTaskTO;
+import org.apache.syncope.common.lib.to.PropagationTaskTO;
+import org.apache.syncope.common.lib.to.PushTaskTO;
+import org.apache.syncope.common.lib.to.SchedTaskTO;
+import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.server.persistence.api.entity.task.NotificationTask;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+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.persistence.api.entity.task.TaskUtil;
+
+@SuppressWarnings("unchecked")
+public final class JPATaskUtil implements TaskUtil {
+
+    private final TaskType type;
+
+    protected JPATaskUtil(final TaskType type) {
+        this.type = type;
+    }
+
+    @Override
+    public TaskType getType() {
+        return type;
+    }
+
+    @Override
+    public <T extends Task> Class<T> taskClass() {
+        Class<T> result = null;
+
+        switch (type) {
+            case PROPAGATION:
+                result = (Class<T>) PropagationTask.class;
+                break;
+
+            case SCHEDULED:
+                result = (Class<T>) SchedTask.class;
+                break;
+
+            case SYNCHRONIZATION:
+                result = (Class<T>) SyncTask.class;
+                break;
+
+            case PUSH:
+                result = (Class<T>) PushTask.class;
+                break;
+
+            case NOTIFICATION:
+                result = (Class<T>) NotificationTask.class;
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+    @Override
+    public <T extends Task> T newTask() {
+        final Class<T> taskClass = taskClass();
+        try {
+            return taskClass == null ? null : taskClass.newInstance();
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    @Override
+    public <T extends AbstractTaskTO> Class<T> taskTOClass() {
+        Class<T> result = null;
+
+        switch (type) {
+            case PROPAGATION:
+                result = (Class<T>) PropagationTaskTO.class;
+                break;
+
+            case SCHEDULED:
+                result = (Class<T>) SchedTaskTO.class;
+                break;
+
+            case SYNCHRONIZATION:
+                result = (Class<T>) SyncTaskTO.class;
+                break;
+
+            case PUSH:
+                result = (Class<T>) PushTaskTO.class;
+                break;
+
+            case NOTIFICATION:
+                result = (Class<T>) NotificationTaskTO.class;
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends AbstractTaskTO> T newTaskTO() {
+        final Class<T> taskClass = taskTOClass();
+        try {
+            return taskClass == null ? null : taskClass.newInstance();
+        } catch (Exception e) {
+            return null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskUtilFactory.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskUtilFactory.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskUtilFactory.java
new file mode 100644
index 0000000..08c06bc
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskUtilFactory.java
@@ -0,0 +1,91 @@
+/*
+ * 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.task;
+
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.NotificationTaskTO;
+import org.apache.syncope.common.lib.to.PropagationTaskTO;
+import org.apache.syncope.common.lib.to.PushTaskTO;
+import org.apache.syncope.common.lib.to.SchedTaskTO;
+import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.server.persistence.api.entity.task.NotificationTask;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+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.persistence.api.entity.task.TaskUtil;
+import org.apache.syncope.server.persistence.api.entity.task.TaskUtilFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+public class JPATaskUtilFactory implements TaskUtilFactory {
+
+    @Override
+    public TaskUtil getInstance(final TaskType type) {
+        return new JPATaskUtil(type);
+    }
+
+    @Override
+    public TaskUtil getInstance(final Task task) {
+        TaskType type;
+        if (task instanceof SyncTask) {
+            type = TaskType.SYNCHRONIZATION;
+        } else if (task instanceof PushTask) {
+            type = TaskType.PUSH;
+        } else if (task instanceof SchedTask) {
+            type = TaskType.SCHEDULED;
+        } else if (task instanceof PropagationTask) {
+            type = TaskType.PROPAGATION;
+        } else if (task instanceof NotificationTask) {
+            type = TaskType.NOTIFICATION;
+        } else {
+            throw new IllegalArgumentException("Invalid task: " + task);
+        }
+
+        return getInstance(type);
+    }
+
+    @Override
+    public TaskUtil getInstance(final Class<? extends AbstractTaskTO> taskClass) {
+        TaskType type;
+        if (taskClass == PropagationTaskTO.class) {
+            type = TaskType.PROPAGATION;
+        } else if (taskClass == NotificationTaskTO.class) {
+            type = TaskType.NOTIFICATION;
+        } else if (taskClass == SchedTaskTO.class) {
+            type = TaskType.SCHEDULED;
+        } else if (taskClass == SyncTaskTO.class) {
+            type = TaskType.SYNCHRONIZATION;
+        } else if (taskClass == PushTaskTO.class) {
+            type = TaskType.PUSH;
+        } else {
+            throw new IllegalArgumentException("Invalid TaskTO class: " + taskClass.getName());
+        }
+
+        return getInstance(type);
+    }
+
+    @Override
+    public TaskUtil getInstance(final AbstractTaskTO taskTO) {
+        return getInstance(taskTO.getClass());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUDerAttr.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUDerAttr.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUDerAttr.java
new file mode 100644
index 0000000..6ef0713
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUDerAttr.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.server.persistence.jpa.entity.user;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.apache.syncope.server.persistence.api.entity.Attributable;
+import org.apache.syncope.server.persistence.api.entity.DerSchema;
+import org.apache.syncope.server.persistence.api.entity.user.UDerAttr;
+import org.apache.syncope.server.persistence.api.entity.user.UDerSchema;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractDerAttr;
+
+@Entity
+@Table(name = JPAUDerAttr.TABLE)
+public class JPAUDerAttr extends AbstractDerAttr implements UDerAttr {
+
+    private static final long serialVersionUID = 4723044452807292060L;
+
+    public static final String TABLE = "UDerAttr";
+
+    @ManyToOne
+    private JPAUser owner;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    private JPAUDerSchema derSchema;
+
+    @Override
+    public User getOwner() {
+        return owner;
+    }
+
+    @Override
+    public void setOwner(final Attributable<?, ?, ?> owner) {
+        checkType(owner, JPAUser.class);
+        this.owner = (JPAUser) owner;
+    }
+
+    @Override
+    public UDerSchema getSchema() {
+        return derSchema;
+    }
+
+    @Override
+    public void setSchema(final DerSchema derSchema) {
+        checkType(derSchema, JPAUDerSchema.class);
+        this.derSchema = (JPAUDerSchema) derSchema;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUDerSchema.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUDerSchema.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUDerSchema.java
new file mode 100644
index 0000000..284996e
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUDerSchema.java
@@ -0,0 +1,34 @@
+/*
+ * 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.user;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import org.apache.syncope.server.persistence.api.entity.user.UDerSchema;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractDerSchema;
+
+@Entity
+@Table(name = JPAUDerSchema.TABLE)
+public class JPAUDerSchema extends AbstractDerSchema implements UDerSchema {
+
+    private static final long serialVersionUID = 6244467775394201229L;
+
+    public static final String TABLE = "UDerSchema";
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUMapping.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUMapping.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUMapping.java
new file mode 100644
index 0000000..046e8d6
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/user/JPAUMapping.java
@@ -0,0 +1,125 @@
+/*
+ * 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.user;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import org.apache.syncope.server.persistence.api.entity.ExternalResource;
+import org.apache.syncope.server.persistence.api.entity.MappingItem;
+import org.apache.syncope.server.persistence.api.entity.user.UMapping;
+import org.apache.syncope.server.persistence.api.entity.user.UMappingItem;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractMapping;
+import org.apache.syncope.server.persistence.jpa.entity.JPAExternalResource;
+import org.identityconnectors.framework.common.objects.OperationalAttributes;
+
+@Entity
+@Table(name = JPAUMapping.TABLE)
+public class JPAUMapping extends AbstractMapping<UMappingItem> implements UMapping {
+
+    private static final long serialVersionUID = 4285801404504561073L;
+
+    public static final String TABLE = "UMapping";
+
+    @Id
+    private Long id;
+
+    /**
+     * Resource owning this mapping.
+     */
+    @OneToOne
+    private JPAExternalResource resource;
+
+    /**
+     * Attribute mappings.
+     */
+    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "mapping")
+    private List<JPAUMappingItem> items;
+
+    public JPAUMapping() {
+        super();
+
+        items = new ArrayList<>();
+    }
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public ExternalResource getResource() {
+        return resource;
+    }
+
+    @Override
+    public void setResource(final ExternalResource resource) {
+        checkType(resource, JPAExternalResource.class);
+        this.resource = (JPAExternalResource) resource;
+    }
+
+    @Override
+    public void setAccountIdItem(final UMappingItem item) {
+        checkType(item, JPAUMappingItem.class);
+        this.addAccountIdItem((JPAUMappingItem) item);
+    }
+
+    @Override
+    public UMappingItem getPasswordItem() {
+        UMappingItem passwordItem = null;
+        for (MappingItem item : getItems()) {
+            if (item.isPassword()) {
+                passwordItem = (JPAUMappingItem) item;
+            }
+        }
+        return passwordItem;
+    }
+
+    @Override
+    public boolean setPasswordItem(final UMappingItem passwordItem) {
+        checkType(passwordItem, JPAUMappingItem.class);
+
+        passwordItem.setExtAttrName(OperationalAttributes.PASSWORD_NAME);
+        passwordItem.setPassword(true);
+        return this.addItem((JPAUMappingItem) passwordItem);
+    }
+
+    @Override
+    public List<? extends UMappingItem> getItems() {
+        return items;
+    }
+
+    @Override
+    public boolean addItem(final UMappingItem item) {
+        checkType(item, JPAUMappingItem.class);
+        return items.contains((JPAUMappingItem) item) || items.add((JPAUMappingItem) item);
+    }
+
+    @Override
+    public boolean removeItem(final UMappingItem item) {
+        checkType(item, JPAUMappingItem.class);
+        return items.remove((JPAUMappingItem) item);
+    }
+}