blob: d2122df6d4e3a25d441219c8be902bcaee67b05a [file] [log] [blame]
/*
* 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.openjpa.persistence.detach;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import org.apache.openjpa.conf.Compatibility;
import org.apache.openjpa.persistence.DetachStateType;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.persistence.test.SingleEMFTestCase;
/**
* Test the various options for openjpa.DetachState with the new DETACH
* cascade option.
*
* @author dianner
* @since 2.0.0
*
*/
public class TestDetachStateCascade extends SingleEMFTestCase {
OpenJPAEntityManager em;
int id = 0;
Compatibility compat;
EntityA entityA;
EntityB entityB;
EntityC entityC;
EntityD entityD;
EntityE entityE;
List<EntityC> list = new ArrayList<>();
Collection<Object> allEntities = new HashSet<>();
@Override
public void setUp() throws Exception {
setUp(org.apache.openjpa.persistence.detach.EntityA.class,
org.apache.openjpa.persistence.detach.EntityB.class,
org.apache.openjpa.persistence.detach.EntityC.class,
org.apache.openjpa.persistence.detach.EntityD.class,
org.apache.openjpa.persistence.detach.EntityE.class);
assertNotNull(emf);
em = emf.createEntityManager();
assertNotNull(em);
compat = emf.getConfiguration().getCompatibilityInstance();
assertNotNull(compat);
compat.setFlushBeforeDetach(true);
compat.setCopyOnDetach(false);
compat.setCascadeWithDetach(false);
id++;
create(id);
em.getTransaction().begin();
em.persist(entityA);
em.getTransaction().commit();
}
private void create(int id) {
entityA = new EntityA(id, "entityA", "top level class");
entityB = new EntityB(id, "entityB");
entityC = new EntityC(id, "entityC");
entityD = new EntityD(id, "entityD");
entityE = new EntityE(id, "entityE");
entityA.setEntityB(entityB);
entityA.setEntityC(entityC);
entityA.setEntityD(entityD);
entityA.setEntityE(entityE);
}
/**
* The default DetachState of LOADED is tested. In this scenario:
* A is the main entity to be detached
* B is loaded and DETACH cascade is specified
* C is loaded but DETACH cascade is NOT specified
* D is not loaded and DETACH cascade is specified
* E is not loaded but DETACH cascade is NOT specified
*/
public void testLoaded() {
em.getTransaction().begin();
// Clear the persistence context so we start fresh
em.persist(entityA);
em.clear();
EntityA eA = em.find(EntityA.class, id); // Loads B and C by default
assertTrue(em.contains(eA));
EntityD eD = em.find(EntityD.class, id); // Load independently
assertTrue(em.contains(eD));
EntityE eE = em.find(EntityE.class, id); // Load independently
assertTrue(em.contains(eE));
em.detach(eA);
assertEquals(id, eA.getId());
assertEquals("entityA", eA.getName());
assertNull(eA.getDescription()); // should not be loaded
assertNotNull(eA.getEntityB());
assertNotNull(eA.getEntityC());
assertNull(eA.getEntityD());
assertNull(eA.getEntityE());
assertTrue(em.isDetached(eA));
assertTrue(em.isDetached(eA.getEntityB()));
assertFalse(em.isDetached(eA.getEntityC()));
assertFalse(em.isDetached(eD));
assertFalse(em.isDetached(eE));
em.getTransaction().commit();
}
/**
* The DetachState of ALL is tested. In this scenario:
* A is the main entity to be detached.
* B, C, D, and E are all loaded
* DETACH cascade is specified for B and D
* DETACH cascade is NOT specified for C and E
*/
public void testDetachStateAll() {
em.setDetachState(DetachStateType.ALL);
em.getTransaction().begin();
// Clear the persistence context so we start fresh
em.persist(entityA);
em.clear();
EntityA eA = em.find(EntityA.class, id);
assertTrue(em.contains(eA));
em.detach(eA);
assertEquals(id, eA.getId());
assertEquals("entityA", eA.getName());
assertNotNull(eA.getDescription());
assertNotNull(eA.getEntityB());
assertNotNull(eA.getEntityC());
assertNotNull(eA.getEntityD());
assertNotNull(eA.getEntityE());
assertTrue(em.isDetached(eA));
assertTrue(em.isDetached(eA.getEntityB()));
assertFalse(em.isDetached(eA.getEntityC()));
assertTrue(em.isDetached(eA.getEntityD()));
assertFalse(em.isDetached(eA.getEntityE()));
em.getTransaction().commit();
}
/**
* The default DetachState of LOADED is tested. In this scenario:
* A is the main entity to be detached
* B is loaded by default and DETACH cascade is specified
* C is loaded by default but DETACH cascade is NOT specified
* D is loaded by fetch plan and DETACH cascade is specified
* E is not loaded but DETACH cascade is NOT specified
*/
public void testDetachStateFetchGroup() {
em.setDetachState(DetachStateType.FETCH_GROUPS);
em.getFetchPlan().addFetchGroup("loadD");
em.getTransaction().begin();
// Clear the persistence context so we start fresh
em.persist(entityA);
em.clear();
EntityA eA = em.find(EntityA.class, id);
assertTrue(em.contains(eA));
EntityE eE = em.find(EntityE.class, id); // Load independently
assertTrue(em.contains(eE));
em.detach(eA);
assertEquals(id, eA.getId());
assertEquals("entityA", eA.getName());
assertNull(eA.getDescription());
assertNotNull(eA.getEntityB());
assertNotNull(eA.getEntityC());
assertNotNull(eA.getEntityD());
assertNull(eA.getEntityE());
assertTrue(em.isDetached(eA));
assertTrue(em.isDetached(eA.getEntityB()));
assertFalse(em.isDetached(eA.getEntityC()));
assertTrue(em.isDetached(eA.getEntityD()));
assertFalse(em.isDetached(eE));
em.getTransaction().commit();
}
}