http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
index 46b51dc..8c6aaa7 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java
@@ -20,7 +20,6 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -30,39 +29,33 @@ import javax.persistence.TypedQuery;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
 import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.Entitlement;
-import org.apache.syncope.common.lib.types.SubjectType;
 import org.apache.syncope.core.persistence.api.dao.NotFoundException;
 import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.dao.UserDAO;
-import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.Subject;
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.Membership;
+import 
org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
 import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion;
-import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
-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.api.entity.user.UVirAttr;
 import org.apache.syncope.core.persistence.api.entity.user.User;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.security.UnauthorizedException;
 import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.Role;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.jpa.entity.JPADynGroupMembership;
-import org.apache.syncope.core.persistence.jpa.entity.JPADynRoleMembership;
+import org.apache.syncope.core.persistence.api.entity.user.UMembership;
+import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
+import 
org.apache.syncope.core.persistence.jpa.entity.user.JPADynRoleMembership;
+import 
org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
 @Repository
-public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, 
UVirAttr> implements UserDAO {
+public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
 
     @Autowired
     private GroupDAO groupDAO;
@@ -73,57 +66,60 @@ public class JPAUserDAO extends 
AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
     @Resource(name = "anonymousUser")
     private String anonymousUser;
 
-    @Autowired
-    private AttributableUtilsFactory attrUtilsFactory;
-
     @Override
-    protected Subject<UPlainAttr, UDerAttr, UVirAttr> findInternal(final Long 
key) {
-        return find(key);
+    protected AnyUtils init() {
+        return new JPAAnyUtilsFactory().getInstance(AnyTypeKind.USER);
     }
 
     @Override
-    public User find(final Long key) {
-        TypedQuery<User> query = entityManager.createQuery(
-                "SELECT e FROM " + JPAUser.class.getSimpleName() + " e WHERE 
e.id = :id", User.class);
-        query.setParameter("id", key);
+    protected void securityChecks(final User user) {
+        // Allows anonymous (during self-registration) and self (during 
self-update) to read own user,
+        // otherwise goes through security checks to see if required 
entitlements are owned
+        if (!AuthContextUtils.getAuthenticatedUsername().equals(anonymousUser)
+                && 
!AuthContextUtils.getAuthenticatedUsername().equals(user.getUsername())) {
 
-        User result = null;
-        try {
-            result = query.getSingleResult();
-        } catch (NoResultException e) {
-            LOG.debug("No user found with id {}", key, e);
-        }
+            Set<String> authRealms = 
AuthContextUtils.getAuthorizations().get(Entitlement.USER_READ);
+            boolean authorized = CollectionUtils.exists(authRealms, new 
Predicate<String>() {
 
-        return result;
+                @Override
+                public boolean evaluate(final String realm) {
+                    return user.getRealm().getFullPath().startsWith(realm);
+                }
+            });
+            if (authRealms == null || authRealms.isEmpty() || !authorized) {
+                throw new UnauthorizedException(AnyTypeKind.USER, 
user.getKey());
+            }
+        }
     }
 
+    @Transactional(readOnly = true)
     @Override
-    public User find(final String username) {
-        TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + 
JPAUser.class.getSimpleName()
-                + " e WHERE e.username = :username", User.class);
-        query.setParameter("username", username);
+    public User authFind(final String username) {
+        if (username == null) {
+            throw new NotFoundException("Null username");
+        }
 
-        User result = null;
-        try {
-            result = query.getSingleResult();
-        } catch (NoResultException e) {
-            LOG.debug("No user found with username {}", username, e);
+        User user = find(username);
+        if (user == null) {
+            throw new NotFoundException("User " + username);
         }
 
-        return result;
+        securityChecks(user);
+
+        return user;
     }
 
     @Override
-    public User findByWorkflowId(final String workflowId) {
+    public User find(final String username) {
         TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + 
JPAUser.class.getSimpleName()
-                + " e WHERE e.workflowId = :workflowId", User.class);
-        query.setParameter("workflowId", workflowId);
+                + " e WHERE e.username = :username", User.class);
+        query.setParameter("username", username);
 
         User result = null;
         try {
             result = query.getSingleResult();
         } catch (NoResultException e) {
-            LOG.debug("No user found with workflow id {}", workflowId, e);
+            LOG.debug("No user found with username {}", username, e);
         }
 
         return result;
@@ -154,54 +150,10 @@ public class JPAUserDAO extends 
AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
         return query.getResultList();
     }
 
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<User> findByAttrValue(final String schemaName, final 
UPlainAttrValue attrValue) {
-        return (List<User>) findByAttrValue(
-                schemaName, attrValue, 
attrUtilsFactory.getInstance(AttributableType.USER));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public User findByAttrUniqueValue(final String schemaName, final 
UPlainAttrValue attrUniqueValue) {
-        return (User) findByAttrUniqueValue(schemaName, attrUniqueValue,
-                attrUtilsFactory.getInstance(AttributableType.USER));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<User> findByDerAttrValue(final String schemaName, final String 
value) {
-        return (List<User>) findByDerAttrValue(
-                schemaName, value, 
attrUtilsFactory.getInstance(AttributableType.USER));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
-    public List<User> findByResource(final ExternalResource resource) {
-        return (List<User>) findByResource(resource, 
attrUtilsFactory.getInstance(AttributableType.USER));
-    }
-
-    @Override
-    public final List<User> findAll(final Set<String> adminRealms, final int 
page, final int itemsPerPage) {
-        return findAll(adminRealms, page, itemsPerPage, 
Collections.<OrderByClause>emptyList());
-    }
-
-    @Override
-    public List<User> findAll(final Set<String> adminRealms,
-            final int page, final int itemsPerPage, final List<OrderByClause> 
orderBy) {
-
-        return searchDAO.search(adminRealms, getAllMatchingCond(), page, 
itemsPerPage, orderBy, SubjectType.USER);
-    }
-
-    @Override
-    public final int count(final Set<String> adminRealms) {
-        return searchDAO.count(adminRealms, getAllMatchingCond(), 
SubjectType.USER);
-    }
-
     @Override
     public User save(final User user) {
         User merged = entityManager.merge(user);
-        for (VirAttr virAttr : merged.getVirAttrs()) {
+        for (UVirAttr virAttr : merged.getVirAttrs()) {
             virAttr.getValues().clear();
             
virAttr.getValues().addAll(user.getVirAttr(virAttr.getSchema().getKey()).getValues());
         }
@@ -213,93 +165,17 @@ public class JPAUserDAO extends 
AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
     }
 
     @Override
-    public void delete(final Long key) {
-        User user = (User) findInternal(key);
-        if (user == null) {
-            return;
-        }
-
-        delete(user);
-    }
-
-    @Override
     public void delete(final User user) {
-        // Not calling membershipDAO.delete() here because it would try to 
save this user as well, thus going into
-        // ConcurrentModificationException
-        for (Membership membership : user.getMemberships()) {
-            membership.setUser(null);
-
-            groupDAO.save(membership.getGroup());
-            membership.setGroup(null);
-
-            entityManager.remove(membership);
-        }
-        user.getMemberships().clear();
-
         for (Role role : findDynRoleMemberships(user)) {
-            role.getDynMembership().removeUser(user);
+            role.getDynMembership().remove(user);
         }
         for (Group group : findDynGroupMemberships(user)) {
-            group.getDynMembership().removeUser(user);
+            group.getUDynMembership().remove(user);
         }
 
         entityManager.remove(user);
     }
 
-    private void securityChecks(final User user) {
-        // Allows anonymous (during self-registration) and self (during 
self-update) to read own user,
-        // otherwise goes through security checks to see if required 
entitlements are owned
-        if (!AuthContextUtils.getAuthenticatedUsername().equals(anonymousUser)
-                && 
!AuthContextUtils.getAuthenticatedUsername().equals(user.getUsername())) {
-
-            Set<String> authRealms = 
AuthContextUtils.getAuthorizations().get(Entitlement.USER_READ);
-            boolean authorized = CollectionUtils.exists(authRealms, new 
Predicate<String>() {
-
-                @Override
-                public boolean evaluate(final String realm) {
-                    return user.getRealm().getFullPath().startsWith(realm);
-                }
-            });
-            if (authRealms == null || authRealms.isEmpty() || !authorized) {
-                throw new UnauthorizedException(SubjectType.USER, 
user.getKey());
-            }
-        }
-    }
-
-    @Transactional(readOnly = true)
-    @Override
-    public User authFetch(final Long key) {
-        if (key == null) {
-            throw new NotFoundException("Null user id");
-        }
-
-        User user = find(key);
-        if (user == null) {
-            throw new NotFoundException("User " + key);
-        }
-
-        securityChecks(user);
-
-        return user;
-    }
-
-    @Transactional(readOnly = true)
-    @Override
-    public User authFetch(final String username) {
-        if (username == null) {
-            throw new NotFoundException("Null username");
-        }
-
-        User user = find(username);
-        if (user == null) {
-            throw new NotFoundException("User " + username);
-        }
-
-        securityChecks(user);
-
-        return user;
-    }
-
     @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
     @Override
     public List<Role> findDynRoleMemberships(final User user) {
@@ -315,7 +191,7 @@ public class JPAUserDAO extends 
AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
     @Override
     public List<Group> findDynGroupMemberships(final User user) {
         TypedQuery<Group> query = entityManager.createQuery(
-                "SELECT e.group FROM " + 
JPADynGroupMembership.class.getSimpleName()
+                "SELECT e.group FROM " + 
JPAUDynGroupMembership.class.getSimpleName()
                 + " e WHERE :user MEMBER OF e.users", Group.class);
         query.setParameter("user", user);
 
@@ -332,11 +208,11 @@ public class JPAUserDAO extends 
AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
     @Override
     public Collection<Group> findAllGroups(final User user) {
         return CollectionUtils.union(
-                CollectionUtils.collect(user.getMemberships(), new 
Transformer<Membership, Group>() {
+                CollectionUtils.collect(user.getMemberships(), new 
Transformer<UMembership, Group>() {
 
                     @Override
-                    public Group transform(final Membership input) {
-                        return input.getGroup();
+                    public Group transform(final UMembership input) {
+                        return input.getRightEnd();
                     }
                 }, new ArrayList<Group>()),
                 findDynGroupMemberships(user));

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
index 48a645a..3ef6791 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java
@@ -21,51 +21,51 @@ package org.apache.syncope.core.persistence.jpa.dao;
 import java.util.List;
 import javax.persistence.TypedQuery;
 import org.apache.syncope.core.persistence.api.dao.VirAttrDAO;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AVirAttr;
 import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
 import org.apache.syncope.core.persistence.api.entity.user.UVirAttr;
 import org.apache.syncope.core.persistence.jpa.entity.AbstractVirAttr;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirAttr;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAVirAttr;
 import org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirAttr;
 import org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirAttr;
 import org.springframework.stereotype.Repository;
 
 @Repository
-public class JPAVirAttrDAO extends AbstractDAO<VirAttr, Long> implements 
VirAttrDAO {
+public class JPAVirAttrDAO extends AbstractDAO<VirAttr<?>, Long> implements 
VirAttrDAO {
 
-    public <T extends VirAttr> Class<? extends AbstractVirAttr> 
getJPAEntityReference(
+    public <T extends VirAttr<?>> Class<? extends AbstractVirAttr<?>> 
getJPAEntityReference(
             final Class<T> reference) {
 
         return GVirAttr.class.isAssignableFrom(reference)
                 ? JPAGVirAttr.class
-                : MVirAttr.class.isAssignableFrom(reference)
-                        ? JPAMVirAttr.class
+                : AVirAttr.class.isAssignableFrom(reference)
+                        ? JPAAVirAttr.class
                         : UVirAttr.class.isAssignableFrom(reference)
                                 ? JPAUVirAttr.class
                                 : null;
     }
 
     @Override
-    public <T extends VirAttr> T find(final Long key, final Class<T> 
reference) {
+    public <T extends VirAttr<?>> T find(final Long key, final Class<T> 
reference) {
         return 
reference.cast(entityManager.find(getJPAEntityReference(reference), key));
     }
 
     @Override
-    public <T extends VirAttr> List<T> findAll(final Class<T> reference) {
+    public <T extends VirAttr<?>> List<T> findAll(final Class<T> reference) {
         TypedQuery<T> query = entityManager.createQuery(
                 "SELECT e FROM " + 
getJPAEntityReference(reference).getSimpleName() + " e", reference);
         return query.getResultList();
     }
 
     @Override
-    public <T extends VirAttr> T save(final T virAttr) {
+    public <T extends VirAttr<?>> T save(final T virAttr) {
         return entityManager.merge(virAttr);
     }
 
     @Override
-    public <T extends VirAttr> void delete(final Long key, final Class<T> 
reference) {
+    public <T extends VirAttr<?>> void delete(final Long key, final Class<T> 
reference) {
         T virAttr = find(key, reference);
         if (virAttr == null) {
             return;
@@ -76,9 +76,9 @@ public class JPAVirAttrDAO extends AbstractDAO<VirAttr, Long> 
implements VirAttr
 
     @Override
     @SuppressWarnings("unchecked")
-    public <T extends VirAttr> void delete(final T virAttr) {
+    public <T extends VirAttr<?>> void delete(final T virAttr) {
         if (virAttr.getOwner() != null) {
-            ((Attributable<?, ?, T>) 
virAttr.getOwner()).removeVirAttr(virAttr);
+            ((Any<?, ?, T>) virAttr.getOwner()).remove(virAttr);
         }
 
         entityManager.remove(virAttr);

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
index f0ce84b..ed4f6b6 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java
@@ -20,25 +20,16 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import java.util.List;
 import javax.persistence.TypedQuery;
-import org.apache.commons.collections4.Closure;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.core.persistence.api.dao.AttrTemplateDAO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
 import org.apache.syncope.core.persistence.api.dao.VirAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GVirSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
-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.jpa.entity.AbstractVirSchema;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirSchema;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirSchema;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirSchema;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
+import org.apache.syncope.core.persistence.jpa.entity.JPAVirSchema;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 
@@ -49,44 +40,25 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, 
String> implements V
     private VirAttrDAO virAttrDAO;
 
     @Autowired
-    private AttrTemplateDAO<VirSchema> attrTemplateDAO;
-
-    @Autowired
     private ExternalResourceDAO resourceDAO;
 
-    private <T extends VirSchema> Class<? extends AbstractVirSchema> 
getJPAEntityReference(final Class<T> reference) {
-        return GVirSchema.class.isAssignableFrom(reference)
-                ? JPAGVirSchema.class
-                : MVirSchema.class.isAssignableFrom(reference)
-                        ? JPAMVirSchema.class
-                        : UVirSchema.class.isAssignableFrom(reference)
-                                ? JPAUVirSchema.class
-                                : null;
-    }
-
     @Override
-    public <T extends VirSchema> T find(final String key, final Class<T> 
reference) {
-        return 
reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+    public VirSchema find(final String key) {
+        return entityManager.find(JPAVirSchema.class, key);
     }
 
     @Override
-    public <T extends VirSchema> List<T> findAll(final Class<T> reference) {
-        TypedQuery<T> query = entityManager.createQuery(
-                "SELECT e FROM " + 
getJPAEntityReference(reference).getSimpleName() + " e", reference);
+    public List<VirSchema> findAll() {
+        TypedQuery<VirSchema> query = entityManager.createQuery(
+                "SELECT e FROM " + JPAVirSchema.class.getSimpleName() + " e", 
VirSchema.class);
         return query.getResultList();
     }
 
     @Override
-    public <T extends VirAttr> List<T> findAttrs(final VirSchema schema, final 
Class<T> reference) {
+    public <T extends VirAttr<?>> List<T> findAttrs(final VirSchema schema, 
final Class<T> reference) {
         final StringBuilder queryString = new StringBuilder("SELECT e FROM ").
                 append(((JPAVirAttrDAO) 
virAttrDAO).getJPAEntityReference(reference).getSimpleName()).
-                append(" e WHERE e.");
-        if (UVirAttr.class.isAssignableFrom(reference)) {
-            queryString.append("virSchema");
-        } else {
-            queryString.append("template.schema");
-        }
-        queryString.append("=:schema");
+                append(" e WHERE e.schema=:schema");
 
         TypedQuery<T> query = 
entityManager.createQuery(queryString.toString(), reference);
         query.setParameter("schema", schema);
@@ -95,41 +67,28 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, 
String> implements V
     }
 
     @Override
-    public <T extends VirSchema> T save(final T virSchema) {
+    public VirSchema save(final VirSchema virSchema) {
         return entityManager.merge(virSchema);
     }
 
     @Override
-    public void delete(final String key, final AttributableUtils 
attributableUtil) {
-        final VirSchema schema = find(key, attributableUtil.virSchemaClass());
+    public void delete(final String key) {
+        final VirSchema schema = find(key);
         if (schema == null) {
             return;
         }
 
-        CollectionUtils.forAllDo(findAttrs(schema, 
attributableUtil.virAttrClass()), new Closure<VirAttr>() {
+        AnyUtilsFactory anyUtilsFactory = new JPAAnyUtilsFactory();
+        for (AnyTypeKind anyTypeKind : AnyTypeKind.values()) {
+            AnyUtils anyUtils = anyUtilsFactory.getInstance(anyTypeKind);
 
-            @Override
-            public void execute(final VirAttr input) {
-                virAttrDAO.delete(input.getKey(), 
attributableUtil.virAttrClass());
+            for (VirAttr<?> attr : findAttrs(schema, anyUtils.virAttrClass())) 
{
+                virAttrDAO.delete(attr.getKey(), anyUtils.virAttrClass());
             }
 
-        });
-
-        if (attributableUtil.getType() != AttributableType.USER) {
-            CollectionUtils.forAllDo(attrTemplateDAO.
-                    findBySchemaName(schema.getKey(), 
attributableUtil.virAttrTemplateClass()).iterator(),
-                    new Closure<Number>() {
-
-                        @Override
-                        public void execute(final Number input) {
-                            attrTemplateDAO.delete(input.longValue(), 
attributableUtil.virAttrTemplateClass());
-                        }
-
-                    });
+            resourceDAO.deleteMapping(key, anyUtils.virIntMappingType());
         }
 
-        resourceDAO.deleteMapping(key, attributableUtil.virIntMappingType(), 
UMappingItem.class);
-
         entityManager.remove(schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
index 11b3298..77be714 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java
@@ -20,8 +20,8 @@ package org.apache.syncope.core.persistence.jpa.dao;
 
 import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.SubjectType;
 
 class SearchSupport {
 
@@ -47,10 +47,10 @@ class SearchSupport {
         }
     }
 
-    private final SubjectType subjectType;
+    private final AnyTypeKind anyTypeKind;
 
-    public SearchSupport(final SubjectType subjectType) {
-        this.subjectType = subjectType;
+    public SearchSupport(final AnyTypeKind anyTypeKind) {
+        this.anyTypeKind = anyTypeKind;
     }
 
     public String fieldName(final AttrSchemaType attrSchemaType) {
@@ -88,15 +88,19 @@ class SearchSupport {
     public SearchView field() {
         String result = "";
 
-        switch (subjectType) {
-            case USER:
-            default:
-                result = "user_search";
+        switch (anyTypeKind) {
+            case ANY_OBJECT:
+                result = "anyObject_search";
                 break;
 
             case GROUP:
                 result = "group_search";
                 break;
+
+            case USER:
+            default:
+                result = "user_search";
+                break;
         }
 
         return new SearchView("sv", result);
@@ -106,12 +110,19 @@ class SearchSupport {
         return new SearchView("sva", field().name + "_attr");
     }
 
+    public SearchView relationship() {
+        String kind = anyTypeKind == AnyTypeKind.USER ? "u" : "a";
+        return new SearchView("sv" + kind + "m", field().name + "_" + kind + 
"relationship");
+    }
+
     public SearchView membership() {
-        return new SearchView("svm", field().name + "_membership");
+        String kind = anyTypeKind == AnyTypeKind.USER ? "u" : "a";
+        return new SearchView("sv" + kind + "m", field().name + "_" + kind + 
"membership");
     }
 
     public SearchView dyngroupmembership() {
-        return new SearchView("svdg", field().name + "_dyngroupmembership");
+        String kind = anyTypeKind == AnyTypeKind.USER ? "u" : "a";
+        return new SearchView("sv" + kind + "dgm", field().name + "_" + kind + 
"dyngroupmembership");
     }
 
     public SearchView role() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
new file mode 100644
index 0000000..161927c
--- /dev/null
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAny.java
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity;
+
+import 
org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
+import java.util.ArrayList;
+import java.util.List;
+import javax.persistence.Column;
+import javax.persistence.FetchType;
+import javax.persistence.ManyToOne;
+import javax.persistence.MappedSuperclass;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Predicate;
+import org.apache.commons.collections4.Transformer;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.DerAttr;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.VirAttr;
+import 
org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+
+@MappedSuperclass
+public abstract class AbstractAny<P extends PlainAttr<?>, D extends 
DerAttr<?>, V extends VirAttr<?>>
+        extends AbstractAnnotatedEntity<Long>
+        implements Any<P, D, V> {
+
+    private static final long serialVersionUID = -2666540708092702810L;
+
+    @ManyToOne(fetch = FetchType.EAGER, optional = false)
+    private JPARealm realm;
+
+    private String workflowId;
+
+    @Column(nullable = true)
+    private String status;
+
+    @Override
+    public Realm getRealm() {
+        return realm;
+    }
+
+    @Override
+    public void setRealm(final Realm realm) {
+        checkType(realm, JPARealm.class);
+        this.realm = (JPARealm) realm;
+    }
+
+    @Override
+    public String getWorkflowId() {
+        return workflowId;
+    }
+
+    @Override
+    public void setWorkflowId(final String workflowId) {
+        this.workflowId = workflowId;
+    }
+
+    @Override
+    public String getStatus() {
+        return status;
+    }
+
+    @Override
+    public void setStatus(final String status) {
+        this.status = status;
+    }
+
+    @Override
+    public P getPlainAttr(final String plainSchemaName) {
+        return CollectionUtils.find(getPlainAttrs(), new Predicate<P>() {
+
+            @Override
+            public boolean evaluate(final P plainAttr) {
+                return plainAttr != null && plainAttr.getSchema() != null
+                        && 
plainSchemaName.equals(plainAttr.getSchema().getKey());
+            }
+        });
+    }
+
+    @Override
+    public D getDerAttr(final String derSchemaName) {
+        return CollectionUtils.find(getDerAttrs(), new Predicate<D>() {
+
+            @Override
+            public boolean evaluate(final D derAttr) {
+                return derAttr != null && derAttr.getSchema() != null
+                        && derSchemaName.equals(derAttr.getSchema().getKey());
+            }
+        });
+    }
+
+    @Override
+    public V getVirAttr(final String virSchemaName) {
+        return CollectionUtils.find(getVirAttrs(), new Predicate<V>() {
+
+            @Override
+            public boolean evaluate(final V virAttr) {
+                return virAttr != null && virAttr.getSchema() != null
+                        && virSchemaName.equals(virAttr.getSchema().getKey());
+            }
+        });
+    }
+
+    protected abstract List<JPAExternalResource> internalGetResources();
+
+    @Override
+    public boolean add(final ExternalResource resource) {
+        checkType(resource, JPAExternalResource.class);
+        return internalGetResources().add((JPAExternalResource) resource);
+    }
+
+    @Override
+    public boolean remove(final ExternalResource resource) {
+        checkType(resource, JPAExternalResource.class);
+        return internalGetResources().remove((JPAExternalResource) resource);
+    }
+
+    @Override
+    public List<String> getResourceNames() {
+        return CollectionUtils.collect(getResources(), new 
Transformer<ExternalResource, String>() {
+
+            @Override
+            public String transform(final ExternalResource input) {
+                return input.getKey();
+            }
+        }, new ArrayList<String>());
+    }
+
+    @Override
+    public List<? extends ExternalResource> getResources() {
+        return internalGetResources();
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttrTemplate.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttrTemplate.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttrTemplate.java
deleted file mode 100644
index f2a32a1..0000000
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttrTemplate.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity;
-
-import org.apache.syncope.core.persistence.api.entity.AttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.Schema;
-
-public abstract class AbstractAttrTemplate<S extends Schema> extends 
AbstractEntity<Long> implements AttrTemplate<S> {
-
-    private static final long serialVersionUID = 4829112252713766666L;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttributable.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttributable.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttributable.java
deleted file mode 100644
index b2e2b34..0000000
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttributable.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity;
-
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
-import org.apache.syncope.core.persistence.api.entity.DerAttr;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-
-public abstract class AbstractAttributable<P extends PlainAttr, D extends 
DerAttr, V extends VirAttr>
-        extends AbstractAnnotatedEntity<Long> implements Attributable<P, D, V> 
{
-
-    private static final long serialVersionUID = -4801685541488201119L;
-
-    @Override
-    public P getPlainAttr(final String plainSchemaName) {
-        return CollectionUtils.find(getPlainAttrs(), new Predicate<P>() {
-
-            @Override
-            public boolean evaluate(final P plainAttr) {
-                return plainAttr != null && plainAttr.getSchema() != null
-                        && 
plainSchemaName.equals(plainAttr.getSchema().getKey());
-            }
-        });
-    }
-
-    @Override
-    public D getDerAttr(final String derSchemaName) {
-        return CollectionUtils.find(getDerAttrs(), new Predicate<D>() {
-
-            @Override
-            public boolean evaluate(final D derAttr) {
-                return derAttr != null && derAttr.getSchema() != null
-                        && derSchemaName.equals(derAttr.getSchema().getKey());
-            }
-        });
-    }
-
-    @Override
-    public V getVirAttr(final String virSchemaName) {
-        return CollectionUtils.find(getVirAttrs(), new Predicate<V>() {
-
-            @Override
-            public boolean evaluate(final V virAttr) {
-                return virAttr != null && virAttr.getSchema() != null
-                        && virSchemaName.equals(virAttr.getSchema().getKey());
-            }
-        });
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttr.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttr.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttr.java
index ae2ec1b..60dae3c 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttr.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttr.java
@@ -19,16 +19,21 @@
 package org.apache.syncope.core.persistence.jpa.entity;
 
 import java.util.Collection;
+import javax.persistence.Column;
+import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
+import javax.persistence.ManyToOne;
 import javax.persistence.MappedSuperclass;
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.misc.jexl.JexlUtils;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
 
 @MappedSuperclass
-public abstract class AbstractDerAttr extends AbstractEntity<Long> implements 
DerAttr {
+public abstract class AbstractDerAttr<O extends Any<?, ?, ?>> extends 
AbstractEntity<Long> implements DerAttr<O> {
 
     private static final long serialVersionUID = 4740924251090424771L;
 
@@ -36,17 +41,32 @@ public abstract class AbstractDerAttr extends 
AbstractEntity<Long> implements De
     @GeneratedValue(strategy = GenerationType.AUTO)
     protected Long id;
 
+    @ManyToOne(fetch = FetchType.EAGER)
+    @Column(name = "schema_name")
+    private JPADerSchema schema;
+
     @Override
     public Long getKey() {
         return id;
     }
 
+    @Override
+    public DerSchema getSchema() {
+        return schema;
+    }
+
+    @Override
+    public void setSchema(final DerSchema derSchema) {
+        checkType(derSchema, JPADerSchema.class);
+        this.schema = (JPADerSchema) derSchema;
+    }
+
     /**
      * @param attributes the set of attributes against which evaluate this 
derived attribute
      * @return the value of this derived attribute
      */
     @Override
-    public String getValue(final Collection<? extends PlainAttr> attributes) {
+    public String getValue(final Collection<? extends PlainAttr<?>> 
attributes) {
         return JexlUtils.evaluate(getSchema().getExpression(), getOwner(), 
attributes);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttrTemplate.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttrTemplate.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttrTemplate.java
deleted file mode 100644
index 3846b12..0000000
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttrTemplate.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity;
-
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.MappedSuperclass;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
-
-@MappedSuperclass
-public abstract class AbstractDerAttrTemplate<D extends DerSchema> extends 
AbstractAttrTemplate<D> {
-
-    private static final long serialVersionUID = 8871895736733379865L;
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    protected Long id;
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerSchema.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerSchema.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerSchema.java
deleted file mode 100644
index 195f41d..0000000
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerSchema.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity;
-
-import javax.persistence.Column;
-import javax.persistence.Id;
-import javax.persistence.MappedSuperclass;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import 
org.apache.syncope.core.persistence.jpa.validation.entity.SchemaNameCheck;
-
-@MappedSuperclass
-@SchemaNameCheck
-public abstract class AbstractDerSchema extends AbstractEntity<String> 
implements DerSchema {
-
-    private static final long serialVersionUID = -6173643493348674060L;
-
-    @Id
-    private String name;
-
-    @Column(nullable = false)
-    private String expression;
-
-    @Override
-    public String getKey() {
-        return name;
-    }
-
-    @Override
-    public void setKey(final String key) {
-        this.name = key;
-    }
-
-    @Override
-    public String getExpression() {
-        return expression;
-    }
-
-    @Override
-    public void setExpression(final String expression) {
-        this.expression = expression;
-    }
-
-    @Override
-    public AttrSchemaType getType() {
-        return AttrSchemaType.String;
-    }
-
-    @Override
-    public String getMandatoryCondition() {
-        return Boolean.FALSE.toString().toLowerCase();
-    }
-
-    @Override
-    public boolean isMultivalue() {
-        return Boolean.TRUE;
-    }
-
-    @Override
-    public boolean isUniqueConstraint() {
-        return Boolean.FALSE;
-    }
-
-    @Override
-    public boolean isReadonly() {
-        return Boolean.FALSE;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDynMembership.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDynMembership.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDynMembership.java
index 6e47b34..c5404e9 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDynMembership.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDynMembership.java
@@ -18,15 +18,14 @@
  */
 package org.apache.syncope.core.persistence.jpa.entity;
 
-import java.util.List;
 import javax.persistence.MappedSuperclass;
 import javax.validation.constraints.NotNull;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.DynMembership;
-import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser;
 
 @MappedSuperclass
-public abstract class AbstractDynMembership extends AbstractEntity<Long> 
implements DynMembership {
+public abstract class AbstractDynMembership<A extends Any<?, ?, ?>>
+        extends AbstractEntity<Long> implements DynMembership<A> {
 
     private static final long serialVersionUID = 921821654690948787L;
 
@@ -43,23 +42,4 @@ public abstract class AbstractDynMembership extends 
AbstractEntity<Long> impleme
         this.fiql = fiql;
     }
 
-    protected abstract List<JPAUser> internalGetUsers();
-
-    @Override
-    public boolean addUser(final User user) {
-        checkType(user, JPAUser.class);
-        return internalGetUsers().add((JPAUser) user);
-    }
-
-    @Override
-    public boolean removeUser(final User user) {
-        checkType(user, JPAUser.class);
-        return internalGetUsers().remove((JPAUser) user);
-    }
-
-    @Override
-    public List<? extends User> getUsers() {
-        return internalGetUsers();
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMapping.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMapping.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMapping.java
deleted file mode 100644
index 4481d3e..0000000
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMapping.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity;
-
-import javax.persistence.Cacheable;
-import javax.persistence.MappedSuperclass;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Predicate;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.core.persistence.api.entity.Mapping;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-
-@MappedSuperclass
-@Cacheable
-public abstract class AbstractMapping<T extends MappingItem> extends 
AbstractEntity<Long> implements Mapping<T> {
-
-    private static final long serialVersionUID = 4316047254916259158L;
-
-    /**
-     * A JEXL expression for determining how to find the account id in 
external resource's space.
-     */
-    private String accountLink;
-
-    @Override
-    public String getAccountLink() {
-        return accountLink;
-    }
-
-    @Override
-    public void setAccountLink(final String accountLink) {
-        this.accountLink = accountLink;
-    }
-
-    @Override
-    public T getAccountIdItem() {
-        return CollectionUtils.find(getItems(), new Predicate<T>() {
-
-            @Override
-            public boolean evaluate(final T item) {
-                return item.isAccountid();
-            }
-        });
-    }
-
-    protected boolean addAccountIdItem(final T accountIdItem) {
-        if (IntMappingType.UserVirtualSchema == 
accountIdItem.getIntMappingType()
-                || IntMappingType.GroupVirtualSchema == 
accountIdItem.getIntMappingType()
-                || IntMappingType.MembershipVirtualSchema == 
accountIdItem.getIntMappingType()
-                || IntMappingType.Password == 
accountIdItem.getIntMappingType()) {
-
-            throw new IllegalArgumentException("Virtual attributes cannot be 
set as accountId");
-        }
-        if (IntMappingType.Password == accountIdItem.getIntMappingType()) {
-            throw new IllegalArgumentException("Password attributes cannot be 
set as accountId");
-        }
-
-        accountIdItem.setExtAttrName(accountIdItem.getExtAttrName());
-        accountIdItem.setAccountid(true);
-
-        return this.addItem(accountIdItem);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMappingItem.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMappingItem.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMappingItem.java
deleted file mode 100644
index 98aab13..0000000
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMappingItem.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity;
-
-import javax.persistence.Basic;
-import javax.persistence.Cacheable;
-import javax.persistence.Column;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.MappedSuperclass;
-import javax.validation.constraints.Max;
-import javax.validation.constraints.Min;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.MappingPurpose;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
-
-@MappedSuperclass
-@Cacheable
-public abstract class AbstractMappingItem extends AbstractEntity<Long> 
implements MappingItem {
-
-    private static final long serialVersionUID = 7383601853619332424L;
-
-    @Column(nullable = true)
-    private String intAttrName;
-
-    @Column(nullable = false)
-    @Enumerated(EnumType.STRING)
-    private IntMappingType intMappingType;
-
-    /**
-     * Target resource's field to be mapped.
-     */
-    @Column(nullable = true)
-    private String extAttrName;
-
-    /**
-     * Specify if the mapped target resource's field is nullable.
-     */
-    @Column(nullable = false)
-    private String mandatoryCondition;
-
-    /**
-     * Specify if the mapped target resource's field is the key.
-     */
-    @Column(nullable = false)
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer accountid;
-
-    /**
-     * Specify if the mapped target resource's field is the password.
-     */
-    @Column(nullable = false)
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer password;
-
-    /**
-     * Mapping purposes: SYNCHRONIZATION, PROPAGATION, BOTH.
-     */
-    @Column(nullable = false)
-    @Enumerated(EnumType.STRING)
-    private MappingPurpose purpose;
-
-    public AbstractMappingItem() {
-        super();
-
-        mandatoryCondition = Boolean.FALSE.toString();
-
-        accountid = getBooleanAsInteger(false);
-        password = getBooleanAsInteger(false);
-    }
-
-    @Override
-    public String getExtAttrName() {
-        return extAttrName;
-    }
-
-    @Override
-    public void setExtAttrName(final String extAttrName) {
-        this.extAttrName = extAttrName;
-    }
-
-    @Override
-    public String getMandatoryCondition() {
-        return mandatoryCondition;
-    }
-
-    @Override
-    public void setMandatoryCondition(final String mandatoryCondition) {
-        this.mandatoryCondition = mandatoryCondition;
-    }
-
-    @Override
-    public String getIntAttrName() {
-        final String name;
-
-        switch (getIntMappingType()) {
-            case UserId:
-            case GroupId:
-            case MembershipId:
-                name = "id";
-                break;
-
-            case Username:
-                name = "username";
-                break;
-
-            case Password:
-                name = "password";
-                break;
-
-            case GroupName:
-                name = "groupName";
-                break;
-
-            case GroupOwnerSchema:
-                name = "groupOwnerSchema";
-                break;
-
-            default:
-                name = intAttrName;
-        }
-
-        return name;
-    }
-
-    @Override
-    public void setIntAttrName(final String intAttrName) {
-        this.intAttrName = intAttrName;
-    }
-
-    @Override
-    public IntMappingType getIntMappingType() {
-        return intMappingType;
-    }
-
-    @Override
-    public void setIntMappingType(final IntMappingType intMappingType) {
-        this.intMappingType = intMappingType;
-    }
-
-    @Override
-    public boolean isAccountid() {
-        return isBooleanAsInteger(accountid);
-    }
-
-    @Override
-    public void setAccountid(final boolean accountid) {
-        this.accountid = getBooleanAsInteger(accountid);
-    }
-
-    @Override
-    public boolean isPassword() {
-        return isBooleanAsInteger(password);
-    }
-
-    @Override
-    public void setPassword(final boolean password) {
-        this.password = getBooleanAsInteger(password);
-    }
-
-    @Override
-    public MappingPurpose getPurpose() {
-        return purpose;
-    }
-
-    @Override
-    public void setPurpose(final MappingPurpose purpose) {
-        this.purpose = purpose;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java
index ff1efee..a93cc45 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java
@@ -21,33 +21,45 @@ package org.apache.syncope.core.persistence.jpa.entity;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import javax.persistence.Column;
+import javax.persistence.FetchType;
+import javax.persistence.ManyToOne;
 import javax.persistence.MappedSuperclass;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 import 
org.apache.syncope.core.persistence.jpa.validation.entity.PlainAttrCheck;
 
 @MappedSuperclass
 @PlainAttrCheck
-public abstract class AbstractPlainAttr extends AbstractEntity<Long> 
implements PlainAttr {
+public abstract class AbstractPlainAttr<O extends Any<?, ?, ?>> extends 
AbstractEntity<Long> implements PlainAttr<O> {
 
     private static final long serialVersionUID = -9115431608821806124L;
 
-    protected abstract boolean addValue(PlainAttrValue attrValue);
+    @ManyToOne(fetch = FetchType.EAGER)
+    @Column(name = "schema_name")
+    private JPAPlainSchema schema;
 
     @Override
-    public void addValue(final String value, final AttributableUtils 
attributableUtil) {
-        PlainAttrValue attrValue;
-        if (getSchema().isUniqueConstraint()) {
-            attrValue = attributableUtil.newPlainAttrUniqueValue();
-            ((PlainAttrUniqueValue) attrValue).setSchema(getSchema());
-        } else {
-            attrValue = attributableUtil.newPlainAttrValue();
-        }
+    public PlainSchema getSchema() {
+        return schema;
+    }
+
+    @Override
+    public void setSchema(final PlainSchema schema) {
+        checkType(schema, JPAPlainSchema.class);
+        this.schema = (JPAPlainSchema) schema;
+    }
+
+    protected abstract boolean addForMultiValue(PlainAttrValue attrValue);
 
+    @Override
+    public void add(final String value, final PlainAttrValue attrValue) {
         attrValue.setAttr(this);
         getSchema().getValidator().validate(value, attrValue);
 
@@ -57,8 +69,21 @@ public abstract class AbstractPlainAttr extends 
AbstractEntity<Long> implements
             if (!getSchema().isMultivalue()) {
                 getValues().clear();
             }
-            addValue(attrValue);
+            addForMultiValue(attrValue);
+        }
+    }
+
+    @Override
+    public void add(final String value, final AnyUtils anyUtils) {
+        PlainAttrValue attrValue;
+        if (getSchema().isUniqueConstraint()) {
+            attrValue = anyUtils.newPlainAttrUniqueValue();
+            ((PlainAttrUniqueValue) attrValue).setSchema(getSchema());
+        } else {
+            attrValue = anyUtils.newPlainAttrValue();
         }
+
+        add(value, attrValue);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrTemplate.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrTemplate.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrTemplate.java
deleted file mode 100644
index a6777a1..0000000
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrTemplate.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity;
-
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-
-public abstract class AbstractPlainAttrTemplate<P extends PlainSchema> extends 
AbstractAttrTemplate<P> {
-
-    private static final long serialVersionUID = -943169893494860655L;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainSchema.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainSchema.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainSchema.java
deleted file mode 100644
index d08ba1c..0000000
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainSchema.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity;
-
-import java.lang.reflect.Constructor;
-import javax.persistence.Basic;
-import javax.persistence.Column;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.Id;
-import javax.persistence.Lob;
-import javax.persistence.MappedSuperclass;
-import javax.persistence.Transient;
-import javax.validation.constraints.Max;
-import javax.validation.constraints.Min;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.common.lib.types.CipherAlgorithm;
-import org.apache.syncope.core.persistence.api.attrvalue.validation.Validator;
-import org.apache.syncope.core.persistence.api.entity.PlainSchema;
-import 
org.apache.syncope.core.persistence.jpa.attrvalue.validation.BasicValidator;
-import 
org.apache.syncope.core.persistence.jpa.validation.entity.PlainSchemaCheck;
-import 
org.apache.syncope.core.persistence.jpa.validation.entity.SchemaNameCheck;
-
-@MappedSuperclass
-@PlainSchemaCheck
-@SchemaNameCheck
-public abstract class AbstractPlainSchema extends AbstractEntity<String> 
implements PlainSchema {
-
-    private static final long serialVersionUID = -8621028596062054739L;
-
-    @Id
-    private String name;
-
-    @Column(nullable = false)
-    @Enumerated(EnumType.STRING)
-    private AttrSchemaType type;
-
-    @Column(nullable = false)
-    private String mandatoryCondition;
-
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer multivalue;
-
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer uniqueConstraint;
-
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer readonly;
-
-    @Column(nullable = true)
-    private String conversionPattern;
-
-    @Column(nullable = true)
-    private String validatorClass;
-
-    @Column(nullable = true)
-    @Lob
-    private String enumerationValues;
-
-    @Column(nullable = true)
-    @Lob
-    private String enumerationKeys;
-
-    @Column(nullable = true)
-    private String secretKey;
-
-    @Column(nullable = true)
-    @Enumerated(EnumType.STRING)
-    private CipherAlgorithm cipherAlgorithm;
-
-    @Column(nullable = true)
-    private String mimeType;
-
-    @Transient
-    private Validator validator;
-
-    public AbstractPlainSchema() {
-        super();
-
-        type = AttrSchemaType.String;
-        mandatoryCondition = Boolean.FALSE.toString();
-        multivalue = getBooleanAsInteger(false);
-        uniqueConstraint = getBooleanAsInteger(false);
-        readonly = getBooleanAsInteger(false);
-    }
-
-    @Override
-    public String getKey() {
-        return name;
-    }
-
-    @Override
-    public void setKey(final String name) {
-        this.name = name;
-    }
-
-    @Override
-    public AttrSchemaType getType() {
-        return type;
-    }
-
-    @Override
-    public void setType(final AttrSchemaType type) {
-        this.type = type;
-    }
-
-    @Override
-    public String getMandatoryCondition() {
-        return mandatoryCondition;
-    }
-
-    @Override
-    public void setMandatoryCondition(final String condition) {
-        this.mandatoryCondition = condition;
-    }
-
-    @Override
-    public boolean isMultivalue() {
-        return isBooleanAsInteger(multivalue);
-    }
-
-    @Override
-    public void setMultivalue(final boolean multivalue) {
-        this.multivalue = getBooleanAsInteger(multivalue);
-    }
-
-    @Override
-    public boolean isUniqueConstraint() {
-        return isBooleanAsInteger(uniqueConstraint);
-    }
-
-    @Override
-    public void setUniqueConstraint(final boolean uniquevalue) {
-        this.uniqueConstraint = getBooleanAsInteger(uniquevalue);
-    }
-
-    @Override
-    public boolean isReadonly() {
-        return isBooleanAsInteger(readonly);
-    }
-
-    @Override
-    public void setReadonly(final boolean readonly) {
-        this.readonly = getBooleanAsInteger(readonly);
-    }
-
-    @Override
-    public Validator getValidator() {
-        if (validator != null) {
-            return validator;
-        }
-
-        if (getValidatorClass() != null && getValidatorClass().length() > 0) {
-            try {
-                Constructor<?> validatorConstructor = 
Class.forName(getValidatorClass()).
-                        getConstructor(new Class<?>[] { PlainSchema.class });
-                validator = (Validator) validatorConstructor.newInstance(this);
-            } catch (Exception e) {
-                LOG.error("Could not instantiate validator of type {}, 
reverting to {}",
-                        getValidatorClass(), 
BasicValidator.class.getSimpleName(), e);
-            }
-        }
-
-        if (validator == null) {
-            validator = new BasicValidator(this);
-        }
-
-        return validator;
-    }
-
-    @Override
-    public String getValidatorClass() {
-        return validatorClass;
-    }
-
-    @Override
-    public void setValidatorClass(final String validatorClass) {
-        this.validatorClass = validatorClass;
-    }
-
-    @Override
-    public String getEnumerationValues() {
-        return enumerationValues;
-    }
-
-    @Override
-    public void setEnumerationValues(final String enumerationValues) {
-        this.enumerationValues = enumerationValues;
-    }
-
-    @Override
-    public String getEnumerationKeys() {
-        return enumerationKeys;
-    }
-
-    @Override
-    public void setEnumerationKeys(final String enumerationKeys) {
-        this.enumerationKeys = enumerationKeys;
-    }
-
-    @Override
-    public String getConversionPattern() {
-        if (!getType().isConversionPatternNeeded()) {
-            LOG.debug("Conversion pattern is not needed: {}'s type is {}", 
this, getType());
-        }
-
-        return conversionPattern;
-    }
-
-    @Override
-    public void setConversionPattern(final String conversionPattern) {
-        if (StringUtils.isNotBlank(conversionPattern) && 
!getType().isConversionPatternNeeded()) {
-            LOG.warn("Conversion pattern will be ignored: this attribute type 
is {}", getType());
-        }
-
-        this.conversionPattern = conversionPattern;
-    }
-
-    @Override
-    public String getSecretKey() {
-        return secretKey;
-    }
-
-    @Override
-    public void setSecretKey(final String secretKey) {
-        this.secretKey = secretKey;
-    }
-
-    @Override
-    public CipherAlgorithm getCipherAlgorithm() {
-        return cipherAlgorithm;
-    }
-
-    @Override
-    public void setCipherAlgorithm(final CipherAlgorithm cipherAlgorithm) {
-        this.cipherAlgorithm = cipherAlgorithm;
-    }
-
-    @Override
-    public String getMimeType() {
-        return mimeType;
-    }
-
-    @Override
-    public void setMimeType(final String mimeType) {
-        this.mimeType = mimeType;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractSubject.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractSubject.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractSubject.java
deleted file mode 100644
index 166309f..0000000
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractSubject.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity;
-
-import java.util.HashSet;
-import java.util.Set;
-import javax.persistence.FetchType;
-import javax.persistence.ManyToOne;
-import javax.persistence.MappedSuperclass;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.Transformer;
-import org.apache.syncope.core.persistence.api.entity.DerAttr;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.PlainAttr;
-import org.apache.syncope.core.persistence.api.entity.Realm;
-import org.apache.syncope.core.persistence.api.entity.Subject;
-import org.apache.syncope.core.persistence.api.entity.VirAttr;
-
-@MappedSuperclass
-public abstract class AbstractSubject<P extends PlainAttr, D extends DerAttr, 
V extends VirAttr>
-        extends AbstractAttributable<P, D, V> implements Subject<P, D, V> {
-
-    private static final long serialVersionUID = -6876467491398928855L;
-
-    @ManyToOne(fetch = FetchType.EAGER, optional = false)
-    protected JPARealm realm;
-
-    @Override
-    public Realm getRealm() {
-        return realm;
-    }
-
-    @Override
-    public void setRealm(final Realm realm) {
-        checkType(realm, JPARealm.class);
-        this.realm = (JPARealm) realm;
-    }
-
-    protected abstract Set<JPAExternalResource> internalGetResources();
-
-    @Override
-    public boolean addResource(final ExternalResource resource) {
-        checkType(resource, JPAExternalResource.class);
-        return internalGetResources().add((JPAExternalResource) resource);
-    }
-
-    @Override
-    public boolean removeResource(final ExternalResource resource) {
-        checkType(resource, JPAExternalResource.class);
-        return internalGetResources().remove((JPAExternalResource) resource);
-    }
-
-    @Override
-    public Set<? extends ExternalResource> getResources() {
-        return internalGetResources();
-    }
-
-    @Override
-    public Set<String> getResourceNames() {
-        return CollectionUtils.collect(getResources(), new 
Transformer<ExternalResource, String>() {
-
-            @Override
-            public String transform(final ExternalResource input) {
-                return input.getKey();
-            }
-        }, new HashSet<String>());
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttr.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttr.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttr.java
index 7097c8d..1ed64f3 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttr.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttr.java
@@ -20,16 +20,20 @@ package org.apache.syncope.core.persistence.jpa.entity;
 
 import java.util.ArrayList;
 import java.util.List;
-
+import javax.persistence.Column;
+import javax.persistence.FetchType;
 import javax.persistence.GeneratedValue;
 import javax.persistence.GenerationType;
 import javax.persistence.Id;
+import javax.persistence.ManyToOne;
 import javax.persistence.MappedSuperclass;
 import javax.persistence.Transient;
+import org.apache.syncope.core.persistence.api.entity.Any;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
 
 @MappedSuperclass
-public abstract class AbstractVirAttr extends AbstractEntity<Long> implements 
VirAttr {
+public abstract class AbstractVirAttr<O extends Any<?, ?, ?>> extends 
AbstractEntity<Long> implements VirAttr<O> {
 
     private static final long serialVersionUID = 5023204776925954907L;
 
@@ -40,6 +44,10 @@ public abstract class AbstractVirAttr extends 
AbstractEntity<Long> implements Vi
     @Transient
     protected List<String> values = new ArrayList<>();
 
+    @ManyToOne(fetch = FetchType.EAGER)
+    @Column(name = "schema_name")
+    private JPAVirSchema schema;
+
     @Override
     public Long getKey() {
         return id;
@@ -51,12 +59,23 @@ public abstract class AbstractVirAttr extends 
AbstractEntity<Long> implements Vi
     }
 
     @Override
-    public boolean addValue(final String value) {
+    public boolean add(final String value) {
         return !values.contains(value) && values.add(value);
     }
 
     @Override
-    public boolean removeValue(final String value) {
+    public boolean remove(final String value) {
         return values.remove(value);
     }
+
+    @Override
+    public VirSchema getSchema() {
+        return schema;
+    }
+
+    @Override
+    public void setSchema(final VirSchema virSchema) {
+        checkType(virSchema, JPAVirSchema.class);
+        this.schema = (JPAVirSchema) virSchema;
+    }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttrTemplate.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttrTemplate.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttrTemplate.java
deleted file mode 100644
index 94b34dc..0000000
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirAttrTemplate.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity;
-
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.MappedSuperclass;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
-
-@MappedSuperclass
-public abstract class AbstractVirAttrTemplate<V extends VirSchema> extends 
AbstractAttrTemplate<V> {
-
-    private static final long serialVersionUID = -943169893494860655L;
-
-    @Id
-    @GeneratedValue(strategy = GenerationType.AUTO)
-    protected Long id;
-
-    @Override
-    public Long getKey() {
-        return id;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirSchema.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirSchema.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirSchema.java
deleted file mode 100644
index 9541a2e..0000000
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractVirSchema.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.core.persistence.jpa.entity;
-
-import javax.persistence.Basic;
-import javax.persistence.Id;
-import javax.persistence.MappedSuperclass;
-import javax.validation.constraints.Max;
-import javax.validation.constraints.Min;
-import org.apache.syncope.common.lib.types.AttrSchemaType;
-import org.apache.syncope.core.persistence.api.entity.VirSchema;
-import 
org.apache.syncope.core.persistence.jpa.validation.entity.SchemaNameCheck;
-
-@MappedSuperclass
-@SchemaNameCheck
-public abstract class AbstractVirSchema extends AbstractEntity<String> 
implements VirSchema {
-
-    private static final long serialVersionUID = 3274006935328590141L;
-
-    @Id
-    private String name;
-
-    @Basic
-    @Min(0)
-    @Max(1)
-    private Integer readonly;
-
-    public AbstractVirSchema() {
-        super();
-
-        readonly = getBooleanAsInteger(false);
-    }
-
-    @Override
-    public String getKey() {
-        return name;
-    }
-
-    @Override
-    public void setKey(final String key) {
-        this.name = key;
-    }
-
-    @Override
-    public AttrSchemaType getType() {
-        return AttrSchemaType.String;
-    }
-
-    @Override
-    public String getMandatoryCondition() {
-        return Boolean.FALSE.toString().toLowerCase();
-    }
-
-    @Override
-    public boolean isMultivalue() {
-        return Boolean.TRUE;
-    }
-
-    @Override
-    public boolean isUniqueConstraint() {
-        return Boolean.FALSE;
-    }
-
-    @Override
-    public boolean isReadonly() {
-        return isBooleanAsInteger(readonly);
-    }
-
-    @Override
-    public void setReadonly(final boolean readonly) {
-        this.readonly = getBooleanAsInteger(readonly);
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccountPolicy.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccountPolicy.java
 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccountPolicy.java
index 9509e38..6949817 100644
--- 
a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccountPolicy.java
+++ 
b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAccountPolicy.java
@@ -26,12 +26,12 @@ import javax.persistence.FetchType;
 import javax.persistence.JoinColumn;
 import javax.persistence.JoinTable;
 import javax.persistence.ManyToMany;
-import javax.validation.Valid;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Transformer;
 import org.apache.syncope.common.lib.types.PolicyType;
 import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import 
org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import 
org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 
 @Entity
 @DiscriminatorValue("AccountPolicy")
@@ -44,10 +44,9 @@ public class JPAAccountPolicy extends JPAPolicy implements 
AccountPolicy {
      */
     @ManyToMany(fetch = FetchType.EAGER)
     @JoinTable(joinColumns =
-            @JoinColumn(name = "account_policy_id"),
+            @JoinColumn(name = "accountPolicy_id"),
             inverseJoinColumns =
             @JoinColumn(name = "resource_name"))
-    @Valid
     private Set<JPAExternalResource> resources = new HashSet<>();
 
     public JPAAccountPolicy() {

Reply via email to