http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
new file mode 100644
index 0000000..5385600
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskExecTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Date;
+import java.util.List;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.core.persistence.api.dao.TaskDAO;
+import org.apache.syncope.core.persistence.api.dao.TaskExecDAO;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.persistence.api.entity.task.TaskExec;
+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 TaskExecTest extends AbstractTest {
+
+    @Autowired
+    private TaskExecDAO taskExecDAO;
+
+    @Autowired
+    private TaskDAO taskDAO;
+
+    @Test
+    public void findAll() {
+        List<TaskExec> list = taskExecDAO.findAll(TaskType.PROPAGATION);
+        assertEquals(2, list.size());
+
+        list = taskExecDAO.findAll(TaskType.SCHEDULED);
+        assertTrue(list.isEmpty());
+
+        list = taskExecDAO.findAll(TaskType.SYNCHRONIZATION);
+        assertTrue(list.isEmpty());
+
+        list = taskExecDAO.findAll(TaskType.NOTIFICATION);
+        assertTrue(list.isEmpty());
+    }
+
+    @Test
+    public void findLatestStarted() {
+        PropagationTask task = taskDAO.find(1L);
+        assertNotNull(task);
+
+        TaskExec latestStarted = taskExecDAO.findLatestStarted(task);
+        assertNotNull(latestStarted);
+        assertEquals(Long.valueOf(1L), latestStarted.getKey());
+    }
+
+    @Test
+    public void issueSYNCOPE214() {
+        PropagationTask task = taskDAO.find(1L);
+        assertNotNull(task);
+
+        String faultyMessage = "A faulty message";
+        faultyMessage = faultyMessage.replace('a', '\0');
+
+        TaskExec exec = entityFactory.newEntity(TaskExec.class);
+        exec.setStartDate(new Date());
+        exec.setEndDate(new Date());
+        exec.setStatus(PropagationTaskExecStatus.SUCCESS.name());
+        exec.setMessage(faultyMessage);
+
+        task.addExec(exec);
+        exec.setTask(task);
+
+        exec = taskExecDAO.save(exec);
+        assertNotNull(exec);
+
+        assertEquals(faultyMessage.replace('\0', '\n'), exec.getMessage());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
new file mode 100644
index 0000000..4f4b02c
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/TaskTest.java
@@ -0,0 +1,117 @@
+/*
+ * 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.inner;
+
+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.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.PropagationMode;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.dao.TaskDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import 
org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.AttributeBuilder;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class TaskTest extends AbstractTest {
+
+    @Autowired
+    private TaskDAO taskDAO;
+
+    @Autowired
+    private ExternalResourceDAO resourceDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Test
+    public void findWithoutExecs() {
+        List<PropagationTask> tasks = taskDAO.findToExec(TaskType.PROPAGATION);
+        assertNotNull(tasks);
+        assertEquals(3, tasks.size());
+    }
+
+    @Test
+    public void findAll() {
+        assertEquals(5, taskDAO.findAll(TaskType.PROPAGATION).size());
+        assertEquals(1, taskDAO.findAll(TaskType.NOTIFICATION).size());
+        assertEquals(1, taskDAO.findAll(TaskType.SCHEDULED).size());
+        assertEquals(10, taskDAO.findAll(TaskType.SYNCHRONIZATION).size());
+        assertEquals(11, taskDAO.findAll(TaskType.PUSH).size());
+    }
+
+    @Test
+    public void savePropagationTask() {
+        ExternalResource resource = resourceDAO.find("ws-target-resource-1");
+        assertNotNull(resource);
+
+        User user = userDAO.find(2L);
+        assertNotNull(user);
+
+        PropagationTask task = entityFactory.newEntity(PropagationTask.class);
+        task.setResource(resource);
+        task.setAnyTypeKind(AnyTypeKind.USER);
+        task.setPropagationMode(PropagationMode.TWO_PHASES);
+        task.setPropagationOperation(ResourceOperation.CREATE);
+        task.setConnObjectKey("[email protected]");
+
+        Set<Attribute> attributes = new HashSet<>();
+        attributes.add(AttributeBuilder.build("testAttribute", "testValue1", 
"testValue2"));
+        
attributes.add(AttributeBuilder.buildPassword("password".toCharArray()));
+        task.setAttributes(attributes);
+
+        task = taskDAO.save(task);
+        assertNotNull(task);
+
+        PropagationTask actual = taskDAO.find(task.getKey());
+        assertEquals(task, actual);
+    }
+
+    @Test
+    public void delete() {
+        PropagationTask task = taskDAO.find(1L);
+        assertNotNull(task);
+
+        ExternalResource resource = task.getResource();
+        assertNotNull(resource);
+
+        taskDAO.delete(task);
+        task = taskDAO.find(1L);
+        assertNull(task);
+
+        resource = resourceDAO.find(resource.getKey());
+        assertNotNull(resource);
+        assertFalse(taskDAO.findAll(resource, 
TaskType.PROPAGATION).contains(task));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
new file mode 100644
index 0000000..587f31d
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/UserTest.java
@@ -0,0 +1,241 @@
+/*
+ * 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
+
+import java.util.Date;
+import java.util.List;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import 
org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.apache.syncope.core.misc.policy.InvalidPasswordPolicySpecException;
+import org.apache.syncope.core.misc.security.PasswordGenerator;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class UserTest extends AbstractTest {
+
+    @Autowired
+    private PasswordGenerator passwordGenerator;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Test
+    public void findAll() {
+        List<User> list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 
1, 100);
+        assertEquals("did not get expected number of users ", 5, list.size());
+    }
+
+    @Test
+    public void count() {
+        Integer count = userDAO.count(SyncopeConstants.FULL_ADMIN_REALMS);
+        assertNotNull(count);
+        assertEquals(5, count, 0);
+    }
+
+    @Test
+    public void findAllByPageAndSize() {
+        // get first page
+        List<User> list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 
1, 2);
+        assertEquals("did not get expected number of users ", 2, list.size());
+
+        // get second page
+        list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 2, 2);
+        assertEquals("did not get expected number of users ", 2, list.size());
+
+        // get second page with uncomplete set
+        list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 2, 3);
+        assertEquals("did not get expected number of users ", 2, list.size());
+
+        // get unexistent page
+        list = userDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 3, 2);
+        assertEquals("did not get expected number of users ", 1, list.size());
+    }
+
+    @Test
+    public void findByDerAttributeValue() {
+        final List<User> list = userDAO.findByDerAttrValue("cn", "Vivaldi, 
Antonio");
+        assertEquals("did not get expected number of users ", 1, list.size());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void findByInvalidDerAttrValue() {
+        userDAO.findByDerAttrValue("cn", "Antonio, Maria, Rossi");
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void findByInvalidDerAttrExpression() {
+        userDAO.findByDerAttrValue("noschema", "Antonio, Maria");
+    }
+
+    @Test
+    public void findByAttributeValue() {
+        final UPlainAttrValue fullnameValue = 
entityFactory.newEntity(UPlainAttrValue.class);
+        fullnameValue.setStringValue("Gioacchino Rossini");
+
+        final List<User> list = userDAO.findByAttrValue("fullname", 
fullnameValue);
+        assertEquals("did not get expected number of users ", 1, list.size());
+    }
+
+    @Test
+    public void findByAttributeBooleanValue() {
+        final UPlainAttrValue coolValue = 
entityFactory.newEntity(UPlainAttrValue.class);
+        coolValue.setBooleanValue(true);
+
+        final List<User> list = userDAO.findByAttrValue("cool", coolValue);
+        assertEquals("did not get expected number of users ", 1, list.size());
+    }
+
+    @Test
+    public void findById() {
+        User user = userDAO.find(1L);
+        assertNotNull("did not find expected user", user);
+        user = userDAO.find(3L);
+        assertNotNull("did not find expected user", user);
+        user = userDAO.find(6L);
+        assertNull("found user but did not expect it", user);
+    }
+
+    @Test
+    public void findByUsername() {
+        User user = userDAO.find("rossini");
+        assertNotNull("did not find expected user", user);
+        user = userDAO.find("vivaldi");
+        assertNotNull("did not find expected user", user);
+        user = userDAO.find("user6");
+        assertNull("found user but did not expect it", user);
+    }
+
+    @Test
+    public void save() {
+        User user = entityFactory.newEntity(User.class);
+        user.setUsername("username");
+        user.setRealm(realmDAO.find("/even/two"));
+        user.setCreationDate(new Date());
+
+        user.setPassword("pass", CipherAlgorithm.SHA256);
+
+        try {
+            userDAO.save(user);
+            fail();
+        } catch (InvalidEntityException e) {
+            assertNotNull(e);
+        }
+
+        user.setPassword("password", CipherAlgorithm.SHA256);
+
+        user.setUsername("username!");
+
+        try {
+            userDAO.save(user);
+            fail();
+        } catch (InvalidEntityException e) {
+            assertNotNull(e);
+        }
+
+        user.setUsername("username");
+
+        User actual = userDAO.save(user);
+        assertNotNull("expected save to work", actual);
+        assertEquals(1, actual.getPasswordHistory().size());
+    }
+
+    @Test
+    public void delete() {
+        User user = userDAO.find(3L);
+
+        userDAO.delete(user.getKey());
+
+        User actual = userDAO.find(3L);
+        assertNull("delete did not work", actual);
+    }
+
+    @Test
+    public void issue237() {
+        User user = entityFactory.newEntity(User.class);
+        user.setUsername("username");
+        user.setRealm(realmDAO.find("/even/two"));
+        user.setCreationDate(new Date());
+
+        user.setPassword("password123", CipherAlgorithm.AES);
+
+        User actual = userDAO.save(user);
+        assertNotNull(actual);
+    }
+
+    @Test
+    public void issueSYNCOPE391() {
+        User user = entityFactory.newEntity(User.class);
+        user.setUsername("username");
+        user.setPassword(null, CipherAlgorithm.AES);
+        user.setRealm(realmDAO.find("/even/two"));
+
+        User actual = userDAO.save(user);
+        assertNull(user.getPassword());
+        assertNotNull(actual);
+    }
+
+    @Test
+    public void issueSYNCOPE226() {
+        User user = userDAO.find(5L);
+        String password = "";
+        try {
+            password = passwordGenerator.generate(user);
+        } catch (InvalidPasswordPolicySpecException ex) {
+            fail(ex.getMessage());
+        }
+        assertNotNull(password);
+
+        user.setPassword(password, CipherAlgorithm.AES);
+
+        User actual = userDAO.save(user);
+        assertNotNull(actual);
+    }
+
+    @Test
+    public void testPasswordGenerator() {
+        User user = userDAO.find(5L);
+
+        String password = "";
+        try {
+            password = passwordGenerator.generate(user);
+
+        } catch (InvalidPasswordPolicySpecException ex) {
+            fail(ex.getMessage());
+        }
+        assertNotNull(password);
+        user.setPassword(password, CipherAlgorithm.SHA);
+        userDAO.save(user);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirAttrTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirAttrTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirAttrTest.java
new file mode 100644
index 0000000..95111c6
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirAttrTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+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.VirAttrDAO;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
+import org.apache.syncope.core.persistence.api.entity.group.GVirAttr;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+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.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class VirAttrTest extends AbstractTest {
+
+    @Autowired
+    private VirAttrDAO virAttrDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
+    @Test
+    public void findAll() {
+        List<UVirAttr> list = virAttrDAO.findAll(UVirAttr.class);
+        assertEquals("did not get expected number of derived attributes ", 1, 
list.size());
+    }
+
+    @Test
+    public void findById() {
+        UVirAttr attribute = virAttrDAO.find(100L, UVirAttr.class);
+        assertNotNull("did not find expected attribute schema", attribute);
+    }
+
+    @Test
+    public void saveUVirAttribute() {
+        VirSchema virSchema = virSchemaDAO.find("virtualdata");
+        assertNotNull(virSchema);
+
+        User owner = userDAO.find(3L);
+        assertNotNull("did not get expected user", owner);
+
+        UVirAttr virAttr = entityFactory.newEntity(UVirAttr.class);
+        virAttr.setOwner(owner);
+        virAttr.setSchema(virSchema);
+
+        virAttr = virAttrDAO.save(virAttr);
+
+        UVirAttr actual = virAttrDAO.find(virAttr.getKey(), UVirAttr.class);
+        assertNotNull("expected save to work", actual);
+        assertEquals(virAttr, actual);
+    }
+
+    @Test
+    public void saveGVirAttribute() {
+        VirSchema virSchema = virSchemaDAO.find("rvirtualdata");
+        assertNotNull(virSchema);
+
+        Group owner = groupDAO.find(3L);
+        assertNotNull("did not get expected membership", owner);
+
+        GVirAttr virAttr = entityFactory.newEntity(GVirAttr.class);
+        virAttr.setOwner(owner);
+        virAttr.setSchema(virSchema);
+
+        virAttr = virAttrDAO.save(virAttr);
+
+        GVirAttr actual = virAttrDAO.find(virAttr.getKey(), GVirAttr.class);
+        assertNotNull("expected save to work", actual);
+        assertEquals(virAttr, actual);
+    }
+
+    @Test
+    public void delete() {
+        UVirAttr attribute = virAttrDAO.find(100L, UVirAttr.class);
+        String attributeSchemaName = attribute.getSchema().getKey();
+
+        virAttrDAO.delete(attribute.getKey(), UVirAttr.class);
+
+        UVirAttr actual = virAttrDAO.find(1000L, UVirAttr.class);
+        assertNull("delete did not work", actual);
+
+        VirSchema attributeSchema = virSchemaDAO.find(attributeSchemaName);
+        assertNotNull("user virtual attribute schema deleted " + "when 
deleting values", attributeSchema);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirSchemaTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirSchemaTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirSchemaTest.java
new file mode 100644
index 0000000..fc56739
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/VirSchemaTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import 
org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO;
+import org.apache.syncope.core.persistence.api.entity.VirSchema;
+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 VirSchemaTest extends AbstractTest {
+
+    @Autowired
+    private VirSchemaDAO virSchemaDAO;
+
+    @Test
+    public void findAll() {
+        List<VirSchema> list = virSchemaDAO.findAll();
+        assertEquals(4, list.size());
+    }
+
+    @Test
+    public void findByName() {
+        VirSchema attributeSchema = virSchemaDAO.find("virtualdata");
+        assertNotNull("did not find expected virtual attribute schema", 
attributeSchema);
+    }
+
+    @Test
+    public void save() {
+        VirSchema virtualAttributeSchema = 
entityFactory.newEntity(VirSchema.class);
+        virtualAttributeSchema.setKey("virtual");
+        virtualAttributeSchema.setReadonly(true);
+
+        virSchemaDAO.save(virtualAttributeSchema);
+
+        VirSchema actual = virSchemaDAO.find("virtual");
+        assertNotNull("expected save to work", actual);
+        assertTrue(actual.isReadonly());
+    }
+
+    @Test
+    public void delete() {
+        VirSchema virtualdata = virSchemaDAO.find("virtualdata");
+
+        virSchemaDAO.delete(virtualdata.getKey());
+
+        VirSchema actual = virSchemaDAO.find("virtualdata");
+        assertNull("delete did not work", actual);
+
+        // ------------- //
+        VirSchema rvirtualdata = virSchemaDAO.find("rvirtualdata");
+        assertNotNull(rvirtualdata);
+
+        virSchemaDAO.delete(rvirtualdata.getKey());
+
+        actual = virSchemaDAO.find("rvirtualdata");
+        assertNull("delete did not work", actual);
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        VirSchema schema = entityFactory.newEntity(VirSchema.class);
+        
schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit";);
+
+        try {
+            virSchemaDAO.save(schema);
+            fail();
+        } catch (InvalidEntityException e) {
+            assertTrue(e.hasViolation(EntityViolationType.InvalidName));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnySearchTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnySearchTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnySearchTest.java
new file mode 100644
index 0000000..79f96ed
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnySearchTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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.outer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.Entitlement;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.entity.user.DynRoleMembership;
+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.User;
+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 AnySearchTest extends AbstractTest {
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private AnySearchDAO searchDAO;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
+    private RoleDAO roleDAO;
+
+    @Test
+    public void issueSYNCOPE95() {
+        Set<Group> groups = new 
HashSet<>(groupDAO.findAll(SyncopeConstants.FULL_ADMIN_REALMS, 1, 100));
+        for (Group group : groups) {
+            groupDAO.delete(group.getKey());
+        }
+        groupDAO.flush();
+
+        AttributeCond coolLeafCond = new AttributeCond(AttributeCond.Type.EQ);
+        coolLeafCond.setSchema("cool");
+        coolLeafCond.setExpression("true");
+
+        SearchCond cond = SearchCond.getLeafCond(coolLeafCond);
+        assertTrue(cond.isValid());
+
+        List<User> users = 
searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS, cond, AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+
+        assertEquals(4L, users.get(0).getKey(), 0);
+    }
+
+    @Test
+    public void searchByDynMembership() {
+        // 1. create role with dynamic membership
+        Role role = entityFactory.newEntity(Role.class);
+        role.setName("new");
+        role.addRealm(realmDAO.getRoot());
+        role.addRealm(realmDAO.find("/even/two"));
+        role.getEntitlements().add(Entitlement.LOG_LIST);
+        role.getEntitlements().add(Entitlement.LOG_SET_LEVEL);
+
+        DynRoleMembership dynMembership = 
entityFactory.newEntity(DynRoleMembership.class);
+        dynMembership.setFIQLCond("cool==true");
+        dynMembership.setRole(role);
+
+        role.setDynMembership(dynMembership);
+
+        role = roleDAO.save(role);
+        assertNotNull(role);
+
+        roleDAO.flush();
+
+        // 2. search user by this dynamic role
+        RoleCond roleCond = new RoleCond();
+        roleCond.setRoleKey(role.getKey());
+
+        List<User> users = searchDAO.search(SyncopeConstants.FULL_ADMIN_REALMS,
+                SearchCond.getLeafCond(roleCond), AnyTypeKind.USER);
+        assertNotNull(users);
+        assertEquals(1, users.size());
+        assertEquals(4L, users.get(0).getKey(), 0);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeClassTest.java
new file mode 100644
index 0000000..29b97a3
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/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.outer;
+
+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/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeTest.java
new file mode 100644
index 0000000..b3712d8
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/AnyTypeTest.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.outer;
+
+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");
+
+        anyTypeDAO.flush();
+
+        userType = anyTypeDAO.findUser();
+        assertNotNull(userType);
+        assertEquals(before, userType.getClasses().size() + 1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ConnInstanceTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ConnInstanceTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ConnInstanceTest.java
new file mode 100644
index 0000000..0046679
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ConnInstanceTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.outer;
+
+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 static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import org.apache.syncope.common.lib.types.ConnectorCapability;
+import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.entity.ConnInstance;
+import 
org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+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 ConnInstanceTest extends AbstractTest {
+
+    @Autowired
+    private ExternalResourceDAO resourceDAO;
+
+    @Autowired
+    private ConnInstanceDAO connInstanceDAO;
+
+    @Test
+    public void deleteCascade() {
+        ConnInstance connInstance = connInstanceDAO.find(103L);
+        assertNotNull(connInstance);
+
+        List<? extends ExternalResource> resources = 
connInstance.getResources();
+        assertNotNull(resources);
+        assertFalse(resources.isEmpty());
+
+        connInstanceDAO.delete(connInstance.getKey());
+
+        connInstanceDAO.flush();
+
+        ConnInstance actual = connInstanceDAO.find(103L);
+        assertNull(actual);
+
+        for (ExternalResource resource : resources) {
+            assertNull(resourceDAO.find(resource.getKey()));
+        }
+    }
+
+    /**
+     * Connector change used to miss connector bean registration.
+     *
+     * http://code.google.com/p/syncope/issues/detail?id=176
+     */
+    @Test
+    public void issue176() {
+        ConnInstance connInstance = connInstanceDAO.find(103L);
+        assertNotNull(connInstance);
+        assertTrue(connInstance.getCapabilities().isEmpty());
+
+        List<? extends ExternalResource> resources = 
connInstance.getResources();
+        assertNotNull(resources);
+        assertEquals(4, resources.size());
+        assertTrue(
+                
"ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(0).getKey())
+                || 
"ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(1).getKey())
+                || 
"ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(2).getKey())
+                || 
"ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(3).getKey()));
+
+        connInstance.addCapability(ConnectorCapability.SEARCH);
+
+        connInstance = connInstanceDAO.save(connInstance);
+        assertNotNull(connInstance);
+        assertFalse(connInstance.getCapabilities().isEmpty());
+
+        resources = connInstance.getResources();
+        assertNotNull(resources);
+        assertEquals(4, resources.size());
+        assertTrue(
+                
"ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(0).getKey())
+                || 
"ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(1).getKey())
+                || 
"ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(2).getKey())
+                || 
"ws-target-resource-nopropagation".equalsIgnoreCase(resources.get(3).getKey()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/DerSchemaTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/DerSchemaTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/DerSchemaTest.java
new file mode 100644
index 0000000..fcbe239
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/DerSchemaTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.outer;
+
+import static org.junit.Assert.assertNull;
+
+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.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.DerSchema;
+import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class DerSchemaTest extends AbstractTest {
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private DerSchemaDAO derSchemaDAO;
+
+    @Autowired
+    private DerAttrDAO derAttrDAO;
+
+    @Test
+    public void test() {
+        DerSchema schema = derSchemaDAO.find("cn");
+
+        derSchemaDAO.delete(schema.getKey());
+
+        derSchemaDAO.flush();
+
+        assertNull(derSchemaDAO.find(schema.getKey()));
+        assertNull(derAttrDAO.find(100L, UDerAttr.class));
+        assertNull(userDAO.find(3L).getDerAttr(schema.getKey()));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
new file mode 100644
index 0000000..d208106
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/GroupTest.java
@@ -0,0 +1,328 @@
+/*
+ * 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.outer;
+
+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 static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+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.AnyObjectDAO;
+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.PlainAttrDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import 
org.apache.syncope.core.persistence.api.entity.anyobject.ADynGroupMembership;
+import org.apache.syncope.core.persistence.api.entity.anyobject.APlainAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.group.Group;
+import org.apache.syncope.core.persistence.api.entity.user.UDynGroupMembership;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import 
org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADynGroupMembership;
+import 
org.apache.syncope.core.persistence.jpa.entity.user.JPAUDynGroupMembership;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class GroupTest extends AbstractTest {
+
+    @Autowired
+    private EntityManager entityManager;
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private AnyObjectDAO anyObjectDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private GroupDAO groupDAO;
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private PlainAttrDAO plainAttrDAO;
+
+    @Autowired
+    private PlainAttrValueDAO plainAttrValueDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test(expected = InvalidEntityException.class)
+    public void saveWithTwoOwners() {
+        Group root = groupDAO.find("root");
+        assertNotNull("did not find expected group", root);
+
+        User user = userDAO.find(1L);
+        assertNotNull("did not find expected user", user);
+
+        Group group = entityFactory.newEntity(Group.class);
+        group.setRealm(realmDAO.getRoot());
+        group.setName("error");
+        group.setUserOwner(user);
+        group.setGroupOwner(root);
+
+        groupDAO.save(group);
+    }
+
+    @Test
+    public void findByOwner() {
+        Group group = groupDAO.find(6L);
+        assertNotNull("did not find expected group", group);
+
+        User user = userDAO.find(5L);
+        assertNotNull("did not find expected user", user);
+
+        assertEquals(user, group.getUserOwner());
+
+        List<Group> ownedGroups = groupDAO.findOwnedByUser(user.getKey());
+        assertFalse(ownedGroups.isEmpty());
+        assertEquals(1, ownedGroups.size());
+        assertTrue(ownedGroups.contains(group));
+    }
+
+    @Test
+    public void delete() {
+        groupDAO.delete(2L);
+
+        groupDAO.flush();
+
+        assertNull(groupDAO.find(2L));
+        assertEquals(userDAO.findAllGroups(userDAO.find(2L)).size(), 2);
+        assertNull(plainAttrDAO.find(700L, GPlainAttr.class));
+        assertNull(plainAttrValueDAO.find(41L, GPlainAttrValue.class));
+        assertNotNull(plainSchemaDAO.find("icon"));
+    }
+
+    /**
+     * Static copy of {@link 
org.apache.syncope.core.persistence.jpa.dao.JPAUserDAO} method with same 
signature:
+     * required for avoiding creating of a new transaction - good for general 
use case but bad for the way how
+     * this test class is architected.
+     */
+    private Collection<Group> findDynGroupMemberships(final User user) {
+        TypedQuery<Group> query = entityManager.createQuery(
+                "SELECT e.group FROM " + 
JPAUDynGroupMembership.class.getSimpleName()
+                + " e WHERE :user MEMBER OF e.users", Group.class);
+        query.setParameter("user", user);
+
+        return query.getResultList();
+    }
+
+    @Test
+    public void udynMembership() {
+        // 0. create user matching the condition below
+        User user = entityFactory.newEntity(User.class);
+        user.setUsername("username");
+        user.setRealm(realmDAO.find("/even/two"));
+        user.add(anyTypeClassDAO.find("other"));
+
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setOwner(user);
+        attr.setSchema(plainSchemaDAO.find("cool"));
+        attr.add("true", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        user.add(attr);
+
+        user = userDAO.save(user);
+        Long newUserKey = user.getKey();
+        assertNotNull(newUserKey);
+
+        // 1. create group with dynamic membership
+        Group group = entityFactory.newEntity(Group.class);
+        group.setRealm(realmDAO.getRoot());
+        group.setName("new");
+
+        UDynGroupMembership dynMembership = 
entityFactory.newEntity(UDynGroupMembership.class);
+        dynMembership.setFIQLCond("cool==true");
+        dynMembership.setGroup(group);
+
+        group.setUDynMembership(dynMembership);
+
+        Group actual = groupDAO.save(group);
+        assertNotNull(actual);
+
+        groupDAO.flush();
+
+        // 2. verify that dynamic membership is there
+        actual = groupDAO.find(actual.getKey());
+        assertNotNull(actual);
+        assertNotNull(actual.getUDynMembership());
+        assertNotNull(actual.getUDynMembership().getKey());
+        assertEquals(actual, actual.getUDynMembership().getGroup());
+
+        // 3. verify that expected users have the created group dynamically 
assigned
+        assertEquals(2, actual.getUDynMembership().getMembers().size());
+        assertEquals(new HashSet<>(Arrays.asList(4L, newUserKey)),
+                
CollectionUtils.collect(actual.getUDynMembership().getMembers(), new 
Transformer<User, Long>() {
+
+                    @Override
+                    public Long transform(final User input) {
+                        return input.getKey();
+                    }
+                }, new HashSet<Long>()));
+
+        user = userDAO.find(4L);
+        assertNotNull(user);
+        Collection<Group> dynGroupMemberships = findDynGroupMemberships(user);
+        assertEquals(1, dynGroupMemberships.size());
+        
assertTrue(dynGroupMemberships.contains(actual.getUDynMembership().getGroup()));
+
+        // 4. delete the new user and verify that dynamic membership was 
updated
+        userDAO.delete(newUserKey);
+
+        userDAO.flush();
+
+        actual = groupDAO.find(actual.getKey());
+        assertEquals(1, actual.getUDynMembership().getMembers().size());
+        assertEquals(4L, 
actual.getUDynMembership().getMembers().get(0).getKey(), 0);
+
+        // 5. delete group and verify that dynamic membership was also removed
+        Long dynMembershipKey = actual.getUDynMembership().getKey();
+
+        groupDAO.delete(actual);
+
+        groupDAO.flush();
+
+        assertNull(entityManager.find(JPAUDynGroupMembership.class, 
dynMembershipKey));
+
+        dynGroupMemberships = findDynGroupMemberships(user);
+        assertTrue(dynGroupMemberships.isEmpty());
+    }
+
+    /**
+     * Static copy of {@link 
org.apache.syncope.core.persistence.jpa.dao.JPAAnyObjectDAO} method with same 
signature:
+     * required for avoiding creating of a new transaction - good for general 
use case but bad for the way how
+     * this test class is architected.
+     */
+    private List<Group> findDynGroupMemberships(final AnyObject anyObject) {
+        TypedQuery<Group> query = entityManager.createQuery(
+                "SELECT e.group FROM " + 
JPAADynGroupMembership.class.getSimpleName()
+                + " e WHERE :anyObject MEMBER OF e.anyObjects", Group.class);
+        query.setParameter("anyObject", anyObject);
+
+        return query.getResultList();
+    }
+
+    @Test
+    public void adynMembership() {
+        // 0. create any object matching the condition below
+        AnyObject anyObject = entityFactory.newEntity(AnyObject.class);
+        anyObject.setType(anyTypeDAO.find("PRINTER"));
+        anyObject.setRealm(realmDAO.find("/even/two"));
+
+        APlainAttr attr = entityFactory.newEntity(APlainAttr.class);
+        attr.setOwner(anyObject);
+        attr.setSchema(plainSchemaDAO.find("model"));
+        attr.add("Canon MFC8030", 
anyUtilsFactory.getInstance(AnyTypeKind.ANY_OBJECT));
+        anyObject.add(attr);
+
+        anyObject = anyObjectDAO.save(anyObject);
+        Long newAnyObjectKey = anyObject.getKey();
+        assertNotNull(newAnyObjectKey);
+
+        // 1. create group with dynamic membership
+        Group group = entityFactory.newEntity(Group.class);
+        group.setRealm(realmDAO.getRoot());
+        group.setName("new");
+
+        ADynGroupMembership dynMembership = 
entityFactory.newEntity(ADynGroupMembership.class);
+        dynMembership.setFIQLCond("model==Canon MFC8030");
+        dynMembership.setGroup(group);
+
+        group.setADynMembership(dynMembership);
+
+        Group actual = groupDAO.save(group);
+        assertNotNull(actual);
+
+        groupDAO.flush();
+
+        // 2. verify that dynamic membership is there
+        actual = groupDAO.find(actual.getKey());
+        assertNotNull(actual);
+        assertNotNull(actual.getADynMembership());
+        assertNotNull(actual.getADynMembership().getKey());
+        assertEquals(actual, actual.getADynMembership().getGroup());
+
+        // 3. verify that expected any objects have the created group 
dynamically assigned
+        assertEquals(2, actual.getADynMembership().getMembers().size());
+        assertEquals(new HashSet<>(Arrays.asList(1L, newAnyObjectKey)),
+                
CollectionUtils.collect(actual.getADynMembership().getMembers(), new 
Transformer<AnyObject, Long>() {
+
+                    @Override
+                    public Long transform(final AnyObject input) {
+                        return input.getKey();
+                    }
+                }, new HashSet<Long>()));
+
+        anyObject = anyObjectDAO.find(1L);
+        assertNotNull(anyObject);
+        Collection<Group> dynGroupMemberships = 
findDynGroupMemberships(anyObject);
+        assertEquals(1, dynGroupMemberships.size());
+        
assertTrue(dynGroupMemberships.contains(actual.getADynMembership().getGroup()));
+
+        // 4. delete the new any object and verify that dynamic membership was 
updated
+        anyObjectDAO.delete(newAnyObjectKey);
+
+        anyObjectDAO.flush();
+
+        actual = groupDAO.find(actual.getKey());
+        assertEquals(1, actual.getADynMembership().getMembers().size());
+        assertEquals(1L, 
actual.getADynMembership().getMembers().get(0).getKey(), 0);
+
+        // 5. delete group and verify that dynamic membership was also removed
+        Long dynMembershipKey = actual.getADynMembership().getKey();
+
+        groupDAO.delete(actual);
+
+        groupDAO.flush();
+
+        assertNull(entityManager.find(JPAADynGroupMembership.class, 
dynMembershipKey));
+
+        dynGroupMemberships = findDynGroupMemberships(anyObject);
+        assertTrue(dynGroupMemberships.isEmpty());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainAttrTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainAttrTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainAttrTest.java
new file mode 100644
index 0000000..2e46caf
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainAttrTest.java
@@ -0,0 +1,179 @@
+/*
+ * 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.outer;
+
+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 static org.junit.Assert.assertTrue;
+
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+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.PlainAttrDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainAttrValueDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+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.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.User;
+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 PlainAttrTest extends AbstractTest {
+
+    @Autowired
+    private PlainAttrDAO plainAttrDAO;
+
+    @Autowired
+    private DerAttrDAO derAttrDAO;
+
+    @Autowired
+    private PlainAttrValueDAO plainAttrValueDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private DerSchemaDAO derSchemaDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private AnyTypeClassDAO anyTypeClassDAO;
+
+    @Test
+    public void deleteAttribute() {
+        plainAttrDAO.delete(117L, UPlainAttr.class);
+
+        plainAttrDAO.flush();
+
+        assertNull(plainAttrDAO.find(117L, UPlainAttr.class));
+        assertNull(plainAttrValueDAO.find(28L, UPlainAttrValue.class));
+    }
+
+    @Test
+    public void deleteAttributeValue() {
+        UPlainAttrValue value = plainAttrValueDAO.find(14L, 
UPlainAttrValue.class);
+        int attributeValueNumber = value.getAttr().getValues().size();
+
+        plainAttrValueDAO.delete(value.getKey(), UPlainAttrValue.class);
+
+        plainAttrValueDAO.flush();
+
+        assertNull(plainAttrValueDAO.find(value.getKey(), 
UPlainAttrValue.class));
+
+        UPlainAttr attribute = plainAttrDAO.find(104L, UPlainAttr.class);
+        assertEquals(attribute.getValues().size(), attributeValueNumber - 1);
+    }
+
+    @Test
+    public void checkForEnumType() {
+        User user = userDAO.find(1L);
+        user.setPassword("password123", CipherAlgorithm.SHA);
+        assertNotNull(user);
+
+        AnyTypeClass other = anyTypeClassDAO.find("other");
+
+        PlainSchema color = entityFactory.newEntity(PlainSchema.class);
+        color.setType(AttrSchemaType.Enum);
+        color.setKey("color");
+        color.setEnumerationValues("red" + 
SyncopeConstants.ENUM_VALUES_SEPARATOR + "yellow");
+
+        color = plainSchemaDAO.save(color);
+
+        other.add(color);
+        color.setAnyTypeClass(other);
+
+        plainSchemaDAO.flush();
+
+        color = plainSchemaDAO.find("color");
+        assertNotNull("expected save to work", color);
+        assertEquals(other, color.getAnyTypeClass());
+
+        UPlainAttr attr = entityFactory.newEntity(UPlainAttr.class);
+        attr.setOwner(user);
+        attr.setSchema(color);
+        attr.add("yellow", anyUtilsFactory.getInstance(AnyTypeKind.USER));
+        user.add(attr);
+
+        userDAO.save(user);
+        userDAO.flush();
+
+        user = userDAO.find(1L);
+        assertNotNull(user);
+        assertNotNull(user.getPlainAttr(color.getKey()));
+        assertNotNull(user.getPlainAttr(color.getKey()).getValues());
+        assertEquals(user.getPlainAttr(color.getKey()).getValues().size(), 1);
+    }
+
+    @Test
+    public void derAttrFromSpecialAttrs() {
+        AnyTypeClass other = anyTypeClassDAO.find("other");
+
+        DerSchema sderived = entityFactory.newEntity(DerSchema.class);
+        sderived.setKey("sderived");
+        sderived.setExpression("username + ' - ' + creationDate + '[' + 
failedLogins + ']'");
+
+        sderived = derSchemaDAO.save(sderived);
+
+        derSchemaDAO.flush();
+
+        other.add(sderived);
+        sderived.setAnyTypeClass(other);
+
+        derSchemaDAO.flush();
+
+        sderived = derSchemaDAO.find("sderived");
+        assertNotNull("expected save to work", sderived);
+        assertEquals(other, sderived.getAnyTypeClass());
+
+        User owner = userDAO.find(3L);
+        assertNotNull("did not get expected user", owner);
+
+        UDerAttr derAttr = entityFactory.newEntity(UDerAttr.class);
+        derAttr.setOwner(owner);
+        derAttr.setSchema(sderived);
+
+        derAttr = derAttrDAO.save(derAttr);
+        derAttrDAO.flush();
+
+        derAttr = derAttrDAO.find(derAttr.getKey(), UDerAttr.class);
+        assertNotNull("expected save to work", derAttr);
+
+        String value = derAttr.getValue(owner.getPlainAttrs());
+        assertNotNull(value);
+        assertFalse(value.isEmpty());
+        assertTrue(value.startsWith("vivaldi - 2010-10-20"));
+        assertTrue(value.endsWith("[0]"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
new file mode 100644
index 0000000..0917d27
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/PlainSchemaTest.java
@@ -0,0 +1,170 @@
+/*
+ * 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.outer;
+
+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 static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+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.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import 
org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
+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 PlainSchemaTest extends AbstractTest {
+
+    @Autowired
+    private AnyTypeDAO anyTypeDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Autowired
+    private PlainSchemaDAO plainSchemaDAO;
+
+    @Autowired
+    private PlainAttrDAO plainAttrDAO;
+
+    @Autowired
+    private ExternalResourceDAO resourceDAO;
+
+    @Test
+    public void deleteFullname() {
+        // fullname is mapped as ConnObjectKey for ws-target-resource-2, need 
to swap it otherwise validation errors 
+        // will be raised
+        for (MappingItem item : resourceDAO.find("ws-target-resource-2").
+                getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
+
+            if ("fullname".equals(item.getIntAttrName())) {
+                item.setConnObjectKey(false);
+            } else if ("surname".equals(item.getIntAttrName())) {
+                item.setConnObjectKey(true);
+            }
+        }
+
+        // search for user schema fullname
+        PlainSchema schema = plainSchemaDAO.find("fullname");
+        assertNotNull(schema);
+
+        // check for associated mappings
+        Set<MappingItem> mapItems = new HashSet<>();
+        for (ExternalResource resource : resourceDAO.findAll()) {
+            if (resource.getProvision(anyTypeDAO.findUser()) != null
+                    && 
resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+
+                for (MappingItem mapItem : 
resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
+                    if (schema.getKey().equals(mapItem.getIntAttrName())) {
+                        mapItems.add(mapItem);
+                    }
+                }
+            }
+        }
+        assertFalse(mapItems.isEmpty());
+
+        // delete user schema fullname
+        plainSchemaDAO.delete("fullname");
+
+        plainSchemaDAO.flush();
+
+        // check for schema deletion
+        schema = plainSchemaDAO.find("fullname");
+        assertNull(schema);
+
+        plainSchemaDAO.clear();
+
+        // check for mappings deletion
+        mapItems = new HashSet<>();
+        for (ExternalResource resource : resourceDAO.findAll()) {
+            if (resource.getProvision(anyTypeDAO.findUser()) != null
+                    && 
resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+
+                for (MappingItem mapItem : 
resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
+                    if ("fullname".equals(mapItem.getIntAttrName())) {
+                        mapItems.add(mapItem);
+                    }
+                }
+            }
+        }
+        assertTrue(mapItems.isEmpty());
+
+        assertNull(plainAttrDAO.find(100L, UPlainAttr.class));
+        assertNull(plainAttrDAO.find(300L, UPlainAttr.class));
+        assertNull(userDAO.find(1L).getPlainAttr("fullname"));
+        assertNull(userDAO.find(3L).getPlainAttr("fullname"));
+    }
+
+    @Test
+    public void deleteSurname() {
+        // search for user schema fullname
+        PlainSchema schema = plainSchemaDAO.find("surname");
+        assertNotNull(schema);
+
+        // check for associated mappings
+        Set<MappingItem> mappings = new HashSet<>();
+        for (ExternalResource resource : resourceDAO.findAll()) {
+            if (resource.getProvision(anyTypeDAO.findUser()) != null
+                    && 
resource.getProvision(anyTypeDAO.findUser()).getMapping() != null) {
+
+                for (MappingItem mapItem : 
resource.getProvision(anyTypeDAO.findUser()).getMapping().getItems()) {
+                    if (schema.getKey().equals(mapItem.getIntAttrName())) {
+                        mappings.add(mapItem);
+                    }
+                }
+            }
+        }
+        assertFalse(mappings.isEmpty());
+
+        // delete user schema fullname
+        plainSchemaDAO.delete("surname");
+
+        plainSchemaDAO.flush();
+
+        // check for schema deletion
+        schema = plainSchemaDAO.find("surname");
+        assertNull(schema);
+    }
+
+    @Test
+    public void deleteALong() {
+        assertEquals(6, resourceDAO.find("resource-db-sync").
+                
getProvision(anyTypeDAO.findUser()).getMapping().getItems().size());
+
+        plainSchemaDAO.delete("aLong");
+        assertNull(plainSchemaDAO.find("aLong"));
+
+        plainSchemaDAO.flush();
+
+        assertEquals(5, resourceDAO.find("resource-db-sync").
+                
getProvision(anyTypeDAO.findUser()).getMapping().getItems().size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java
new file mode 100644
index 0000000..d55fa62
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/RealmTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.outer;
+
+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.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.api.entity.Role;
+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 RealmTest extends AbstractTest {
+
+    @Autowired
+    private RealmDAO realmDAO;
+
+    @Autowired
+    private RoleDAO roleDAO;
+
+    @Test
+    public void test() {
+        Realm realm = realmDAO.find("/odd");
+        assertNotNull(realm);
+
+        Role role = roleDAO.find(1L);
+        assertTrue(role.getRealms().contains(realm));
+
+        int beforeSize = role.getRealms().size();
+
+        realmDAO.delete(realm);
+
+        realmDAO.flush();
+
+        role = roleDAO.find(1L);
+        assertEquals(beforeSize - 1, role.getRealms().size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d8927ef4/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ReportTest.java
----------------------------------------------------------------------
diff --git 
a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ReportTest.java
 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ReportTest.java
new file mode 100644
index 0000000..713ea64
--- /dev/null
+++ 
b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/outer/ReportTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.outer;
+
+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.Date;
+import javax.persistence.EntityExistsException;
+import org.apache.syncope.common.lib.types.ReportExecStatus;
+import org.apache.syncope.core.persistence.api.dao.ReportDAO;
+import org.apache.syncope.core.persistence.api.dao.ReportExecDAO;
+import org.apache.syncope.core.persistence.api.entity.Report;
+import org.apache.syncope.core.persistence.api.entity.ReportExec;
+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 ReportTest extends AbstractTest {
+
+    @Autowired
+    private ReportDAO reportDAO;
+
+    @Autowired
+    private ReportExecDAO reportExecDAO;
+
+    @Test
+    public void find() {
+        Report report = reportDAO.find(1L);
+        assertNotNull(report);
+
+        assertNotNull(report.getExecs());
+        assertFalse(report.getExecs().isEmpty());
+        assertEquals(1, report.getExecs().size());
+    }
+
+    @Test(expected = EntityExistsException.class)
+    public void saveWithExistingName() {
+        Report report = reportDAO.find(1L);
+        assertNotNull(report);
+
+        String name = report.getName();
+
+        report = entityFactory.newEntity(Report.class);
+        report.setName(name);
+
+        reportDAO.save(report);
+        reportDAO.flush();
+    }
+
+    @Test
+    public void save() {
+        Report report = reportDAO.find(1L);
+        assertNotNull(report);
+        assertEquals(1, report.getExecs().size());
+
+        ReportExec reportExec = entityFactory.newEntity(ReportExec.class);
+        reportExec.setReport(report);
+        reportExec.setStartDate(new Date());
+        reportExec.setEndDate(new Date());
+        reportExec.setStatus(ReportExecStatus.SUCCESS);
+
+        report.addExec(reportExec);
+
+        reportExec = reportExecDAO.save(reportExec);
+        assertNotNull(reportExec);
+        assertNotNull(reportExec.getKey());
+
+        reportExecDAO.flush();
+
+        report = reportDAO.find(1L);
+        assertNotNull(report);
+        assertEquals(2, report.getExecs().size());
+    }
+
+    @Test
+    public void deleteReport() {
+        reportDAO.delete(1L);
+
+        reportDAO.flush();
+
+        assertNull(reportDAO.find(1L));
+        assertNull(reportExecDAO.find(1L));
+    }
+
+    @Test
+    public void deleteReportExecution() {
+        ReportExec execution = reportExecDAO.find(1L);
+        int executionNumber = execution.getReport().getExecs().size();
+
+        reportExecDAO.delete(1L);
+
+        reportExecDAO.flush();
+
+        assertNull(reportExecDAO.find(1L));
+
+        Report report = reportDAO.find(1L);
+        assertEquals(report.getExecs().size(), executionNumber - 1);
+    }
+}

Reply via email to