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/06/11 16:17:24 UTC

[34/70] syncope git commit: [SYNCOPE-666] Several JPA tests added

[SYNCOPE-666] Several JPA tests added


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/419fccfe
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/419fccfe
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/419fccfe

Branch: refs/heads/master
Commit: 419fccfeba9ebd63112e98e00350e5be90706ce8
Parents: a78a6f1
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Tue May 26 16:55:56 2015 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Tue May 26 16:55:56 2015 +0200

----------------------------------------------------------------------
 .../common/lib/types/EntityViolationType.java   |   1 +
 .../core/persistence/api/dao/AnyObjectDAO.java  |   6 +
 .../core/persistence/api/dao/AnyTypeDAO.java    |   3 +
 .../core/persistence/api/dao/DerSchemaDAO.java  |  12 +-
 .../persistence/api/dao/PlainSchemaDAO.java     |  12 +-
 .../core/persistence/api/dao/SchemaDAO.java     |  39 +++++++
 .../core/persistence/api/dao/VirSchemaDAO.java  |  13 +--
 .../core/persistence/api/entity/Schema.java     |   4 +
 .../persistence/jpa/dao/JPAAnyObjectDAO.java    |  40 ++++++-
 .../persistence/jpa/dao/JPAAnyTypeClassDAO.java |  35 ++++++
 .../core/persistence/jpa/dao/JPAAnyTypeDAO.java |  34 +++---
 .../persistence/jpa/dao/JPADerSchemaDAO.java    |  17 ++-
 .../persistence/jpa/dao/JPAPlainSchemaDAO.java  |  15 +++
 .../core/persistence/jpa/dao/JPAUserDAO.java    |   7 +-
 .../persistence/jpa/dao/JPAVirSchemaDAO.java    |  15 +++
 .../core/persistence/jpa/entity/JPAAnyType.java |   2 +
 .../persistence/jpa/entity/JPAAnyTypeClass.java |  25 +---
 .../persistence/jpa/entity/JPADerSchema.java    |  16 +++
 .../jpa/entity/JPAEntityFactory.java            |  22 ++++
 .../persistence/jpa/entity/JPAPlainSchema.java  |  16 +++
 .../persistence/jpa/entity/JPAVirSchema.java    |  16 +++
 .../jpa/entity/resource/JPAProvision.java       |   2 +
 .../jpa/validation/entity/AnyTypeCheck.java     |  41 +++++++
 .../jpa/validation/entity/AnyTypeValidator.java |  56 +++++++++
 .../entity/ExternalResourceValidator.java       |  28 ++++-
 .../src/main/resources/META-INF/spring-orm.xml  |  20 +++-
 .../persistence/jpa/entity/AnyObjectTest.java   |  75 ++++++++++++
 .../jpa/entity/AnyTypeClassTest.java            |  81 +++++++++++++
 .../persistence/jpa/entity/AnyTypeTest.java     | 114 +++++++++++++++++++
 .../persistence/jpa/entity/ResourceTest.java    |  51 ++++++++-
 .../jpa/relationship/AnyTypeClassTest.java      |  62 ++++++++++
 .../jpa/relationship/AnyTypeTest.java           |  66 +++++++++++
 .../persistence/jpa/relationship/GroupTest.java | 107 ++++++++++++++++-
 .../persistence/jpa/relationship/UserTest.java  |  59 +++++++++-
 .../src/test/resources/content.xml              |  96 ++++++++++------
 35 files changed, 1078 insertions(+), 130 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java
index 2192bd5..6e05a52 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/EntityViolationType.java
@@ -25,6 +25,7 @@ public enum EntityViolationType {
 
     Standard(""),
     InvalidAccountPolicy("org.apache.syncope.core.persistence.validation.accountpolicy"),
+    InvalidAnyType("org.apache.syncope.core.persistence.validation.anytype"),
     InvalidConnInstanceLocation("org.apache.syncope.core.persistence.validation.conninstance.location"),
     InvalidConnPoolConf("org.apache.syncope.core.persistence.validation.conninstance.poolConf"),
     InvalidMapping("org.apache.syncope.core.persistence.validation.mapping"),

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
index d01511f..bd2f938 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyObjectDAO.java
@@ -20,9 +20,11 @@ package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.Collection;
 import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.user.URelationship;
 
 public interface AnyObjectDAO extends AnyDAO<AnyObject> {
 
@@ -30,6 +32,10 @@ public interface AnyObjectDAO extends AnyDAO<AnyObject> {
 
     List<Group> findDynGroupMemberships(AnyObject anyObject);
 
+    List<ARelationship> findARelationships(AnyObject anyObject);
+
+    List<URelationship> findURelationships(AnyObject anyObject);
+
     Collection<Group> findAllGroups(AnyObject anyObject);
 
     Collection<Long> findAllGroupKeys(AnyObject anyObject);

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyTypeDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyTypeDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyTypeDAO.java
index bef6812..32483b5 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyTypeDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/AnyTypeDAO.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.persistence.api.dao;
 
 import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 
 public interface AnyTypeDAO extends DAO<AnyType, String> {
 
@@ -29,6 +30,8 @@ public interface AnyTypeDAO extends DAO<AnyType, String> {
 
     AnyType findGroup();
 
+    List<AnyType> findByTypeClass(AnyTypeClass anyTypeClass);
+
     List<AnyType> findAll();
 
     AnyType save(AnyType anyType);

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DerSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DerSchemaDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DerSchemaDAO.java
index d943b83..70161f9 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DerSchemaDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/DerSchemaDAO.java
@@ -18,19 +18,9 @@
  */
 package org.apache.syncope.core.persistence.api.dao;
 
-import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.DerAttr;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 
-public interface DerSchemaDAO extends DAO<DerSchema, String> {
+public interface DerSchemaDAO extends SchemaDAO<DerSchema, DerAttr<?>> {
 
-    DerSchema find(String name);
-
-    List<DerSchema> findAll();
-
-    <T extends DerAttr<?>> List<T> findAttrs(DerSchema schema, Class<T> reference);
-
-    DerSchema save(DerSchema derSchema);
-
-    void delete(String key);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java
index 2dda81e..df51db4 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/PlainSchemaDAO.java
@@ -18,19 +18,9 @@
  */
 package org.apache.syncope.core.persistence.api.dao;
 
-import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.PlainAttr;
 import org.apache.syncope.core.persistence.api.entity.PlainSchema;
 
-public interface PlainSchemaDAO extends DAO<PlainSchema, String> {
+public interface PlainSchemaDAO extends SchemaDAO<PlainSchema, PlainAttr<?>> {
 
-    PlainSchema find(String name);
-
-    List<PlainSchema> findAll();
-
-    <T extends PlainAttr<?>> List<T> findAttrs(PlainSchema schema, Class<T> reference);
-
-    PlainSchema save(PlainSchema derSchema);
-
-    void delete(String key);
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SchemaDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SchemaDAO.java
new file mode 100644
index 0000000..4b36115
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/SchemaDAO.java
@@ -0,0 +1,39 @@
+/*
+ * 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.api.dao;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.api.entity.Attr;
+import org.apache.syncope.core.persistence.api.entity.Schema;
+
+public interface SchemaDAO<S extends Schema, A extends Attr<S, ?>> extends DAO<S, String> {
+
+    S find(String name);
+
+    List<S> findByAnyTypeClass(AnyTypeClass anyTypeClass);
+
+    List<S> findAll();
+
+    <T extends A> List<T> findAttrs(S schema, Class<T> reference);
+
+    S save(S derSchema);
+
+    void delete(String key);
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java
index fc6c7fa..2bcd81c 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/VirSchemaDAO.java
@@ -18,19 +18,8 @@
  */
 package org.apache.syncope.core.persistence.api.dao;
 
-import java.util.List;
 import org.apache.syncope.core.persistence.api.entity.VirAttr;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 
-public interface VirSchemaDAO extends DAO<VirSchema, String> {
-
-    VirSchema find(String name);
-
-    List<VirSchema> findAll();
-
-    <T extends VirAttr<?>> List<T> findAttrs(VirSchema virSchema, Class<T> reference);
-
-    VirSchema save(VirSchema derSchema);
-
-    void delete(String key);
+public interface VirSchemaDAO extends SchemaDAO<VirSchema, VirAttr<?>> {
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Schema.java
----------------------------------------------------------------------
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Schema.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Schema.java
index cef3701..ec6bf50 100644
--- a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Schema.java
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/Schema.java
@@ -22,6 +22,10 @@ import org.apache.syncope.common.lib.types.AttrSchemaType;
 
 public interface Schema extends Entity<String> {
 
+    AnyTypeClass getAnyTypeClass();
+
+    void setAnyTypeClass(AnyTypeClass anyTypeClass);
+
     AttrSchemaType getType();
 
     String getMandatoryCondition();

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
index fd99019..298f5c4 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyObjectDAO.java
@@ -32,14 +32,20 @@ import org.apache.syncope.common.lib.types.Entitlement;
 import org.apache.syncope.core.misc.security.AuthContextUtils;
 import org.apache.syncope.core.misc.security.UnauthorizedException;
 import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyUtils;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
+import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.group.Group;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.user.URelationship;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAARelationship;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAURelationship;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
@@ -47,6 +53,9 @@ import org.springframework.transaction.annotation.Transactional;
 @Repository
 public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObjectDAO {
 
+    @Autowired
+    private GroupDAO groupDAO;
+
     @Override
     protected AnyUtils init() {
         return new JPAAnyUtilsFactory().getInstance(AnyTypeKind.ANY_OBJECT);
@@ -77,6 +86,35 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
     }
 
     @Override
+    public List<ARelationship> findARelationships(final AnyObject anyObject) {
+        TypedQuery<ARelationship> query = entityManager.createQuery(
+                "SELECT e FROM " + JPAARelationship.class.getSimpleName()
+                + " e WHERE e.rightEnd=:anyObject", ARelationship.class);
+        query.setParameter("anyObject", anyObject);
+
+        return query.getResultList();
+    }
+
+    @Override
+    public List<URelationship> findURelationships(final AnyObject anyObject) {
+        TypedQuery<URelationship> query = entityManager.createQuery(
+                "SELECT e FROM " + JPAURelationship.class.getSimpleName()
+                + " e WHERE e.rightEnd=:anyObject", URelationship.class);
+        query.setParameter("anyObject", anyObject);
+
+        return query.getResultList();
+    }
+
+    @Override
+    public AnyObject save(final AnyObject anyObject) {
+        AnyObject merged = super.save(anyObject);
+
+        groupDAO.refreshDynMemberships(merged);
+
+        return merged;
+    }
+
+    @Override
     public void delete(final AnyObject any) {
         for (Group group : findDynGroupMemberships(any)) {
             group.getADynMembership().remove(any);
@@ -90,7 +128,7 @@ public class JPAAnyObjectDAO extends AbstractAnyDAO<AnyObject> implements AnyObj
     public List<Group> findDynGroupMemberships(final AnyObject anyObject) {
         TypedQuery<Group> query = entityManager.createQuery(
                 "SELECT e.group FROM " + JPAADynGroupMembership.class.getSimpleName()
-                + " e WHERE :anyObject MEMBER OF e.members", Group.class);
+                + " e WHERE :anyObject MEMBER OF e.anyObjects", Group.class);
         query.setParameter("anyObject", anyObject);
 
         return query.getResultList();

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
index 4d82d31..3339c9a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
@@ -21,13 +21,34 @@ package org.apache.syncope.core.persistence.jpa.dao;
 import java.util.List;
 import javax.persistence.TypedQuery;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyTypeClass;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 
 @Repository
 public class JPAAnyTypeClassDAO extends AbstractDAO<AnyTypeClass, String> implements AnyTypeClassDAO {
 
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private DerSchemaDAO derSchemaDAO;
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
     @Override
     public AnyTypeClass find(final String key) {
         return entityManager.find(JPAAnyTypeClass.class, key);
@@ -52,6 +73,20 @@ public class JPAAnyTypeClassDAO extends AbstractDAO<AnyTypeClass, String> implem
             return;
         }
 
+        for (PlainSchema schema : plainSchemaDAO.findByAnyTypeClass(anyTypeClass)) {
+            schema.setAnyTypeClass(null);
+        }
+        for (DerSchema schema : derSchemaDAO.findByAnyTypeClass(anyTypeClass)) {
+            schema.setAnyTypeClass(null);
+        }
+        for (VirSchema schema : virSchemaDAO.findByAnyTypeClass(anyTypeClass)) {
+            schema.setAnyTypeClass(null);
+        }
+
+        for (AnyType type : anyTypeDAO.findByTypeClass(anyTypeClass)) {
+            type.remove(anyTypeClass);
+        }
+
         entityManager.remove(anyTypeClass);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
index bbbf859..4342811 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
@@ -23,9 +23,9 @@ import javax.persistence.TypedQuery;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
 import org.springframework.stereotype.Repository;
-import org.springframework.transaction.annotation.Transactional;
 
 @Repository
 public class JPAAnyTypeDAO extends AbstractDAO<AnyType, String> implements AnyTypeDAO {
@@ -35,27 +35,25 @@ public class JPAAnyTypeDAO extends AbstractDAO<AnyType, String> implements AnyTy
         return entityManager.find(JPAAnyType.class, key);
     }
 
-    private AnyType find(final AnyTypeKind typeKind) {
-        AnyType anyType = find(typeKind.name());
-        if (anyType == null) {
-            anyType = new JPAAnyType();
-            anyType.setKey(typeKind.name());
-            anyType.setKind(typeKind);
-            anyType = save(anyType);
-        }
-        return anyType;
-    }
-
-    @Transactional(readOnly = false)
     @Override
     public AnyType findUser() {
-        return find(AnyTypeKind.USER);
+        return find(AnyTypeKind.USER.name());
     }
 
-    @Transactional(readOnly = false)
     @Override
     public AnyType findGroup() {
-        return find(AnyTypeKind.GROUP);
+        return find(AnyTypeKind.GROUP.name());
+    }
+
+    public List<AnyType> findByTypeClass(final AnyTypeClass anyTypeClass) {
+        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+                append(JPAAnyType.class.getSimpleName()).
+                append(" e WHERE :anyTypeClass MEMBER OF e.classes");
+
+        TypedQuery<AnyType> query = entityManager.createQuery(queryString.toString(), AnyType.class);
+        query.setParameter("anyTypeClass", anyTypeClass);
+
+        return query.getResultList();
     }
 
     @Override
@@ -77,6 +75,10 @@ public class JPAAnyTypeDAO extends AbstractDAO<AnyType, String> implements AnyTy
             return;
         }
 
+        if (anyType.equals(findUser()) || anyType.equals(findGroup())) {
+            throw new IllegalArgumentException(key + " cannot be deleted");
+        }
+
         entityManager.remove(anyType);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
index c3c10bf..a849ef5 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
@@ -24,6 +24,7 @@ import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.dao.DerAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
 import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 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.DerAttr;
@@ -48,6 +49,18 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
     }
 
     @Override
+    public List<DerSchema> findByAnyTypeClass(final AnyTypeClass anyTypeClass) {
+        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+                append(JPADerSchema.class.getSimpleName()).
+                append(" e WHERE e.anyTypeClass=:anyTypeClass");
+
+        TypedQuery<DerSchema> query = entityManager.createQuery(queryString.toString(), DerSchema.class);
+        query.setParameter("anyTypeClass", anyTypeClass);
+
+        return query.getResultList();
+    }
+
+    @Override
     public List<DerSchema> findAll() {
         TypedQuery<DerSchema> query = entityManager.createQuery(
                 "SELECT e FROM " + JPADerSchema.class.getSimpleName() + " e", DerSchema.class);
@@ -56,7 +69,7 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
 
     @Override
     public <T extends DerAttr<?>> List<T> findAttrs(final DerSchema schema, final Class<T> reference) {
-        final StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
                 append(((JPADerAttrDAO) derAttrDAO).getJPAEntityReference(reference).getSimpleName()).
                 append(" e WHERE e.schema=:schema");
 
@@ -89,6 +102,8 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
             resourceDAO.deleteMapping(key, anyUtils.derIntMappingType());
         }
 
+        schema.getAnyTypeClass().remove(schema);
+
         entityManager.remove(schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
index a922946..50865c3 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
@@ -24,6 +24,7 @@ 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.PlainAttrDAO;
 import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 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.PlainAttr;
@@ -48,6 +49,18 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
     }
 
     @Override
+    public List<PlainSchema> findByAnyTypeClass(final AnyTypeClass anyTypeClass) {
+        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+                append(JPAPlainSchema.class.getSimpleName()).
+                append(" e WHERE e.anyTypeClass=:anyTypeClass");
+
+        TypedQuery<PlainSchema> query = entityManager.createQuery(queryString.toString(), PlainSchema.class);
+        query.setParameter("anyTypeClass", anyTypeClass);
+
+        return query.getResultList();
+    }
+
+    @Override
     public List<PlainSchema> findAll() {
         TypedQuery<PlainSchema> query = entityManager.createQuery(
                 "SELECT e FROM " + JPAPlainSchema.class.getSimpleName() + " e", PlainSchema.class);
@@ -89,6 +102,8 @@ public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implemen
             resourceDAO.deleteMapping(key, anyUtils.plainIntMappingType());
         }
 
+        schema.getAnyTypeClass().remove(schema);
+
         entityManager.remove(schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 8c6aaa7..7045ddc 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
@@ -45,7 +45,6 @@ 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.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;
@@ -152,11 +151,7 @@ public class JPAUserDAO extends AbstractAnyDAO<User> implements UserDAO {
 
     @Override
     public User save(final User user) {
-        User merged = entityManager.merge(user);
-        for (UVirAttr virAttr : merged.getVirAttrs()) {
-            virAttr.getValues().clear();
-            virAttr.getValues().addAll(user.getVirAttr(virAttr.getSchema().getKey()).getValues());
-        }
+        User merged = super.save(user);
 
         roleDAO.refreshDynMemberships(merged);
         groupDAO.refreshDynMemberships(merged);

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/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 ed4f6b6..cc4ffe4 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
@@ -24,6 +24,7 @@ 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.AnyTypeClass;
 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;
@@ -48,6 +49,18 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
     }
 
     @Override
+    public List<VirSchema> findByAnyTypeClass(final AnyTypeClass anyTypeClass) {
+        StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+                append(JPAVirSchema.class.getSimpleName()).
+                append(" e WHERE e.anyTypeClass=:anyTypeClass");
+
+        TypedQuery<VirSchema> query = entityManager.createQuery(queryString.toString(), VirSchema.class);
+        query.setParameter("anyTypeClass", anyTypeClass);
+
+        return query.getResultList();
+    }
+
+    @Override
     public List<VirSchema> findAll() {
         TypedQuery<VirSchema> query = entityManager.createQuery(
                 "SELECT e FROM " + JPAVirSchema.class.getSimpleName() + " e", VirSchema.class);
@@ -89,6 +102,8 @@ public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements V
             resourceDAO.deleteMapping(key, anyUtils.virIntMappingType());
         }
 
+        schema.getAnyTypeClass().remove(schema);
+
         entityManager.remove(schema);
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyType.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyType.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyType.java
index 2615520..d50cdba 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyType.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyType.java
@@ -34,9 +34,11 @@ import javax.validation.constraints.NotNull;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.jpa.validation.entity.AnyTypeCheck;
 
 @Entity
 @Table(name = JPAAnyType.TABLE)
+@AnyTypeCheck
 @Cacheable
 public class JPAAnyType extends AbstractEntity<String> implements AnyType {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java
index 5c52097..e4f0db9 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTypeClass.java
@@ -21,12 +21,9 @@ package org.apache.syncope.core.persistence.jpa.entity;
 import java.util.ArrayList;
 import java.util.List;
 import javax.persistence.Cacheable;
-import javax.persistence.CascadeType;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.JoinTable;
 import javax.persistence.OneToMany;
 import javax.persistence.Table;
 import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
@@ -46,25 +43,13 @@ public class JPAAnyTypeClass extends AbstractEntity<String> implements AnyTypeCl
     @Id
     private String name;
 
-    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
-    @JoinTable(joinColumns =
-            @JoinColumn(name = "anyTypeClass_name"),
-            inverseJoinColumns =
-            @JoinColumn(name = "plainSchema_name"))
+    @OneToMany(fetch = FetchType.EAGER, mappedBy = "anyTypeClass")
     private List<JPAPlainSchema> plainSchemas = new ArrayList<>();
 
-    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
-    @JoinTable(joinColumns =
-            @JoinColumn(name = "anyTypeClass_name"),
-            inverseJoinColumns =
-            @JoinColumn(name = "derSchema_name"))
+    @OneToMany(fetch = FetchType.EAGER, mappedBy = "anyTypeClass")
     private List<JPADerSchema> derSchemas = new ArrayList<>();
 
-    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
-    @JoinTable(joinColumns =
-            @JoinColumn(name = "anyTypeClass_name"),
-            inverseJoinColumns =
-            @JoinColumn(name = "virSchema_name"))
+    @OneToMany(fetch = FetchType.EAGER, mappedBy = "anyTypeClass")
     private List<JPAVirSchema> virSchemas = new ArrayList<>();
 
     @Override
@@ -102,7 +87,7 @@ public class JPAAnyTypeClass extends AbstractEntity<String> implements AnyTypeCl
 
     @Override
     public boolean remove(final DerSchema facet) {
-        checkType(facet, JPAPlainSchema.class);
+        checkType(facet, JPADerSchema.class);
         return this.derSchemas.remove((JPADerSchema) facet);
     }
 
@@ -119,7 +104,7 @@ public class JPAAnyTypeClass extends AbstractEntity<String> implements AnyTypeCl
 
     @Override
     public boolean remove(final VirSchema facet) {
-        checkType(facet, JPAPlainSchema.class);
+        checkType(facet, JPAVirSchema.class);
         return this.virSchemas.remove((JPAVirSchema) facet);
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADerSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADerSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADerSchema.java
index 0b9a31b..62fc5d6 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADerSchema.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPADerSchema.java
@@ -22,8 +22,10 @@ import javax.persistence.Cacheable;
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.Id;
+import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
 import org.apache.syncope.core.persistence.jpa.validation.entity.SchemaNameCheck;
 
@@ -40,6 +42,9 @@ public class JPADerSchema extends AbstractEntity<String> implements DerSchema {
     @Id
     private String name;
 
+    @OneToOne
+    private JPAAnyTypeClass anyTypeClass;
+
     @Column(nullable = false)
     private String expression;
 
@@ -54,6 +59,17 @@ public class JPADerSchema extends AbstractEntity<String> implements DerSchema {
     }
 
     @Override
+    public AnyTypeClass getAnyTypeClass() {
+        return anyTypeClass;
+    }
+
+    @Override
+    public void setAnyTypeClass(final AnyTypeClass anyTypeClass) {
+        checkType(anyTypeClass, JPAAnyTypeClass.class);
+        this.anyTypeClass = (JPAAnyTypeClass) anyTypeClass;
+    }
+
+    @Override
     public String getExpression() {
         return expression;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
index 92f9855..6a152b0 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
@@ -22,6 +22,8 @@ import org.apache.syncope.core.persistence.jpa.entity.user.JPADynRoleMembership;
 import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
 import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
 import org.apache.syncope.core.persistence.api.entity.AnyAbout;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.ConnInstance;
 import org.apache.syncope.core.persistence.api.entity.ConnPoolConf;
 import org.apache.syncope.core.persistence.api.entity.DerSchema;
@@ -43,7 +45,11 @@ import org.apache.syncope.core.persistence.api.entity.SyncPolicy;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership;
 import org.apache.syncope.core.persistence.api.entity.anyobject.AMembership;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttrValue;
 import org.apache.syncope.core.persistence.api.entity.anyobject.ARelationship;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrValue;
@@ -77,7 +83,11 @@ 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.anyobject.JPAADynGroupMembership;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttr;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAPlainAttrValue;
 import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAARelationship;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAnyObject;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttr;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrUniqueValue;
 import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrValue;
@@ -128,6 +138,12 @@ public class JPAEntityFactory implements EntityFactory {
             result = (T) new JPAPushPolicy();
         } else if (reference.equals(SyncPolicy.class)) {
             result = (T) new JPASyncPolicy();
+        } else if (reference.equals(AnyTypeClass.class)) {
+            result = (T) new JPAAnyTypeClass();
+        } else if (reference.equals(AnyType.class)) {
+            result = (T) new JPAAnyType();
+        } else if (reference.equals(AnyObject.class)) {
+            result = (T) new JPAAnyObject();
         } else if (reference.equals(Role.class)) {
             result = (T) new JPARole();
         } else if (reference.equals(User.class)) {
@@ -156,6 +172,12 @@ public class JPAEntityFactory implements EntityFactory {
             result = (T) new JPAConnInstance();
         } else if (reference.equals(PlainSchema.class)) {
             result = (T) new JPAPlainSchema();
+        } else if (reference.equals(APlainAttr.class)) {
+            result = (T) new JPAAPlainAttr();
+        } else if (reference.equals(APlainAttrValue.class)) {
+            result = (T) new JPAAPlainAttrValue();
+        } else if (reference.equals(APlainAttrUniqueValue.class)) {
+            result = (T) new JPAAPlainAttrUniqueValue();
         } else if (reference.equals(UPlainAttr.class)) {
             result = (T) new JPAUPlainAttr();
         } else if (reference.equals(UPlainAttrValue.class)) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAPlainSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAPlainSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAPlainSchema.java
index 5f767e0..d4935e9 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAPlainSchema.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAPlainSchema.java
@@ -26,6 +26,7 @@ import javax.persistence.EnumType;
 import javax.persistence.Enumerated;
 import javax.persistence.Id;
 import javax.persistence.Lob;
+import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.persistence.Transient;
 import javax.validation.constraints.Max;
@@ -34,6 +35,7 @@ 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.AnyTypeClass;
 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;
@@ -52,6 +54,9 @@ public class JPAPlainSchema extends AbstractEntity<String> implements PlainSchem
     @Id
     private String name;
 
+    @OneToOne
+    private JPAAnyTypeClass anyTypeClass;
+
     @Column(nullable = false)
     @Enumerated(EnumType.STRING)
     private AttrSchemaType type;
@@ -122,6 +127,17 @@ public class JPAPlainSchema extends AbstractEntity<String> implements PlainSchem
     }
 
     @Override
+    public AnyTypeClass getAnyTypeClass() {
+        return anyTypeClass;
+    }
+
+    @Override
+    public void setAnyTypeClass(final AnyTypeClass anyTypeClass) {
+        checkType(anyTypeClass, JPAAnyTypeClass.class);
+        this.anyTypeClass = (JPAAnyTypeClass) anyTypeClass;
+    }
+
+    @Override
     public AttrSchemaType getType() {
         return type;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java
index f7cf717..d268aff 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAVirSchema.java
@@ -22,10 +22,12 @@ import javax.persistence.Basic;
 import javax.persistence.Cacheable;
 import javax.persistence.Entity;
 import javax.persistence.Id;
+import javax.persistence.OneToOne;
 import javax.persistence.Table;
 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.AnyTypeClass;
 import org.apache.syncope.core.persistence.api.entity.VirSchema;
 import org.apache.syncope.core.persistence.jpa.validation.entity.SchemaNameCheck;
 
@@ -42,6 +44,9 @@ public class JPAVirSchema extends AbstractEntity<String> implements VirSchema {
     @Id
     private String name;
 
+    @OneToOne
+    private JPAAnyTypeClass anyTypeClass;
+
     @Basic
     @Min(0)
     @Max(1)
@@ -64,6 +69,17 @@ public class JPAVirSchema extends AbstractEntity<String> implements VirSchema {
     }
 
     @Override
+    public AnyTypeClass getAnyTypeClass() {
+        return anyTypeClass;
+    }
+
+    @Override
+    public void setAnyTypeClass(final AnyTypeClass anyTypeClass) {
+        checkType(anyTypeClass, JPAAnyTypeClass.class);
+        this.anyTypeClass = (JPAAnyTypeClass) anyTypeClass;
+    }
+
+    @Override
     public AttrSchemaType getType() {
         return AttrSchemaType.String;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
index 273b79d..8e13879 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/resource/JPAProvision.java
@@ -27,6 +27,7 @@ import javax.persistence.ManyToOne;
 import javax.persistence.OneToOne;
 import javax.persistence.Table;
 import javax.persistence.UniqueConstraint;
+import javax.validation.constraints.NotNull;
 import org.apache.syncope.core.misc.serialization.POJOHelper;
 import org.apache.syncope.core.persistence.api.entity.AnyType;
 import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
@@ -55,6 +56,7 @@ public class JPAProvision extends AbstractEntity<Long> implements Provision {
     @ManyToOne
     private JPAAnyType anyType;
 
+    @NotNull
     private String objectClass;
 
     @Lob

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyTypeCheck.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyTypeCheck.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyTypeCheck.java
new file mode 100644
index 0000000..957fd71
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyTypeCheck.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = AnyTypeValidator.class)
+@Documented
+public @interface AnyTypeCheck {
+
+    String message() default "{org.apache.syncope.core.persistence.validation.anytype}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyTypeValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyTypeValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyTypeValidator.java
new file mode 100644
index 0000000..5619295
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/AnyTypeValidator.java
@@ -0,0 +1,56 @@
+/*
+ * 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.validation.entity;
+
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+
+public class AnyTypeValidator extends AbstractValidator<AnyTypeCheck, AnyType> {
+
+    @Override
+    public boolean isValid(final AnyType object, final ConstraintValidatorContext context) {
+        context.disableDefaultConstraintViolation();
+
+        boolean isValid;
+        switch (object.getKind()) {
+            case USER:
+                isValid = AnyTypeKind.USER.name().equalsIgnoreCase(object.getKey());
+                break;
+
+            case GROUP:
+                isValid = AnyTypeKind.GROUP.name().equalsIgnoreCase(object.getKey());
+                break;
+
+            case ANY_OBJECT:
+            default:
+                isValid = !AnyTypeKind.USER.name().equalsIgnoreCase(object.getKey())
+                        && !AnyTypeKind.GROUP.name().equalsIgnoreCase(object.getKey());
+        }
+
+        if (!isValid) {
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidAnyType, "Name / kind mismatch")).
+                    addPropertyNode("name").addConstraintViolation();
+        }
+
+        return isValid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
index f888374..9ad2082 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/ExternalResourceValidator.java
@@ -18,6 +18,8 @@
  */
 package org.apache.syncope.core.persistence.jpa.validation.entity;
 
+import java.util.HashSet;
+import java.util.Set;
 import javax.validation.ConstraintValidatorContext;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.Predicate;
@@ -138,12 +140,26 @@ public class ExternalResourceValidator extends AbstractValidator<ExternalResourc
             }
         }
 
-        return CollectionUtils.matchesAll(resource.getProvisions(), new Predicate<Provision>() {
+        final Set<String> objectClasses = new HashSet<>();
+        boolean validMappings = CollectionUtils.matchesAll(resource.getProvisions(),
+                new Predicate<Provision>() {
+
+                    @Override
+                    public boolean evaluate(final Provision provision) {
+                        if (provision.getObjectClass() != null) {
+                            objectClasses.add(provision.getObjectClass().getObjectClassValue());
+                        }
+                        return isValid(provision.getAnyType(), provision.getMapping(), context);
+                    }
+                });
+
+        if (objectClasses.size() < resource.getProvisions().size()) {
+            context.buildConstraintViolationWithTemplate(getTemplate(EntityViolationType.InvalidResource,
+                    "Each provision requires a different ObjectClass")).
+                    addPropertyNode("provisions").addConstraintViolation();
+            return false;
+        }
 
-            @Override
-            public boolean evaluate(final Provision provision) {
-                return isValid(provision.getAnyType(), provision.getMapping(), context);
-            }
-        });
+        return validMappings;
     }
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml b/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
index 9d300d0..746314c 100644
--- a/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
+++ b/core/persistence-jpa/src/main/resources/META-INF/spring-orm.xml
@@ -66,6 +66,15 @@ under the License.
     </attributes>
   </entity>
   
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAAMembership">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_AMembership" strategy="TABLE"/>
+        <table-generator name="SEQ_AMembership" pk-column-value="SEQ_AMembership" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+  
   <entity class="org.apache.syncope.core.persistence.jpa.entity.JPARole">
     <attributes>
       <id name="id">
@@ -83,7 +92,7 @@ under the License.
       </id>
     </attributes>
   </entity>
-  
+
   <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUser">
     <attributes>
       <id name="id">
@@ -102,6 +111,15 @@ under the License.
     </attributes>
   </entity>
   
+  <entity class="org.apache.syncope.core.persistence.jpa.entity.user.JPAUMembership">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_UMembership" strategy="TABLE"/>
+        <table-generator name="SEQ_UMembership" pk-column-value="SEQ_UMembership" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
+  
   <entity class="org.apache.syncope.core.persistence.jpa.entity.group.JPAGroup">
     <attributes>
       <id name="id">

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java
new file mode 100644
index 0000000..e3a4a74
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyObjectTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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 static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class AnyObjectTest extends AbstractTest {
+
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Test
+    public void findAll() {
+        List<AnyObject> list = anyObjectDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 100);
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void find() {
+        AnyObject anyObject = anyObjectDAO.find(2L);
+        assertNotNull(anyObject);
+        assertNotNull(anyObject.getType());
+        assertFalse(anyObject.getType().getClasses().isEmpty());
+    }
+
+    @Test
+    public void save() {
+        AnyObject anyObject = entityFactory.newEntity(AnyObject.class);
+        anyObject.setRealm(realmDAO.find(SyncopeConstants.ROOT_REALM));
+
+        anyObject = anyObjectDAO.save(anyObject);
+        assertNotNull(anyObject);
+    }
+
+    @Test
+    public void delete() {
+        AnyObject anyObject = anyObjectDAO.find(2L);
+        anyObjectDAO.delete(anyObject.getKey());
+
+        AnyObject actual = anyObjectDAO.find(2L);
+        assertNull(actual);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeClassTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeClassTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeClassTest.java
new file mode 100644
index 0000000..c77ea93
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeClassTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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 static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class AnyTypeClassTest extends AbstractTest {
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test
+    public void find() {
+        AnyTypeClass minimalGroup = anyTypeClassDAO.find("minimal group");
+        assertNotNull(minimalGroup);
+
+        assertFalse(minimalGroup.getPlainSchemas().isEmpty());
+        assertFalse(minimalGroup.getDerSchemas().isEmpty());
+        assertFalse(minimalGroup.getVirSchemas().isEmpty());
+    }
+
+    @Test
+    public void findAll() {
+        List<AnyTypeClass> list = anyTypeClassDAO.findAll();
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void save() {
+        AnyTypeClass newClass = entityFactory.newEntity(AnyTypeClass.class);
+        newClass.setKey("new class");
+        newClass.add(plainSchemaDAO.find("firstname"));
+
+        newClass = anyTypeClassDAO.save(newClass);
+        assertNotNull(newClass);
+        assertFalse(newClass.getPlainSchemas().isEmpty());
+        assertTrue(newClass.getDerSchemas().isEmpty());
+        assertTrue(newClass.getVirSchemas().isEmpty());
+    }
+
+    @Test
+    public void delete() {
+        AnyTypeClass minimalUser = anyTypeClassDAO.find("minimal user");
+        assertNotNull(minimalUser);
+
+        anyTypeClassDAO.delete(minimalUser.getKey());
+        assertNull(anyTypeClassDAO.find("minimal user"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
new file mode 100644
index 0000000..2337a32
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/AnyTypeTest.java
@@ -0,0 +1,114 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class AnyTypeTest extends AbstractTest {
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test
+    public void find() {
+        AnyType userType = anyTypeDAO.findUser();
+        assertNotNull(userType);
+        assertEquals(AnyTypeKind.USER, userType.getKind());
+        assertEquals(AnyTypeKind.USER.name(), userType.getKey());
+        assertFalse(userType.getClasses().isEmpty());
+
+        AnyType groupType = anyTypeDAO.findGroup();
+        assertNotNull(groupType);
+        assertEquals(AnyTypeKind.GROUP, groupType.getKind());
+        assertEquals(AnyTypeKind.GROUP.name(), groupType.getKey());
+        assertFalse(groupType.getClasses().isEmpty());
+
+        AnyType otherType = anyTypeDAO.find("OTHER");
+        assertNotNull(otherType);
+        assertEquals(AnyTypeKind.ANY_OBJECT, otherType.getKind());
+        assertEquals("OTHER", otherType.getKey());
+    }
+
+    @Test
+    public void findAll() {
+        List<AnyType> list = anyTypeDAO.findAll();
+        assertFalse(list.isEmpty());
+    }
+
+    @Test
+    public void save() {
+        AnyType newType = entityFactory.newEntity(AnyType.class);
+        newType.setKey("new type");
+        newType.setKind(AnyTypeKind.ANY_OBJECT);
+        newType.add(anyTypeClassDAO.find("generic membership"));
+        newType.add(anyTypeClassDAO.find("csv"));
+
+        newType = anyTypeDAO.save(newType);
+        assertNotNull(newType);
+        assertFalse(newType.getClasses().isEmpty());
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidKind() {
+        AnyType newType = entityFactory.newEntity(AnyType.class);
+        newType.setKey("new type");
+        newType.setKind(AnyTypeKind.USER);
+        anyTypeDAO.save(newType);
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidName() {
+        AnyType newType = entityFactory.newEntity(AnyType.class);
+        newType.setKey("group");
+        newType.setKind(AnyTypeKind.ANY_OBJECT);
+        anyTypeDAO.save(newType);
+    }
+
+    @Test
+    public void delete() {
+        AnyType otherType = anyTypeDAO.find("OTHER");
+        assertNotNull(otherType);
+
+        anyTypeDAO.delete(otherType.getKey());
+        assertNull(anyTypeDAO.find("OTHER"));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void deleteInvalid() {
+        anyTypeDAO.delete(anyTypeDAO.findUser().getKey());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ResourceTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ResourceTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ResourceTest.java
index ad6c37c..5fd6f53 100644
--- a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ResourceTest.java
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/entity/ResourceTest.java
@@ -41,6 +41,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.Mapping;
 import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
 import org.apache.syncope.core.persistence.api.entity.resource.Provision;
 import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.identityconnectors.framework.common.objects.ObjectClass;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
@@ -108,6 +109,7 @@ public class ResourceTest extends AbstractTest {
 
         Provision provision = entityFactory.newEntity(Provision.class);
         provision.setAnyType(anyTypeDAO.findUser());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
         provision.setResource(resource);
         resource.add(provision);
 
@@ -146,6 +148,7 @@ public class ResourceTest extends AbstractTest {
 
         Provision provision = entityFactory.newEntity(Provision.class);
         provision.setAnyType(anyTypeDAO.findUser());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
         provision.setResource(resource);
         resource.add(provision);
 
@@ -159,8 +162,7 @@ public class ResourceTest extends AbstractTest {
         mapping.add(connObjectKey);
 
         // save the resource
-        ExternalResource actual = resourceDAO.save(resource);
-        assertNotNull(actual);
+        resourceDAO.save(resource);
     }
 
     @Test(expected = IllegalArgumentException.class)
@@ -173,6 +175,7 @@ public class ResourceTest extends AbstractTest {
 
         Provision provision = entityFactory.newEntity(Provision.class);
         provision.setAnyType(anyTypeDAO.findUser());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
         provision.setResource(resource);
         resource.add(provision);
 
@@ -186,8 +189,7 @@ public class ResourceTest extends AbstractTest {
         mapping.setConnObjectKeyItem(connObjectKey);
 
         // save the resource
-        ExternalResource actual = resourceDAO.save(resource);
-        assertNotNull(actual);
+        resourceDAO.save(resource);
     }
 
     @Test(expected = InvalidEntityException.class)
@@ -200,6 +202,7 @@ public class ResourceTest extends AbstractTest {
 
         Provision provision = entityFactory.newEntity(Provision.class);
         provision.setAnyType(anyTypeDAO.findUser());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
         provision.setResource(resource);
         resource.add(provision);
 
@@ -218,8 +221,42 @@ public class ResourceTest extends AbstractTest {
         item.setIntMappingType(IntMappingType.UserPlainSchema);
         mapping.add(item);
 
-        ExternalResource actual = resourceDAO.save(resource);
-        assertNotNull(actual);
+        resourceDAO.save(resource);
+    }
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveInvalidProvision() {
+        ExternalResource resource = entityFactory.newEntity(ExternalResource.class);
+        resource.setKey("invalidProvision");
+
+        Provision provision = entityFactory.newEntity(Provision.class);
+        provision.setAnyType(anyTypeDAO.findUser());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
+        provision.setResource(resource);
+        resource.add(provision);
+
+        Mapping mapping = entityFactory.newEntity(Mapping.class);
+        mapping.setProvision(provision);
+        provision.setMapping(mapping);
+
+        MappingItem connObjectKey = entityFactory.newEntity(MappingItem.class);
+        connObjectKey.setExtAttrName("username");
+        connObjectKey.setIntAttrName("fullname");
+        connObjectKey.setIntMappingType(IntMappingType.UserId);
+        connObjectKey.setPurpose(MappingPurpose.BOTH);
+        mapping.setConnObjectKeyItem(connObjectKey);
+
+        provision = entityFactory.newEntity(Provision.class);
+        provision.setAnyType(anyTypeDAO.findGroup());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
+        provision.setResource(resource);
+        resource.add(provision);
+
+        ConnInstance connector = resourceDAO.find("ws-target-resource-1").getConnector();
+        resource.setConnector(connector);
+
+        // save the resource
+        resourceDAO.save(resource);
     }
 
     @Test
@@ -232,6 +269,7 @@ public class ResourceTest extends AbstractTest {
 
         Provision provision = entityFactory.newEntity(Provision.class);
         provision.setAnyType(anyTypeDAO.findUser());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
         provision.setResource(resource);
         resource.add(provision);
 
@@ -312,6 +350,7 @@ public class ResourceTest extends AbstractTest {
 
         Provision provision = entityFactory.newEntity(Provision.class);
         provision.setAnyType(anyTypeDAO.findUser());
+        provision.setObjectClass(ObjectClass.ACCOUNT);
         provision.setResource(resource);
         resource.add(provision);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeClassTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeClassTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeClassTest.java
new file mode 100644
index 0000000..4b5f2f5
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeClassTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.relationship;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import static org.junit.Assert.assertTrue;
+
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class AnyTypeClassTest extends AbstractTest {
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test
+    public void delete() {
+        AnyTypeClass minimalUser = anyTypeClassDAO.find("minimal user");
+        assertNotNull(minimalUser);
+
+        PlainSchema surname = plainSchemaDAO.find("surname");
+        assertNotNull(surname);
+        assertTrue(minimalUser.getPlainSchemas().contains(surname));
+        int before = minimalUser.getPlainSchemas().size();
+
+        plainSchemaDAO.delete("surname");
+
+        anyTypeClassDAO.flush();
+
+        minimalUser = anyTypeClassDAO.find("minimal user");
+        assertNotNull(minimalUser);
+        assertEquals(before, minimalUser.getPlainSchemas().size() + 1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/419fccfe/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.java
new file mode 100644
index 0000000..e6a919d
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/relationship/AnyTypeTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.relationship;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class AnyTypeTest extends AbstractTest {
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test
+    public void delete() {
+        AnyType userType = anyTypeDAO.findUser();
+        assertNotNull(userType);
+
+        AnyTypeClass other = anyTypeClassDAO.find("other");
+        assertNotNull(other);
+        assertTrue(userType.getClasses().contains(other));
+        int before = userType.getClasses().size();
+
+        anyTypeClassDAO.delete("other");
+
+        try {
+        anyTypeDAO.flush();
+        } catch(Exception e) {
+            System.err.println("EEEEEEEEEEEE");
+            e.printStackTrace();
+        }
+        
+        userType = anyTypeDAO.findUser();
+        assertNotNull(userType);
+        assertEquals(before, userType.getClasses().size() + 1);
+    }
+}