blob: 951b7292e5120c81e63925560d5b23e871d67f31 [file] [log] [blame]
/*
* TestFetchGroups.java
*
* Created on October 10, 2006, 5:46 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
/*
* 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.kernel;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.persistence.FetchPlan;
import org.apache.openjpa.persistence.OpenJPAEntityManager;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
import org.apache.openjpa.persistence.kernel.common.apps.AttachA;
import org.apache.openjpa.persistence.kernel.common.apps.AttachB;
import org.apache.openjpa.persistence.kernel.common.apps.AttachC;
import org.apache.openjpa.persistence.kernel.common.apps.AttachD;
import org.apache.openjpa.persistence.kernel.common.apps.AttachE;
import org.apache.openjpa.persistence.kernel.common.apps.AttachF;
import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObject;
import org.apache.openjpa.persistence.kernel.common.apps.
FetchGroupTestObjectChild;
public class TestFetchGroups extends BaseKernelTest {
private int oid1;
private int oid2;
private int oidc1;
public TestFetchGroups(String s) {
super(s);
}
/**
* Creates a new instance of TestFetchGroups
*/
public TestFetchGroups() {
}
@Override
public void setUp() throws Exception {
super.setUp(FetchGroupTestObject.class, FetchGroupTestObjectChild.class,
AttachA.class, AttachB.class, AttachC.class, AttachD.class, AttachE.class, AttachF.class);
FetchGroupTestObject o1 = new FetchGroupTestObject();
// the value that 'a' is set to is important -- TestFetchGroupsExtent
// and TestFetchGroupsQuery rely on this
o1.setA(5);
o1.setB("foo");
//o1.setC (new BigInteger (89));
o1.setD(new Date());
o1.setE("e-foo");
o1.setF("f-foo");
FetchGroupTestObject o2 = new FetchGroupTestObject();
// the value that 'a' is set to is important -- TestFetchGroupsExtent
// and TestFetchGroupsQuery rely on this
o2.setA(3);
o2.setB("bar");
//o2.setC (new BigInteger (13));
o2.setD(new Date());
o2.setE("e-bar");
o2.setF("f-bar");
o2.setG(o1);
o2.setH(o1);
FetchGroupTestObjectChild c1 = new FetchGroupTestObjectChild();
// the value that 'a' is set to is important -- TestFetchGroupsExtent
// and TestFetchGroupsQuery rely on this
c1.setA(4);
c1.setB("child");
c1.setD(new Date());
c1.setE("e-baz");
c1.setF("f-baz");
c1.setG(o1);
c1.setH(o1);
c1.setChildA(1);
c1.setChildB(2);
c1.setChildC(3);
c1.setChildD(4);
OpenJPAEntityManager pm = getPM();
startTx(pm);
pm.persist(o1);
pm.persist(o2);
pm.persist(c1);
endTx(pm);
oid1 = o1.getId();
oid2 = o2.getId();
oidc1 = c1.getId();
endEm(pm);
}
public void testFetchGroupsFromConfiguration() {
Map props = new HashMap();
props.put("openjpa.FetchGroups", "default,fg1,fg2");
OpenJPAEntityManagerFactory factory = getEmf(props);
OpenJPAEntityManager pm = factory.createEntityManager();
checkGroups(pm, new String[]{ "fg1", "fg2" });
factory.close();
}
public void testFetchGroupsNoConfiguration() {
OpenJPAEntityManager pm = getPM();
FetchGroupTestObject o1 = getO1(pm);
FetchGroupTestObject o2 = getO2(pm);
// only field a should be loaded.
checkObject(pm, o1, true, false, false, false, false, false);
// upon loading field b, fields c and d should also be loaded,
// but e and f should not.
o1.getB();
checkObject(pm, o1, true, true, true, true, false, false);
// loading field h should not cause any of the others to be loaded.
assertEquals(o1, o2.getH());
checkObject(pm, o2, true, false, false, false, false, false);
// loading field g should cause e and f to be loaded.
assertEquals(o1, o2.getG());
checkObject(pm, o2, true, false, false, false, true, true);
}
public void testRetrieveAll() {
OpenJPAEntityManager pm = getPM();
FetchGroupTestObject o1 = getO1(pm);
FetchGroupTestObject o2 = getO2(pm);
// only field a should be loaded.
checkObject(pm, o1, true, false, false, false, false, false);
checkObject(pm, o2, true, false, false, false, false, false);
// only field a should be loaded.
pm.retrieve(o1);
checkObject(pm, o1, true, false, false, false, false, false);
// Add groups 1 and 3 to the default fetch configuration.
pm.getFetchPlan().addFetchGroup("g1");
pm.getFetchPlan().addFetchGroup("g3");
// Retrieve o1's "DFG" which will actually do all configured
// fetch groups.
// DFG fields and fields in groups 1 and 3 should be loaded
pm.retrieve(o1);
checkObject(pm, o1, true, true, true, true, false, false);
}
public void testFetchGroupConfiguration() {
OpenJPAEntityManager pm = getPM();
FetchPlan fetch = pm.getFetchPlan();
checkGroups(pm, new String[0]);
fetch.addFetchGroup("foo");
checkGroups(pm, new String[]{ "foo" });
fetch.addFetchGroup("bar");
fetch.addFetchGroup("baz");
checkGroups(pm, new String[]{ "foo", "bar", "baz" });
fetch.addFetchGroup("a");
fetch.addFetchGroup("b");
fetch.addFetchGroup("c");
fetch.addFetchGroup("d");
checkGroups(pm, new String[]
{ "foo", "bar", "baz", "a", "b", "c", "d" });
fetch.removeFetchGroup("bar");
checkGroups(pm, new String[]{ "foo", "baz", "a", "b", "c", "d" });
fetch.removeFetchGroup("baz");
fetch.removeFetchGroup("c");
checkGroups(pm, new String[]{ "foo", "a", "b", "d" });
fetch.clearFetchGroups().addFetchGroup(FetchPlan.GROUP_DEFAULT);
checkGroups(pm, new String[0]);
}
private void checkGroups(OpenJPAEntityManager pm, String[] groups) {
HashSet groupSet = new HashSet(Arrays.asList(groups));
groupSet.add(FetchPlan.GROUP_DEFAULT);
assertEquals("groupSet dont match", groupSet,
new HashSet(pm.getFetchPlan().getFetchGroups()));
}
public void testFetchGroupsChildWithConfiguration() {
OpenJPAEntityManager pm = getPM();
pm.getFetchPlan().addFetchGroup("g1");
pm.getFetchPlan().addFetchGroup("g3");
// get this so that h's value is loaded into cache.
FetchGroupTestObject o1 = getO1(pm);
FetchGroupTestObjectChild c1 = getC1(pm);
// DFG fields and fields in groups 1 and 3 should be loaded
checkChildObject(pm, c1, true, true, true, true, false, false,
true, true, false, true);
// upon accessing field b, nothing should change.
c1.getB();
checkChildObject(pm, c1, true, true, true, true, false, false,
true, true, false, true);
c1.getH();
}
public void testFetchGroupsWithConfiguration() {
OpenJPAEntityManager pm = getPM();
pm.getFetchPlan().addFetchGroup("g1");
pm.getFetchPlan().addFetchGroup("g3");
FetchGroupTestObject o1 = getO1(pm);
FetchGroupTestObject o2 = getO2(pm);
// DFG fields and fields in groups 1 and 3 should be loaded
checkObject(pm, o1, true, true, true, true, false, false);
// upon accessing field b, nothing should change.
o1.getB();
checkObject(pm, o1, true, true, true, true, false, false);
// loading field h should not cause any of the others to be loaded.
assertEquals(o1, o2.getH());
checkObject(pm, o2, true, true, true, true, false, false);
// loading field g should cause e and f to be loaded.
assertEquals(o1, o2.getG());
checkObject(pm, o2, true, true, true, true, true, true);
}
/**
* Tests that relation fields are loaded immediately when
* they are in one of the PM's configured fetch groups.
*/
public void testRelationsLoaded() {
OpenJPAEntityManager pm = getPM();
pm.getFetchPlan().addFetchGroup("g2");
// note: important the o1 is *not* in pm's cache at this point, so that
// we know it takes another datastore trip to get o1
// load o2 and retrieve its state manager
OpenJPAStateManager sm = getStateManager(getO2(pm), pm);
assertNotNull("SM is NULL", sm);
// 'g' is the name of a 1-1 relation field to o1 in configured
// fetch group 'g2'; make sure it is loaded
int field = sm.getMetaData().getField("g").getIndex();
try {
assertTrue(sm.getLoaded().get(field));
assertEquals(oid1,
((FetchGroupTestObject) sm.fetchObjectField(field)).getId());
} catch (junit.framework.AssertionFailedError afe) {
bug(623, afe, "One to one mappings do not work with custom "
+ "fetch groups");
}
}
protected void checkObject(OpenJPAEntityManager pm,
FetchGroupTestObject o, boolean a, boolean b,
boolean c, boolean d, boolean e, boolean f) {
OpenJPAStateManager sm = getStateManager(o, pm);
BitSet loaded = sm.getLoaded();
FieldMetaData[] fmds = sm.getMetaData().getFields();
int i = 0;
for (; i < fmds.length; i++) {
if (fmds[i].getName().equals("a"))
assertEquals(a, loaded.get(i));
else if (fmds[i].getName().equals("b"))
assertEquals(b, loaded.get(i));
else if (fmds[i].getName().equals("c"))
assertEquals(c, loaded.get(i));
else if (fmds[i].getName().equals("d"))
assertEquals(d, loaded.get(i));
else if (fmds[i].getName().equals("e"))
assertEquals(e, loaded.get(i));
else if (fmds[i].getName().equals("f"))
assertEquals(f, loaded.get(i));
}
}
protected void checkChildObject(OpenJPAEntityManager pm,
FetchGroupTestObjectChild o, boolean a, boolean b,
boolean c, boolean d, boolean e, boolean f, boolean childA,
boolean childB, boolean childC, boolean childD) {
checkObject(pm, o, a, b, c, d, e, f);
OpenJPAStateManager sm = getStateManager(o, pm);
BitSet loaded = sm.getLoaded();
FieldMetaData[] fmds = sm.getMetaData().getFields();
int i = 0;
for (; i < fmds.length; i++) {
if (fmds[i].getName().equals("childA"))
assertEquals(childA, loaded.get(i));
else if (fmds[i].getName().equals("childB"))
assertEquals(childB, loaded.get(i));
else if (fmds[i].getName().equals("childC"))
assertEquals(childC, loaded.get(i));
else if (fmds[i].getName().equals("childD"))
assertEquals(childD, loaded.get(i));
}
}
protected FetchGroupTestObject getO1(OpenJPAEntityManager pm) {
return pm.find(FetchGroupTestObject.class, oid1);
}
protected FetchGroupTestObject getO2(OpenJPAEntityManager pm) {
return pm.find(FetchGroupTestObject.class, oid2);
}
protected FetchGroupTestObjectChild getC1(OpenJPAEntityManager pm) {
return pm.find(FetchGroupTestObjectChild.class, oidc1);
}
/**
* Tests that named fetch groups actually bring in the
* managed object.
*/
public void testFetchGroupInstantiated() {
OpenJPAEntityManager pm = getPM();
startTx(pm);
AttachE e = new AttachE();
AttachB b = new AttachB();
e.setB(b);
pm.persist(e);
endTx(pm);
endEm(pm);
pm = getPM();
startTx(pm);
assertSize(0, pm.getManagedObjects());
pm.createExtent(AttachE.class, true).iterator().next();
// make sure relation is not loaded
assertSize(1, pm.getManagedObjects());
rollbackTx(pm);
endEm(pm);
pm = getPM();
startTx(pm);
// now make sure we load relations
pm.getFetchPlan().addFetchGroup("all");
assertSize(0, pm.getManagedObjects());
pm.createExtent(AttachE.class, true).iterator().next();
// make sure relation is loaded
assertSize(2, pm.getManagedObjects());
rollbackTx(pm);
endEm(pm);
}
}