/*
 * Copyright (c) 2005, 2021 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2005, 2015 SAP. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     SAP - initial API and implementation

package org.eclipse.persistence.testing.tests.wdf.jpa1.entitymanager;

import java.util.Set;

import jakarta.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, Integer.valueOf(child.getId()));
            CascadingNodeDescription managedChildDescription = em.find(CascadingNodeDescription.class, Integer.valueOf(
                    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, Integer.valueOf(parent.getId()));
            CascadingNodeDescription managedParentDescription = em.find(CascadingNodeDescription.class, Integer.valueOf(
                    parentDescription.getId()));
            CascadingNode managedChild = em.find(CascadingNode.class, Integer.valueOf(child.getId()));
            CascadingNodeDescription managedChildDescription = em.find(CascadingNodeDescription.class, Integer.valueOf(
                    childDescription.getId()));
            CascadingNode managedGrandchild = em.find(CascadingNode.class, Integer.valueOf(grandchild.getId()));
            CascadingNodeDescription managedGrandchildDescription = em.find(CascadingNodeDescription.class, Integer.valueOf(
                    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, Integer.valueOf(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, Integer.valueOf(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, Integer.valueOf(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, Integer.valueOf(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, Integer.valueOf(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, Integer.valueOf(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, Integer.valueOf(desc.getId()));
            verify(found == null, "cascading node description with id " + desc.getId() + " found");
        } else {
            throw new IllegalArgumentException("not supported");
        }
    }
}
