/*******************************************************************************
 * Copyright (c) 2005, 2009 SAP. All rights reserved.
 * This program and the accompanying materials are made available under the 
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
 * which accompanies this distribution. 
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
 * and the Eclipse Distribution License is available at 
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * Contributors:
 *     SAP - initial API and implementation
 ******************************************************************************/

package org.eclipse.persistence.testing.tests.wdf.jpa1.entitymanager;

import java.util.Set;

import javax.persistence.EntityManager;

import org.eclipse.persistence.testing.framework.wdf.JPAEnvironment;
import org.eclipse.persistence.testing.framework.wdf.ToBeInvestigated;
import org.eclipse.persistence.testing.models.wdf.jpa1.node.CascadingNode;
import org.eclipse.persistence.testing.models.wdf.jpa1.node.CascadingNodeDescription;
import org.eclipse.persistence.testing.tests.wdf.jpa1.JPA1Base;
import org.junit.Test;

public class TestCascadeMerge extends JPA1Base {

    @Test
    @ToBeInvestigated
    public void testCascadeNew() {
        /*
         * If X is a new entity instance, a new managed entity instance X' is created and the state of X is copied into the new
         * managed entity instance X'.
         * 
         * For all entities Y referenced by relationships from X having the cascade element value cascade=MERGE or cascade=ALL,
         * Y is merged recursively as Y'. For all such Y referenced by X, X' is set to reference Y'. (Note that if X is managed
         * then X is the same object as X'.)
         */
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            CascadingNode parent = new CascadingNode(1, null);
            CascadingNodeDescription parentDescription = new CascadingNodeDescription(2, null, "new parent");
            parent.setDescription(parentDescription);
            CascadingNode child = new CascadingNode(3, null);
            CascadingNodeDescription childDescription = new CascadingNodeDescription(4, null, "new child");
            child.setDescription(childDescription);
            CascadingNode grandchild = new CascadingNode(5, null);
            CascadingNodeDescription grandchildDescription = new CascadingNodeDescription(6, null, "new grandchild");
            grandchild.setDescription(grandchildDescription);
            parent.addChild(child);
            child.addChild(grandchild);
            env.beginTransaction(em);
            CascadingNode mergedNode = em.merge(parent);
            verify(mergedNode.getId() == parent.getId(), "merged entity has wrong id: expected " + parent.getId() + ", got "
                    + mergedNode.getId());
            verify(mergedNode != parent, "merged entity not a copy");
            verify(em.contains(mergedNode), "merged entity not managed");
            CascadingNodeDescription mergedDescription = mergedNode.getDescription();
            verify(mergedDescription.getId() == parentDescription.getId(), "merged entity has wrong id: expected "
                    + parentDescription.getId() + ", got " + mergedDescription.getId());
            verify(mergedDescription != parentDescription, "merged entity not a copy");
            verify(em.contains(mergedDescription), "merged entity not managed");
            Set<CascadingNode> mergedChildren = mergedNode.getChildren();
            verify(mergedChildren.size() == 1, "Wrong number of children: expected 1, got " + mergedChildren.size());
            for (CascadingNode temp : mergedChildren) {
                mergedNode = temp;
                break;
            }
            verify(mergedNode.getId() == child.getId(), "merged entity has wrong id: expected " + child.getId() + ", got "
                    + mergedNode.getId());
            verify(mergedNode != child, "merged entity not a copy");
            verify(em.contains(mergedNode), "merged entity not managed");
            mergedDescription = mergedNode.getDescription();
            verify(mergedDescription.getId() == childDescription.getId(), "merged entity has wrong id: expected "
                    + childDescription.getId() + ", got " + mergedDescription.getId());
            verify(mergedDescription != childDescription, "merged entity not a copy");
            verify(em.contains(mergedDescription), "merged entity not managed");
            mergedChildren = mergedNode.getChildren();
            verify(mergedChildren.size() == 1, "Wrong number of children: expected 1, got " + mergedChildren.size());
            for (CascadingNode temp : mergedChildren) {
                mergedNode = temp;
                break;
            }
            verify(mergedNode.getId() == grandchild.getId(), "merged entity has wrong id: expected " + grandchild.getId()
                    + ", got " + mergedNode.getId());
            verify(mergedNode != grandchild, "merged entity not a copy");
            verify(em.contains(mergedNode), "merged entity not managed");
            mergedDescription = mergedNode.getDescription();
            verify(mergedDescription.getId() == grandchildDescription.getId(), "merged entity has wrong id: expected "
                    + grandchildDescription.getId() + ", got " + mergedDescription.getId());
            verify(mergedDescription != grandchildDescription, "merged entity not a copy");
            verify(em.contains(mergedDescription), "merged entity not managed");
            mergedChildren = mergedNode.getChildren();
            verify(mergedChildren == null, "merged entity has children");
            env.commitTransactionAndClear(em);
            verifyExistence(em, parent);
            verifyExistence(em, parentDescription);
            verifyExistence(em, child);
            verifyExistence(em, childDescription);
            verifyExistence(em, grandchild);
            verifyExistence(em, grandchildDescription);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    @ToBeInvestigated
    public void testCascadeDetached() {
        /*
         * If X is a detached entity, the state of X is copied onto a pre-existing managed entity instance X' of the same
         * identity or a new managed copy X' of X is created.
         * 
         * For all entities Y referenced by relationships from X having the cascade element value cascade=MERGE or cascade=ALL,
         * Y is merged recursively as Y'. For all such Y referenced by X, X' is set to reference Y'. (Note that if X is managed
         * then X is the same object as X'.)
         */
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            // types of being detached:
            // parent, parentDescription: not in persistence context but on db
            // child, childDescription: different object with same pk in persistence context, state FOR_UPDATE
            // grandchild, grandchildDescription: different object with same pk in persistence context, state FOR_INSERT
            CascadingNode parent = new CascadingNode(101, null);
            CascadingNodeDescription parentDescription = new CascadingNodeDescription(102, null, "new parent");
            parent.setDescription(parentDescription);
            CascadingNode child = new CascadingNode(103, null);
            CascadingNodeDescription childDescription = new CascadingNodeDescription(104, null, "new child");
            child.setDescription(childDescription);
            parent.addChild(child);
            env.beginTransaction(em);
            em.persist(parent);
            env.commitTransactionAndClear(em);
            verifyExistence(em, parent);
            verifyExistence(em, parentDescription);
            verifyExistence(em, child);
            verifyExistence(em, childDescription);
            env.beginTransaction(em);
            CascadingNode grandchild = new CascadingNode(105, null);
            CascadingNodeDescription grandchildDescription = new CascadingNodeDescription(106, null, "new grandchild");
            grandchild.setDescription(grandchildDescription);
            child.addChild(grandchild);
            CascadingNode managedChild = em.find(CascadingNode.class, new Integer(child.getId()));
            CascadingNodeDescription managedChildDescription = em.find(CascadingNodeDescription.class, new Integer(
                    childDescription.getId()));
            CascadingNode managedGrandchild = new CascadingNode(grandchild.getId(), null);
            CascadingNodeDescription managedGrandchildDescription = new CascadingNodeDescription(grandchildDescription.getId(),
                    null, "new grandchild");
            managedGrandchild.setDescription(managedGrandchildDescription);
            managedChild.addChild(managedGrandchild);
            em.persist(managedGrandchild);
            verify(!em.contains(parent), "parent is managed");
            verify(!em.contains(parentDescription), "parentDescription is managed");
            verify(!em.contains(child), "child is managed");
            verify(!em.contains(childDescription), "childDescription is managed");
            verify(!em.contains(grandchild), "grandchild is managed");
            verify(!em.contains(grandchildDescription), "grandchildDescription is managed");
            verify(em.contains(managedChild), "managedChild is not managed");
            verify(em.contains(managedChildDescription), "managedChildDescription is not managed");
            verify(em.contains(managedGrandchild), "managedGrandchild is not managed");
            verify(em.contains(managedGrandchildDescription), "managedGrandchildDescription is not managed");
            // setup complete
            CascadingNode mergedNode = em.merge(parent);
            verify(mergedNode.getId() == parent.getId(), "merged entity has wrong id: expected " + parent.getId() + ", got "
                    + mergedNode.getId());
            verify(mergedNode != parent, "merged entity not a copy");
            verify(em.contains(mergedNode), "merged entity not managed");
            CascadingNodeDescription mergedDescription = mergedNode.getDescription();
            verify(mergedDescription.getId() == parentDescription.getId(), "merged entity has wrong id: expected "
                    + parentDescription.getId() + ", got " + mergedDescription.getId());
            verify(mergedDescription != parentDescription, "merged entity not a copy");
            verify(em.contains(mergedDescription), "merged entity not managed");
            Set<CascadingNode> mergedChildren = mergedNode.getChildren();
            verify(mergedChildren.size() == 1, "Wrong number of children: expected 1, got " + mergedChildren.size());
            for (CascadingNode temp : mergedChildren) {
                mergedNode = temp;
                break;
            }
            verify(mergedNode.getId() == child.getId(), "merged entity has wrong id: expected " + child.getId() + ", got "
                    + mergedNode.getId());
            verify(mergedNode != child, "merged entity not a copy");
            verify(em.contains(mergedNode), "merged entity not managed");
            mergedDescription = mergedNode.getDescription();
            verify(mergedDescription.getId() == childDescription.getId(), "merged entity has wrong id: expected "
                    + childDescription.getId() + ", got " + mergedDescription.getId());
            verify(mergedDescription != childDescription, "merged entity not a copy");
            verify(em.contains(mergedDescription), "merged entity not managed");
            mergedChildren = mergedNode.getChildren();
            verify(mergedChildren.size() == 1, "Wrong number of children: expected 1, got " + mergedChildren.size());
            for (CascadingNode temp : mergedChildren) {
                mergedNode = temp;
                break;
            }
            verify(mergedNode.getId() == grandchild.getId(), "merged entity has wrong id: expected " + grandchild.getId()
                    + ", got " + mergedNode.getId());
            verify(mergedNode != grandchild, "merged entity not a copy");
            verify(em.contains(mergedNode), "merged entity not managed");
            mergedDescription = mergedNode.getDescription();
            verify(mergedDescription.getId() == grandchildDescription.getId(), "merged entity has wrong id: expected "
                    + grandchildDescription.getId() + ", got " + mergedDescription.getId());
            verify(mergedDescription != grandchildDescription, "merged entity not a copy");
            verify(em.contains(mergedDescription), "merged entity not managed");
            mergedChildren = mergedNode.getChildren();
            verify(mergedChildren == null, "merged entity has children");
            env.commitTransactionAndClear(em);
            verifyExistence(em, parent);
            verifyExistence(em, parentDescription);
            verifyExistence(em, child);
            verifyExistence(em, childDescription);
            verifyExistence(em, grandchild);
            verifyExistence(em, grandchildDescription);
        } finally {
            closeEntityManager(em);
        }
    }

    /**
     * Scenario: Merge a detached entity in case an entity with the same primary key but different object identiy exists in the
     * persistence context <b>in state FOR_DELETE</b>. The specification does not state clearly how to behave in that case. We
     * decided to throw an IllegalArgumentException.
     */
    @Test
    public void testCascadeDetachedRemoved() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            // child, childDescription: different object with same pk in persistence context, state FOR_DELETE
            // others: detached (other types)
            CascadingNode parent = new CascadingNode(201, null);
            CascadingNodeDescription parentDescription = new CascadingNodeDescription(202, null, "new parent");
            parent.setDescription(parentDescription);
            CascadingNode child = new CascadingNode(203, null);
            CascadingNodeDescription childDescription = new CascadingNodeDescription(204, null, "new child");
            child.setDescription(childDescription);
            CascadingNode grandchild = new CascadingNode(205, null);
            CascadingNodeDescription grandchildDescription = new CascadingNodeDescription(206, null, "new grandchild");
            grandchild.setDescription(grandchildDescription);
            parent.addChild(child);
            child.addChild(grandchild);
            env.beginTransaction(em);
            em.persist(parent);
            env.commitTransactionAndClear(em);
            verifyExistence(em, parent);
            verifyExistence(em, parentDescription);
            verifyExistence(em, child);
            verifyExistence(em, childDescription);
            verifyExistence(em, grandchild);
            verifyExistence(em, grandchildDescription);
            env.beginTransaction(em);
            CascadingNode managedParent = em.find(CascadingNode.class, new Integer(parent.getId()));
            CascadingNodeDescription managedParentDescription = em.find(CascadingNodeDescription.class, new Integer(
                    parentDescription.getId()));
            CascadingNode managedChild = em.find(CascadingNode.class, new Integer(child.getId()));
            CascadingNodeDescription managedChildDescription = em.find(CascadingNodeDescription.class, new Integer(
                    childDescription.getId()));
            CascadingNode managedGrandchild = em.find(CascadingNode.class, new Integer(grandchild.getId()));
            CascadingNodeDescription managedGrandchildDescription = em.find(CascadingNodeDescription.class, new Integer(
                    grandchildDescription.getId()));
            managedParent.setChildren(null);
            em.remove(managedChild);
            em.persist(managedGrandchild);
            verify(!em.contains(parent), "parent is managed");
            verify(!em.contains(parentDescription), "parentDescription is managed");
            verify(!em.contains(child), "child is managed");
            verify(!em.contains(childDescription), "childDescription is managed");
            verify(!em.contains(grandchild), "grandchild is managed");
            verify(!em.contains(grandchildDescription), "grandchildDescription is managed");
            verify(em.contains(managedParent), "managedParent is not managed");
            verify(em.contains(managedParentDescription), "managedParentDescription is not managed");
            verify(!em.contains(managedChild), "managedChild is not in state FOR_DELETE");
            verify(!em.contains(managedChildDescription), "managedChildDescription is not in state FOR_DELETE");
            verify(em.contains(managedGrandchild), "managedGrandchild is not managed");
            verify(em.contains(managedGrandchildDescription), "managedGrandchildDescription is not managed");
            // setup complete
            boolean mergeFailed = false;
            try {
                em.merge(parent);
            } catch (IllegalArgumentException e) {
                // $JL-EXC$ this is expected behavior
                mergeFailed = true;
            }
            verify(mergeFailed, "Merge did not throw IllegalArgumentException");
            verify(em.contains(managedParent), "managedParent is not managed");
            verify(em.contains(managedParentDescription), "managedParentDescription is not managed");
            verify(managedParent.getDescription() == managedParentDescription, "managedParent has wrong description");
            Set<CascadingNode> children = managedParent.getChildren();
            verify(children == null || children.size() == 0, "parent has children");
            verify(!em.contains(managedChild), "managedChild is not in state FOR_DELETE");
            verify(!em.contains(managedChildDescription), "managedChildDescription is not in state FOR_DELETE");
            verify(em.contains(managedGrandchild), "managedGrandchild is not managed");
            verify(em.contains(managedGrandchildDescription), "managedGrandchildDescription is not managed");
            verify(managedGrandchild.getDescription() == managedGrandchildDescription,
                    "managedGrandchild has wrong description");
            env.rollbackTransactionAndClear(em);
            verifyExistence(em, parent);
            verifyExistence(em, parentDescription);
            verifyExistence(em, child);
            verifyExistence(em, childDescription);
            verifyExistence(em, grandchild);
            verifyExistence(em, grandchildDescription);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testCircularCascade() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            CascadingNode node1 = new CascadingNode(301, null);
            CascadingNode node2 = new CascadingNode(302, null);
            env.beginTransaction(em);
            em.persist(node1);
            em.persist(node2);
            env.commitTransactionAndClear(em);
            verifyExistence(em, node1);
            verifyExistence(em, node2);
            node1.addChild(node2);
            node2.addChild(node1);
            env.beginTransaction(em);
            CascadingNode mergedNode1 = em.merge(node1);
            verify(em.contains(mergedNode1), "mergedNode1 not managed");
            Set<CascadingNode> childrenOfNode1 = mergedNode1.getChildren();
            verify(childrenOfNode1.size() == 1, "Wrong number of children: expected 1, got " + childrenOfNode1.size());
            CascadingNode childOfNode1 = null;
            for (CascadingNode temp : childrenOfNode1) {
                childOfNode1 = temp;
                break;
            }
            verify(childOfNode1.getId() == node2.getId(), "childOfNode1 has wrong id: " + childOfNode1.getId());
            verify(em.contains(childOfNode1), "childOfNode1 not managed");
            Set<CascadingNode> childrenOfNode2 = childOfNode1.getChildren();
            verify(childrenOfNode2.size() == 1, "Wrong number of children: expected 1, got " + childrenOfNode2.size());
            CascadingNode childOfNode2 = null;
            for (CascadingNode temp : childrenOfNode2) {
                childOfNode2 = temp;
                break;
            }
            verify(childOfNode2 == mergedNode1, "mergedNode1 not child of childOfNode1");
            env.commitTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }

    /**
     * Tests a scenario where two nodes with the same primary key are related to each other, one is managed, the other detached.
     */
    @Test
    public void testCircularCascadeWithSamePks() {
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            CascadingNode managedNode = new CascadingNode(401, null);
            CascadingNode detachedNode = new CascadingNode(managedNode.getId(), null);
            env.beginTransaction(em);
            em.persist(managedNode);
            env.commitTransactionAndClear(em);
            verifyExistence(em, managedNode);
            env.beginTransaction(em);
            managedNode = em.find(CascadingNode.class, new Integer(managedNode.getId()));
            managedNode.addChild(detachedNode);
            detachedNode.addChild(managedNode);
            CascadingNode mergedNode = em.merge(detachedNode);
            verify(em.contains(mergedNode), "mergedNode not managed");
            verify(mergedNode == managedNode, "mergedNode not identical to managedNode");
            Set<CascadingNode> children = mergedNode.getChildren();
            verify(children.size() == 1, "Wrong number of children: expected 1, got " + children.size());
            CascadingNode child = null;
            for (CascadingNode temp : children) {
                child = temp;
                break;
            }
            verify(child == managedNode, "child is not identical to managedNode");
            env.commitTransactionAndClear(em);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testCascadeManaged() {
        /*
         * If X is a managed entity, it is ignored by the merge operation, however, the merge operation is cascaded to entities
         * referenced by relationships from X if these relationships have been annotated with the cascade element value
         * cascade=MERGE or cascade=ALL annotation.
         * 
         * For all entities Y referenced by relationships from X having the cascade element value cascade=MERGE or cascade=ALL,
         * Y is merged recursively as Y'. For all such Y referenced by X, X' is set to reference Y'. (Note that if X is managed
         * then X is the same object as X'.)
         */
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            // states:
            // parent, parentDescription: managed
            // child, childDescription: new
            CascadingNode parent = new CascadingNode(501, null);
            CascadingNodeDescription parentDescription = new CascadingNodeDescription(502, null, "managed parent");
            parent.setDescription(parentDescription);
            CascadingNode child = new CascadingNode(503, null);
            CascadingNodeDescription childDescription = new CascadingNodeDescription(504, null, "new child");
            child.setDescription(childDescription);
            env.beginTransaction(em);
            em.persist(parent);
            env.commitTransactionAndClear(em);
            verifyExistence(em, parent);
            verifyExistence(em, parentDescription);
            verifyAbsence(em, child);
            verifyAbsence(em, childDescription);
            env.beginTransaction(em);
            parent = em.find(CascadingNode.class, new Integer(parent.getId()));
            parent.addChild(child);
            // setup complete
            CascadingNode mergedNode = em.merge(parent);
            verify(mergedNode == parent, "merge returned a copy of the managed entity");
            verify(em.contains(mergedNode), "merged entity not managed");
            CascadingNodeDescription mergedDescription = mergedNode.getDescription();
            verify(mergedDescription.getId() == parentDescription.getId(), "merged entity has wrong id: expected "
                    + parentDescription.getId() + ", got " + mergedNode.getId());
            verify(mergedDescription != parentDescription, "merged entity not a copy");
            verify(em.contains(mergedDescription), "merged entity not managed");
            Set<CascadingNode> mergedChildren = mergedNode.getChildren();
            verify(mergedChildren.size() == 1, "Wrong number of children: expected 1, got " + mergedChildren.size());
            for (CascadingNode temp : mergedChildren) {
                mergedNode = temp;
                break;
            }
            verify(mergedNode.getId() == child.getId(), "merged entity has wrong id: expected " + child.getId() + ", got "
                    + mergedNode.getId());
            verify(mergedNode != child, "merged entity not a copy");
            verify(em.contains(mergedNode), "merged entity not managed");
            mergedDescription = mergedNode.getDescription();
            verify(mergedDescription.getId() == childDescription.getId(), "merged entity has wrong id: expected "
                    + childDescription.getId() + ", got " + mergedNode.getId());
            verify(mergedDescription != childDescription, "merged entity not a copy");
            verify(em.contains(mergedDescription), "merged entity not managed");
            mergedChildren = mergedNode.getChildren();
            verify(mergedChildren == null || mergedChildren.size() == 0, "Node has children, expected none");
            env.commitTransactionAndClear(em);
            verifyExistence(em, parent);
            verifyExistence(em, parentDescription);
            verifyExistence(em, child);
            verifyExistence(em, childDescription);
        } finally {
            closeEntityManager(em);
        }
    }

    @Test
    public void testCascadeRemoved() {
        /*
         * If X is a removed entity instance, an IllegalArgumentException will be thrown by the merge operation (or the
         * transaction commit will fail).
         */
        final JPAEnvironment env = getEnvironment();
        final EntityManager em = env.getEntityManager();
        try {
            // states:
            // parent, parentDescription: new
            // child, childDescription: removed
            CascadingNode parent = new CascadingNode(601, null);
            CascadingNodeDescription parentDescription = new CascadingNodeDescription(602, null, "new parent");
            parent.setDescription(parentDescription);
            CascadingNode child = new CascadingNode(603, null);
            CascadingNodeDescription childDescription = new CascadingNodeDescription(604, null, "removed child");
            child.setDescription(childDescription);
            env.beginTransaction(em);
            em.persist(child);
            env.commitTransactionAndClear(em);
            verifyAbsence(em, parent);
            verifyAbsence(em, parentDescription);
            verifyExistence(em, child);
            verifyExistence(em, childDescription);
            env.beginTransaction(em);
            child = em.find(CascadingNode.class, new Integer(child.getId()));
            em.remove(child);
            parent.addChild(child);
            verify(!em.contains(parent), "parent not new");
            verify(!em.contains(child), "child not removed");
            // setup complete
            boolean mergeFailed = false;
            boolean immediateException = false;
            try {
                em.merge(parent);
            } catch (IllegalArgumentException e) {
                mergeFailed = true;
                immediateException = true;
                verify(!em.contains(parent), "parent not new");
                verify(!em.contains(child), "child not removed");
            }
            if (!immediateException) {
                try {
                    env.commitTransactionAndClear(em);
                } catch (RuntimeException e) {
                    if (!checkForPersistenceException(e)) {
                        throw e;
                    }
                    mergeFailed = true;
                }
            } else {
                env.rollbackTransactionAndClear(em);
            }
            verify(mergeFailed, "merge succeeded on a removed entity");
            verifyAbsence(em, parent);
            verifyAbsence(em, parentDescription);
            verifyExistence(em, child);
            verifyExistence(em, childDescription);
        } finally {
            closeEntityManager(em);
        }
    }

    private void verifyExistence(EntityManager em, Object entity) {
        if (entity instanceof CascadingNode) {
            CascadingNode node = (CascadingNode) entity;
            CascadingNode found = em.find(CascadingNode.class, new Integer(node.getId()));
            verify(found != null, "cascading node with id " + node.getId() + " not found");
        } else if (entity instanceof CascadingNodeDescription) {
            CascadingNodeDescription desc = (CascadingNodeDescription) entity;
            CascadingNodeDescription found = em.find(CascadingNodeDescription.class, new Integer(desc.getId()));
            verify(found != null, "cascading node description with id " + desc.getId() + " not found");
        } else {
            throw new IllegalArgumentException("not supported");
        }
    }

    private void verifyAbsence(EntityManager em, Object entity) {
        if (entity instanceof CascadingNode) {
            CascadingNode node = (CascadingNode) entity;
            CascadingNode found = em.find(CascadingNode.class, new Integer(node.getId()));
            verify(found == null, "cascading node with id " + node.getId() + " found");
        } else if (entity instanceof CascadingNodeDescription) {
            CascadingNodeDescription desc = (CascadingNodeDescription) entity;
            CascadingNodeDescription found = em.find(CascadingNodeDescription.class, new Integer(desc.getId()));
            verify(found == null, "cascading node description with id " + desc.getId() + " found");
        } else {
            throw new IllegalArgumentException("not supported");
        }
    }
}
