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/02/12 10:14:37 UTC

[32/54] [abbrv] [partial] syncope git commit: [SYNCOPE-620] Renaming 'server' after 'core', to provide continuity with older releases (especially for archetype)

http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/AbstractProvisioningTask.java
new file mode 100644
index 0000000..9f837f7
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/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.core.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.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.core.persistence.jpa.validation.entity.ProvisioningTaskCheck;
+import org.apache.syncope.core.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/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPANotificationTask.java
new file mode 100644
index 0000000..e175245
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/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.core.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.core.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/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPropagationTask.java
new file mode 100644
index 0000000..e532f3c
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/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.core.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.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.persistence.jpa.validation.entity.PropagationTaskCheck;
+import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
+import org.apache.syncope.core.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/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPAPushTask.java
new file mode 100644
index 0000000..041e206
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/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.core.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.core.persistence.api.entity.task.PushTask;
+import org.apache.syncope.core.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/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASchedTask.java
new file mode 100644
index 0000000..5703380
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/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.core.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.core.persistence.api.entity.task.SchedTask;
+import org.apache.syncope.core.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/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPASyncTask.java
new file mode 100644
index 0000000..7d142b2
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/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.core.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.core.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.core.provisioning.api.job.SyncJob;
+import org.apache.syncope.core.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/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATask.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATask.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATask.java
new file mode 100644
index 0000000..f3c6069
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/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.core.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.core.persistence.api.entity.task.Task;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.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/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskExec.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskExec.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskExec.java
new file mode 100644
index 0000000..7a37dc8
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/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.core.persistence.jpa.entity.task;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.task.Task;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+import org.apache.syncope.core.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/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtil.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtil.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtil.java
new file mode 100644
index 0000000..c2f5e86
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtil.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.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.core.persistence.api.entity.task.NotificationTask;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.persistence.api.entity.task.PushTask;
+import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
+import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.core.persistence.api.entity.task.Task;
+import org.apache.syncope.core.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() {
+        T result = null;
+
+        switch (type) {
+            case PROPAGATION:
+                result = (T) new JPAPropagationTask();
+                break;
+
+            case SCHEDULED:
+                result = (T) new JPASchedTask();
+                break;
+
+            case SYNCHRONIZATION:
+                result = (T) new JPASyncTask();
+                break;
+
+            case PUSH:
+                result = (T) new JPAPushTask();
+                break;
+
+            case NOTIFICATION:
+                result = (T) new JPANotificationTask();
+                break;
+
+            default:
+        }
+
+        return result;
+    }
+
+    @Override
+    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;
+    }
+
+    @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/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtilFactory.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtilFactory.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/task/JPATaskUtilFactory.java
new file mode 100644
index 0000000..bdda208
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/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.core.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.core.persistence.api.entity.task.NotificationTask;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.persistence.api.entity.task.PushTask;
+import org.apache.syncope.core.persistence.api.entity.task.SchedTask;
+import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.core.persistence.api.entity.task.Task;
+import org.apache.syncope.core.persistence.api.entity.task.TaskUtil;
+import org.apache.syncope.core.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/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerAttr.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerAttr.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerAttr.java
new file mode 100644
index 0000000..b9cfb2c
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/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.core.persistence.jpa.entity.user;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.Attributable;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
+import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.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/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerSchema.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerSchema.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUDerSchema.java
new file mode 100644
index 0000000..eb9ae93
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/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.core.persistence.jpa.entity.user;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
+import org.apache.syncope.core.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/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMapping.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMapping.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMapping.java
new file mode 100644
index 0000000..86b349a
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/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.core.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.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.user.UMapping;
+import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractMapping;
+import org.apache.syncope.core.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);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMappingItem.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMappingItem.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMappingItem.java
new file mode 100644
index 0000000..14b94f0
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUMappingItem.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.user;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.Mapping;
+import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractMappingItem;
+
+@Entity
+@Table(name = JPAUMappingItem.TABLE)
+public class JPAUMappingItem extends AbstractMappingItem implements UMappingItem {
+
+    private static final long serialVersionUID = 2936446317887310833L;
+
+    public static final String TABLE = "UMappingItem";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    private JPAUMapping mapping;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public Mapping<UMappingItem> getMapping() {
+        return mapping;
+    }
+
+    @Override
+    public void setMapping(final Mapping<?> mapping) {
+        checkType(mapping, JPAUMapping.class);
+        this.mapping = (JPAUMapping) mapping;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
new file mode 100644
index 0000000..8c2e06a
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttr.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.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.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.validation.Valid;
+import org.apache.syncope.core.persistence.api.entity.Attributable;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr;
+
+@Entity
+@Table(name = JPAUPlainAttr.TABLE)
+public class JPAUPlainAttr extends AbstractPlainAttr implements UPlainAttr {
+
+    private static final long serialVersionUID = 6333601983691157406L;
+
+    public static final String TABLE = "UPlainAttr";
+
+    /**
+     * Auto-generated id for this table.
+     */
+    @Id
+    private Long id;
+
+    /**
+     * The owner of this attribute.
+     */
+    @ManyToOne(fetch = FetchType.EAGER)
+    private JPAUser owner;
+
+    /**
+     * The schema of this attribute.
+     */
+    @ManyToOne(fetch = FetchType.EAGER)
+    @JoinColumn(name = "schema_name")
+    private JPAUPlainSchema schema;
+
+    /**
+     * Values of this attribute (if schema is not UNIQUE).
+     */
+    @OneToMany(cascade = CascadeType.MERGE, orphanRemoval = true, mappedBy = "attribute")
+    @Valid
+    private List<JPAUPlainAttrValue> values;
+
+    /**
+     * Value of this attribute (if schema is UNIQUE).
+     */
+    @OneToOne(cascade = CascadeType.ALL, mappedBy = "attribute")
+    @Valid
+    private JPAUPlainAttrUniqueValue uniqueValue;
+
+    /**
+     * Default constructor.
+     */
+    public JPAUPlainAttr() {
+        super();
+        values = new ArrayList<>();
+    }
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public User getOwner() {
+        return owner;
+    }
+
+    @Override
+    public void setOwner(final Attributable<?, ?, ?> owner) {
+        checkType(owner, JPAUser.class);
+        this.owner = (JPAUser) owner;
+    }
+
+    @Override
+    public UPlainSchema getSchema() {
+        return schema;
+    }
+
+    @Override
+    public void setSchema(final PlainSchema schema) {
+        checkType(schema, JPAUPlainSchema.class);
+        this.schema = (JPAUPlainSchema) schema;
+    }
+
+    @Override
+    protected boolean addValue(final PlainAttrValue attrValue) {
+        checkType(attrValue, JPAUPlainAttrValue.class);
+        return values.add((JPAUPlainAttrValue) attrValue);
+    }
+
+    @Override
+    public boolean removeValue(final PlainAttrValue attrValue) {
+        checkType(attrValue, JPAUPlainAttrValue.class);
+        return values.remove((JPAUPlainAttrValue) attrValue);
+    }
+
+    @Override
+    public List<? extends UPlainAttrValue> getValues() {
+        return values;
+    }
+
+    @Override
+    public UPlainAttrUniqueValue getUniqueValue() {
+        return uniqueValue;
+    }
+
+    @Override
+    public void setUniqueValue(final PlainAttrUniqueValue uniqueValue) {
+        checkType(uniqueValue, JPAUPlainAttrUniqueValue.class);
+        this.uniqueValue = (JPAUPlainAttrUniqueValue) uniqueValue;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrUniqueValue.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrUniqueValue.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrUniqueValue.java
new file mode 100644
index 0000000..5c820fb
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrUniqueValue.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity.user;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
+
+@Entity
+@Table(name = JPAUPlainAttrUniqueValue.TABLE)
+public class JPAUPlainAttrUniqueValue extends AbstractPlainAttrValue implements UPlainAttrUniqueValue {
+
+    private static final long serialVersionUID = -64080804563305387L;
+
+    public static final String TABLE = "UPlainAttrUniqueValue";
+
+    @Id
+    private Long id;
+
+    @OneToOne(optional = false)
+    private JPAUPlainAttr attribute;
+
+    @ManyToOne(optional = false)
+    @JoinColumn(name = "schema_name")
+    private JPAUPlainSchema schema;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public UPlainAttr getAttr() {
+        return attribute;
+    }
+
+    @Override
+    public void setAttr(final PlainAttr attr) {
+        checkType(attr, JPAUPlainAttr.class);
+        this.attribute = (JPAUPlainAttr) attr;
+    }
+
+    @Override
+    public UPlainSchema getSchema() {
+        return schema;
+    }
+
+    @Override
+    public void setSchema(final PlainSchema schema) {
+        checkType(schema, JPAUPlainSchema.class);
+        this.schema = (JPAUPlainSchema) schema;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrValue.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrValue.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrValue.java
new file mode 100644
index 0000000..73645b4
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainAttrValue.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.core.persistence.jpa.entity.user;
+
+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.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
+
+@Entity
+@Table(name = JPAUPlainAttrValue.TABLE)
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+public class JPAUPlainAttrValue extends AbstractPlainAttrValue implements UPlainAttrValue {
+
+    private static final long serialVersionUID = -6259576015647897446L;
+
+    public static final String TABLE = "UPlainAttrValue";
+
+    @Id
+    private Long id;
+
+    @ManyToOne
+    @NotNull
+    private JPAUPlainAttr attribute;
+
+    @Override
+    public Long getKey() {
+        return id;
+    }
+
+    @Override
+    public UPlainAttr getAttr() {
+        return attribute;
+    }
+
+    @Override
+    public void setAttr(final PlainAttr attr) {
+        checkType(attr, JPAUPlainAttr.class);
+        this.attribute = (JPAUPlainAttr) attr;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainSchema.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainSchema.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainSchema.java
new file mode 100644
index 0000000..c5b8dac
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUPlainSchema.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.core.persistence.jpa.entity.user;
+
+import javax.persistence.Cacheable;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainSchema;
+
+@Entity
+@Table(name = JPAUPlainSchema.TABLE)
+@Cacheable
+public class JPAUPlainSchema extends AbstractPlainSchema implements UPlainSchema {
+
+    public static final String TABLE = "UPlainSchema";
+
+    private static final long serialVersionUID = -7272127460142463237L;
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirAttr.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirAttr.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirAttr.java
new file mode 100644
index 0000000..c68280d
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirAttr.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.core.persistence.jpa.entity.user;
+
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.Attributable;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
+import org.apache.syncope.core.persistence.api.entity.user.UVirSchema;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractVirAttr;
+
+@Entity
+@Table(name = JPAUVirAttr.TABLE)
+public class JPAUVirAttr extends AbstractVirAttr implements UVirAttr {
+
+    private static final long serialVersionUID = 2943450934283989741L;
+
+    public static final String TABLE = "UVirAttr";
+
+    @ManyToOne
+    private JPAUser owner;
+
+    @ManyToOne(fetch = FetchType.EAGER)
+    private JPAUVirSchema virSchema;
+
+    @Override
+    public User getOwner() {
+        return owner;
+    }
+
+    @Override
+    public void setOwner(final Attributable<?, ?, ?> owner) {
+        checkType(owner, JPAUser.class);
+        this.owner = (JPAUser) owner;
+    }
+
+    @Override
+    public UVirSchema getSchema() {
+        return virSchema;
+    }
+
+    @Override
+    public void setSchema(final VirSchema virSchema) {
+        checkType(virSchema, JPAUVirSchema.class);
+        this.virSchema = (JPAUVirSchema) virSchema;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirSchema.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirSchema.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirSchema.java
new file mode 100644
index 0000000..307dd46
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/user/JPAUVirSchema.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.core.persistence.jpa.entity.user;
+
+import javax.persistence.Cacheable;
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import org.apache.syncope.core.persistence.api.entity.user.UVirSchema;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractVirSchema;
+
+@Entity
+@Table(name = JPAUVirSchema.TABLE)
+@Cacheable
+public class JPAUVirSchema extends AbstractVirSchema implements UVirSchema {
+
+    private static final long serialVersionUID = 1089308700791426201L;
+
+    public static final String TABLE = "UVirSchema";
+
+}