| /* |
| * Copyright (c) 1998, 2020 Oracle and/or its affiliates. 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: |
| // Oracle - initial API and implementation from Oracle TopLink |
| |
| package org.eclipse.persistence.testing.tests.jpa.cascadedeletes; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.List; |
| |
| import jakarta.persistence.EntityManager; |
| |
| import junit.framework.*; |
| import org.eclipse.persistence.testing.framework.junit.JUnitTestCase; |
| import org.eclipse.persistence.testing.models.jpa.cascadedeletes.BranchA; |
| import org.eclipse.persistence.testing.models.jpa.cascadedeletes.BranchB; |
| import org.eclipse.persistence.testing.models.jpa.cascadedeletes.CascadeDeleteTableCreator; |
| import org.eclipse.persistence.testing.models.jpa.cascadedeletes.LeafA; |
| import org.eclipse.persistence.testing.models.jpa.cascadedeletes.LeafB; |
| import org.eclipse.persistence.testing.models.jpa.cascadedeletes.MachineState; |
| import org.eclipse.persistence.testing.models.jpa.cascadedeletes.PersistentIdentity; |
| import org.eclipse.persistence.testing.models.jpa.cascadedeletes.RootA; |
| import org.eclipse.persistence.testing.models.jpa.cascadedeletes.ThreadInfo; |
| |
| public class CascadeDeletesJUnitTestSuite extends JUnitTestCase { |
| |
| public CascadeDeletesJUnitTestSuite() { |
| super(); |
| } |
| |
| public CascadeDeletesJUnitTestSuite(String name) { |
| super(name); |
| } |
| |
| public static Test suite() { |
| TestSuite suite = new TestSuite(); |
| suite.setName("CascadeDeletesJUnitTestSuite"); |
| suite.addTest(new CascadeDeletesJUnitTestSuite("testSetup")); |
| suite.addTest(new CascadeDeletesJUnitTestSuite("testDeleteWholeTree")); |
| suite.addTest(new CascadeDeletesJUnitTestSuite("testRemoveMachineState")); |
| suite.addTest(new CascadeDeletesJUnitTestSuite("testDeletePrivateOwned")); |
| suite.addTest(new CascadeDeletesJUnitTestSuite("testDeleteBranchBTree")); |
| suite.addTest(new CascadeDeletesJUnitTestSuite("testDeletePrivateOwnedChild")); |
| return suite; |
| } |
| |
| /** |
| * The setup is done as a test, both to record its failure, and to allow |
| * execution in the server. |
| */ |
| public void testSetup() { |
| new CascadeDeleteTableCreator().replaceTables(JUnitTestCase.getServerSession("cascade-deletes")); |
| clearCache("cascade-deletes"); |
| } |
| |
| public void testRemoveMachineState(){ |
| EntityManager em = createEntityManager("cascade-deletes"); |
| beginTransaction(em); |
| |
| MachineState ms = new MachineState(); |
| ms.setId(1); |
| ms.setThreads(new ArrayList<ThreadInfo>()); |
| ms.getThreads().add(new ThreadInfo(1, "main")); |
| |
| em.persist(ms); |
| |
| commitTransaction(em); |
| |
| beginTransaction(em); |
| |
| ms = em.find(MachineState.class, 1L); |
| |
| em.remove(ms); |
| |
| commitTransaction(em); |
| |
| } |
| |
| public void testDeleteWholeTree() { |
| Collection<PersistentIdentity> allEntities = new ArrayList<PersistentIdentity>(); |
| RootA rootA = createTree(allEntities); |
| |
| EntityManager em = createEntityManager("cascade-deletes"); |
| try { |
| beginTransaction(em); |
| rootA = em.find(RootA.class, rootA.getId()); |
| // :( |
| for (BranchA a : rootA.getBranchAs()) { |
| a.getLeafs().size(); |
| } |
| em.remove(rootA); |
| for (PersistentIdentity entity : allEntities) { |
| assertNull("Contains found removed entity", em.find(entity.getClass(), entity.getId())); |
| } |
| commitTransaction(em); |
| closeEntityManager(em); |
| clearCache("cascade-deletes"); |
| |
| em = createEntityManager("cascade-deletes"); |
| for (PersistentIdentity entity : allEntities) { |
| assertNull("Failed to remove all entities, found entity class: " + entity.getClass() + " with Id: " + entity.getId(), em.find(entity.getClass(), entity.getId())); |
| } |
| closeEntityManager(em); |
| |
| } catch (RuntimeException ex) { |
| if (isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| throw ex; |
| }finally{ |
| deleteTree(); |
| } |
| } |
| |
| public void testDeletePrivateOwned() { |
| Collection<PersistentIdentity> allEntities = new ArrayList<PersistentIdentity>(); |
| RootA rootA = createTree(allEntities); |
| |
| EntityManager em = createEntityManager("cascade-deletes"); |
| try { |
| beginTransaction(em); |
| BranchB branchB = (BranchB) em.createQuery("Select b from BranchB b join b.branchBs bb where bb.leafBs is not empty").getResultList().get(0); |
| BranchB subB = branchB.getBranchBs().get(0); |
| subB.getLeafBs().size(); |
| branchB.getBranchBs().clear(); |
| commitTransaction(em); |
| closeEntityManager(em); |
| clearCache("cascade-deletes"); |
| em = createEntityManager("cascade-deletes"); |
| assertNull("private owned object was not deleted.", em.find(BranchB.class, subB.getId())); |
| assertNotNull("child of PO object was deleted in error", em.find(LeafB.class, subB.getLeafBs().get(0).getId())); |
| |
| |
| |
| } catch (RuntimeException ex) { |
| if (isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| throw ex; |
| }finally{ |
| deleteTree(); |
| } |
| } |
| |
| public void testDeletePrivateOwnedChild() { |
| Collection<PersistentIdentity> allEntities = new ArrayList<PersistentIdentity>(); |
| createTree(allEntities); |
| |
| EntityManager em = createEntityManager("cascade-deletes"); |
| try { |
| beginTransaction(em); |
| RootA rootA = (RootA) em.createQuery("Select r from RootA r join r.branchAs ba where ba.secondSet is not empty").getResultList().get(0); |
| BranchA subA = rootA.getBranchAs().get(0); |
| subA.getLeafs().size(); |
| rootA.getBranchAs().remove(subA); |
| |
| commitTransaction(em); |
| closeEntityManager(em); |
| clearCache("cascade-deletes"); |
| em = createEntityManager("cascade-deletes"); |
| assertNull("private owned object was not deleted.", em.find(BranchA.class, subA.getId())); |
| for (LeafA leafA : subA.getLeafs()){ |
| assertNull("child of PO object was deleted in error", em.find(LeafA.class, leafA.getId())); |
| } |
| |
| |
| } catch (RuntimeException ex) { |
| if (isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| throw ex; |
| }finally{ |
| deleteTree(); |
| } |
| } |
| |
| public void testDeleteBranchBTree() { |
| Collection<PersistentIdentity> allEntities = new ArrayList<PersistentIdentity>(); |
| RootA rootA = createTree(allEntities); |
| |
| EntityManager em = createEntityManager("cascade-deletes"); |
| try { |
| beginTransaction(em); |
| rootA = em.find(RootA.class, rootA.getId()); |
| BranchB removed = rootA.getBranchB(); |
| em.remove(removed); |
| rootA.setBranchB(null); |
| assertFalse("Failed to remove all entities in tree", removed.checkTreeForRemoval(em)); |
| commitTransaction(em); |
| closeEntityManager(em); |
| clearCache("cascade-deletes"); |
| |
| em = createEntityManager("cascade-deletes"); |
| assertFalse("Failed to remove all entities in tree", removed.checkTreeForRemoval(em)); |
| closeEntityManager(em); |
| |
| } catch (RuntimeException ex) { |
| if (isTransactionActive(em)) { |
| rollbackTransaction(em); |
| } |
| closeEntityManager(em); |
| throw ex; |
| }finally{ |
| deleteTree(); |
| } |
| } |
| |
| public RootA createTree(Collection<PersistentIdentity> allEntities) { |
| EntityManager em = createEntityManager("cascade-deletes"); |
| beginTransaction(em); |
| RootA rootA = new RootA(); |
| em.persist(rootA); |
| allEntities.add(rootA); |
| BranchA branchA = new BranchA(); |
| em.persist(branchA); |
| allEntities.add(branchA); |
| BranchA subBranch = new BranchA(); |
| em.persist(subBranch); |
| allEntities.add(subBranch); |
| branchA.setBranchA(subBranch); |
| LeafA leafA = new LeafA(); |
| em.persist(leafA); |
| allEntities.add(leafA); |
| leafA.setBranchA(branchA); |
| branchA.getLeafs().add(leafA); |
| |
| leafA = new LeafA(); |
| em.persist(leafA); |
| allEntities.add(leafA); |
| branchA.getSecondSet().add(leafA); |
| leafA = new LeafA(); |
| em.persist(leafA); |
| allEntities.add(leafA); |
| branchA.getSecondSet().add(leafA); |
| |
| |
| |
| leafA = new LeafA(); |
| em.persist(leafA); |
| allEntities.add(leafA); |
| leafA.setBranchA(branchA); |
| branchA.getLeafs().add(leafA); |
| rootA.getBranchAs().add(branchA); |
| branchA = new BranchA(); |
| em.persist(branchA); |
| allEntities.add(branchA); |
| subBranch = new BranchA(); |
| em.persist(subBranch); |
| allEntities.add(subBranch); |
| branchA.setBranchA(subBranch); |
| leafA = new LeafA(); |
| em.persist(leafA); |
| allEntities.add(leafA); |
| leafA.setBranchA(branchA); |
| branchA.getLeafs().add(leafA); |
| leafA = new LeafA(); |
| em.persist(leafA); |
| allEntities.add(leafA); |
| leafA.setBranchA(branchA); |
| branchA.getLeafs().add(leafA); |
| rootA.getBranchAs().add(branchA); |
| |
| BranchB branchB = new BranchB(); |
| em.persist(branchB); |
| allEntities.add(branchB); |
| rootA.setBranchB(branchB); |
| |
| BranchB subbranchB = new BranchB(); |
| em.persist(subbranchB); |
| allEntities.add(subbranchB); |
| LeafB subbranchBLeafB = new LeafB(); |
| em.persist(subbranchBLeafB); |
| subbranchB.getLeafBs().add(subbranchBLeafB); |
| |
| branchB.getBranchBs().add(subbranchB); |
| subbranchB = new BranchB(); |
| em.persist(subbranchB); |
| allEntities.add(subbranchB); |
| branchB.getBranchBs().add(subbranchB); |
| |
| LeafB leafB = new LeafB(); |
| em.persist(leafB); |
| allEntities.add(leafB); |
| branchB.getLeafBs().add(leafB); |
| leafB = new LeafB(); |
| em.persist(leafB); |
| allEntities.add(leafB); |
| branchB.getLeafBs().add(leafB); |
| commitTransaction(em); |
| closeEntityManager(em); |
| clearCache("cascade-deletes"); |
| return rootA; |
| } |
| |
| public void deleteTree() { |
| EntityManager em = createEntityManager("cascade-deletes"); |
| beginTransaction(em); |
| List<RootA> result = (List<RootA>)em.createQuery("Select r from RootA r").getResultList(); |
| for (RootA root : result){ |
| root.getBranchAs().clear(); |
| root.setBranchB(null); |
| } |
| List<BranchA> result2 = (List<BranchA>)em.createQuery("Select r from BranchA r").getResultList(); |
| for (BranchA root : result2){ |
| root.getLeafs().clear(); |
| root.getSecondSet().clear(); |
| root.setBranchA(null); |
| } |
| List<BranchB> result3 = (List<BranchB>)em.createQuery("Select r from BranchB r").getResultList(); |
| for (BranchB root : result3){ |
| root.getBranchBs().clear(); |
| root.getLeafBs().clear(); |
| } |
| List<LeafA> result4 = (List<LeafA>)em.createQuery("Select r from LeafA r").getResultList(); |
| for (LeafA root : result4){ |
| root.setBranchA(null); |
| } |
| em.flush(); |
| em.createQuery("delete from RootA").executeUpdate(); |
| em.createQuery("delete from BranchA").executeUpdate(); |
| em.createQuery("delete from BranchB").executeUpdate(); |
| em.createQuery("delete from LeafA").executeUpdate(); |
| em.createQuery("delete from LeafB").executeUpdate(); |
| commitTransaction(em); |
| closeEntityManager(em); |
| clearCache("cascade-deletes"); |
| } |
| |
| } |