001: /*
002: * TestFetchGroups.java
003: *
004: * Created on October 10, 2006, 5:46 PM
005: *
006: * To change this template, choose Tools | Template Manager
007: * and open the template in the editor.
008: */
009:
010: /*
011: * Licensed to the Apache Software Foundation (ASF) under one
012: * or more contributor license agreements. See the NOTICE file
013: * distributed with this work for additional information
014: * regarding copyright ownership. The ASF licenses this file
015: * to you under the Apache License, Version 2.0 (the
016: * "License"); you may not use this file except in compliance
017: * with the License. You may obtain a copy of the License at
018: *
019: * http://www.apache.org/licenses/LICENSE-2.0
020: *
021: * Unless required by applicable law or agreed to in writing,
022: * software distributed under the License is distributed on an
023: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
024: * KIND, either express or implied. See the License for the
025: * specific language governing permissions and limitations
026: * under the License.
027: */
028: package org.apache.openjpa.persistence.kernel;
029:
030: import java.util.Arrays;
031: import java.util.BitSet;
032: import java.util.Date;
033: import java.util.HashMap;
034: import java.util.HashSet;
035: import java.util.Map;
036:
037: import org.apache.openjpa.persistence.kernel.common.apps.AttachA;
038: import org.apache.openjpa.persistence.kernel.common.apps.AttachB;
039: import org.apache.openjpa.persistence.kernel.common.apps.AttachC;
040: import org.apache.openjpa.persistence.kernel.common.apps.AttachD;
041: import org.apache.openjpa.persistence.kernel.common.apps.AttachE;
042: import org.apache.openjpa.persistence.kernel.common.apps.AttachF;
043: import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObject;
044: import org.apache.openjpa.persistence.kernel.common.apps.FetchGroupTestObjectChild;
045:
046: import org.apache.openjpa.kernel.OpenJPAStateManager;
047: import org.apache.openjpa.meta.FieldMetaData;
048: import org.apache.openjpa.persistence.FetchPlan;
049: import org.apache.openjpa.persistence.OpenJPAEntityManager;
050: import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory;
051:
052: public class TestFetchGroups extends BaseKernelTest {
053:
054: private int oid1;
055: private int oid2;
056: private int oidc1;
057:
058: public TestFetchGroups(String s) {
059: super (s);
060: }
061:
062: /**
063: * Creates a new instance of TestFetchGroups
064: */
065: public TestFetchGroups() {
066: }
067:
068: public void setUp() {
069: deleteAll(FetchGroupTestObject.class);
070:
071: FetchGroupTestObject o1 = new FetchGroupTestObject();
072: // the value that 'a' is set to is important -- TestFetchGroupsExtent
073: // and TestFetchGroupsQuery rely on this
074: o1.setA(5);
075: o1.setB("foo");
076: //o1.setC (new BigInteger (89));
077: o1.setD(new Date());
078: o1.setE("e-foo");
079: o1.setF("f-foo");
080:
081: FetchGroupTestObject o2 = new FetchGroupTestObject();
082: // the value that 'a' is set to is important -- TestFetchGroupsExtent
083: // and TestFetchGroupsQuery rely on this
084: o2.setA(3);
085: o2.setB("bar");
086: //o2.setC (new BigInteger (13));
087: o2.setD(new Date());
088: o2.setE("e-bar");
089: o2.setF("f-bar");
090: o2.setG(o1);
091: o2.setH(o1);
092:
093: FetchGroupTestObjectChild c1 = new FetchGroupTestObjectChild();
094: // the value that 'a' is set to is important -- TestFetchGroupsExtent
095: // and TestFetchGroupsQuery rely on this
096: c1.setA(4);
097: c1.setB("child");
098: c1.setD(new Date());
099: c1.setE("e-baz");
100: c1.setF("f-baz");
101: c1.setG(o1);
102: c1.setH(o1);
103: c1.setChildA(1);
104: c1.setChildB(2);
105: c1.setChildC(3);
106: c1.setChildD(4);
107:
108: OpenJPAEntityManager pm = getPM();
109: startTx(pm);
110:
111: pm.persist(o1);
112: pm.persist(o2);
113: pm.persist(c1);
114: endTx(pm);
115:
116: oid1 = o1.getId();
117: oid2 = o2.getId();
118: oidc1 = c1.getId();
119:
120: endEm(pm);
121: }
122:
123: public void testFetchGroupsFromConfiguration() {
124: Map props = new HashMap();
125: props.put("openjpa.FetchGroups", "default,fg1,fg2");
126: OpenJPAEntityManagerFactory factory = getEmf(props);
127:
128: OpenJPAEntityManager pm = (OpenJPAEntityManager) factory
129: .createEntityManager();
130: checkGroups(pm, new String[] { "fg1", "fg2" });
131: factory.close();
132: }
133:
134: public void testFetchGroupsNoConfiguration() {
135: OpenJPAEntityManager pm = getPM();
136:
137: FetchGroupTestObject o1 = getO1(pm);
138: FetchGroupTestObject o2 = getO2(pm);
139:
140: // only field a should be loaded.
141: checkObject(pm, o1, true, false, false, false, false, false);
142:
143: // upon loading field b, fields c and d should also be loaded,
144: // but e and f should not.
145: o1.getB();
146: checkObject(pm, o1, true, true, true, true, false, false);
147:
148: // loading field h should not cause any of the others to be loaded.
149: assertEquals(o1, o2.getH());
150: checkObject(pm, o2, true, false, false, false, false, false);
151:
152: // loading field g should cause e and f to be loaded.
153: assertEquals(o1, o2.getG());
154: checkObject(pm, o2, true, false, false, false, true, true);
155: }
156:
157: public void testRetrieveAll() {
158: OpenJPAEntityManager pm = getPM();
159:
160: FetchGroupTestObject o1 = getO1(pm);
161: FetchGroupTestObject o2 = getO2(pm);
162:
163: // only field a should be loaded.
164: checkObject(pm, o1, true, false, false, false, false, false);
165: checkObject(pm, o2, true, false, false, false, false, false);
166:
167: // only field a should be loaded.
168: pm.retrieve(o1);
169: checkObject(pm, o1, true, false, false, false, false, false);
170:
171: // Add groups 1 and 3 to the default fetch configuration.
172: pm.getFetchPlan().addFetchGroup("g1");
173: pm.getFetchPlan().addFetchGroup("g3");
174:
175: // Retrieve o1's "DFG" which will actually do all configured
176: // fetch groups.
177: // DFG fields and fields in groups 1 and 3 should be loaded
178: pm.retrieve(o1);
179: checkObject(pm, o1, true, true, true, true, false, false);
180: }
181:
182: public void testFetchGroupConfiguration() {
183: OpenJPAEntityManager pm = getPM();
184: FetchPlan fetch = pm.getFetchPlan();
185:
186: checkGroups(pm, new String[0]);
187:
188: fetch.addFetchGroup("foo");
189: checkGroups(pm, new String[] { "foo" });
190:
191: fetch.addFetchGroup("bar");
192: fetch.addFetchGroup("baz");
193: checkGroups(pm, new String[] { "foo", "bar", "baz" });
194:
195: fetch.addFetchGroup("a");
196: fetch.addFetchGroup("b");
197: fetch.addFetchGroup("c");
198: fetch.addFetchGroup("d");
199: checkGroups(pm, new String[] { "foo", "bar", "baz", "a", "b",
200: "c", "d" });
201:
202: fetch.removeFetchGroup("bar");
203: checkGroups(pm,
204: new String[] { "foo", "baz", "a", "b", "c", "d" });
205:
206: fetch.removeFetchGroup("baz");
207: fetch.removeFetchGroup("c");
208: checkGroups(pm, new String[] { "foo", "a", "b", "d" });
209:
210: fetch.clearFetchGroups().addFetchGroup(FetchPlan.GROUP_DEFAULT);
211: checkGroups(pm, new String[0]);
212: }
213:
214: private void checkGroups(OpenJPAEntityManager pm, String[] groups) {
215: HashSet groupSet = new HashSet(Arrays.asList(groups));
216: groupSet.add(FetchPlan.GROUP_DEFAULT);
217: assertEquals("groupSet dont match", groupSet, new HashSet(pm
218: .getFetchPlan().getFetchGroups()));
219: }
220:
221: public void testFetchGroupsChildWithConfiguration() {
222: OpenJPAEntityManager pm = getPM();
223: pm.getFetchPlan().addFetchGroup("g1");
224: pm.getFetchPlan().addFetchGroup("g3");
225:
226: // get this so that h's value is loaded into cache.
227: FetchGroupTestObject o1 = getO1(pm);
228:
229: FetchGroupTestObjectChild c1 = getC1(pm);
230:
231: // DFG fields and fields in groups 1 and 3 should be loaded
232: checkChildObject(pm, c1, true, true, true, true, false, false,
233: true, true, false, true);
234:
235: // upon accessing field b, nothing should change.
236: c1.getB();
237: checkChildObject(pm, c1, true, true, true, true, false, false,
238: true, true, false, true);
239:
240: c1.getH();
241: }
242:
243: public void testFetchGroupsWithConfiguration() {
244: OpenJPAEntityManager pm = getPM();
245:
246: pm.getFetchPlan().addFetchGroup("g1");
247: pm.getFetchPlan().addFetchGroup("g3");
248:
249: FetchGroupTestObject o1 = getO1(pm);
250: FetchGroupTestObject o2 = getO2(pm);
251:
252: // DFG fields and fields in groups 1 and 3 should be loaded
253: checkObject(pm, o1, true, true, true, true, false, false);
254:
255: // upon accessing field b, nothing should change.
256: o1.getB();
257: checkObject(pm, o1, true, true, true, true, false, false);
258:
259: // loading field h should not cause any of the others to be loaded.
260: assertEquals(o1, o2.getH());
261: checkObject(pm, o2, true, true, true, true, false, false);
262:
263: // loading field g should cause e and f to be loaded.
264: assertEquals(o1, o2.getG());
265: checkObject(pm, o2, true, true, true, true, true, true);
266: }
267:
268: /**
269: * Tests that relation fields are loaded immediately when
270: * they are in one of the PM's configured fetch groups.
271: */
272: public void testRelationsLoaded() {
273: OpenJPAEntityManager pm = getPM();
274: pm.getFetchPlan().addFetchGroup("g2");
275:
276: // note: important the o1 is *not* in pm's cache at this point, so that
277: // we know it takes another datastore trip to get o1
278:
279: // load o2 and retrieve its state manager
280: OpenJPAStateManager sm = getStateManager(getO2(pm), pm);
281: assertNotNull("SM is NULL", sm);
282:
283: // 'g' is the name of a 1-1 relation field to o1 in configured
284: // fetch group 'g2'; make sure it is loaded
285: int field = sm.getMetaData().getField("g").getIndex();
286: try {
287: assertTrue(sm.getLoaded().get(field));
288: assertEquals(oid1, ((FetchGroupTestObject) sm
289: .fetchObjectField(field)).getId());
290: } catch (junit.framework.AssertionFailedError afe) {
291: bug(623, afe,
292: "One to one mappings do not work with custom "
293: + "fetch groups");
294: }
295: }
296:
297: protected void checkObject(OpenJPAEntityManager pm,
298: FetchGroupTestObject o, boolean a, boolean b, boolean c,
299: boolean d, boolean e, boolean f) {
300: OpenJPAStateManager sm = getStateManager(o, pm);
301: BitSet loaded = sm.getLoaded();
302:
303: FieldMetaData[] fmds = sm.getMetaData().getFields();
304: int i = 0;
305: for (; i < fmds.length; i++) {
306: if (fmds[i].getName().equals("a"))
307: assertEquals(a, loaded.get(i));
308: else if (fmds[i].getName().equals("b"))
309: assertEquals(b, loaded.get(i));
310: else if (fmds[i].getName().equals("c"))
311: assertEquals(c, loaded.get(i));
312: else if (fmds[i].getName().equals("d"))
313: assertEquals(d, loaded.get(i));
314: else if (fmds[i].getName().equals("e"))
315: assertEquals(e, loaded.get(i));
316: else if (fmds[i].getName().equals("f"))
317: assertEquals(f, loaded.get(i));
318: }
319: }
320:
321: protected void checkChildObject(OpenJPAEntityManager pm,
322: FetchGroupTestObjectChild o, boolean a, boolean b,
323: boolean c, boolean d, boolean e, boolean f, boolean childA,
324: boolean childB, boolean childC, boolean childD) {
325: checkObject(pm, o, a, b, c, d, e, f);
326:
327: OpenJPAStateManager sm = getStateManager(o, pm);
328: BitSet loaded = sm.getLoaded();
329:
330: FieldMetaData[] fmds = sm.getMetaData().getFields();
331: int i = 0;
332: for (; i < fmds.length; i++) {
333: if (fmds[i].getName().equals("childA"))
334: assertEquals(childA, loaded.get(i));
335: else if (fmds[i].getName().equals("childB"))
336: assertEquals(childB, loaded.get(i));
337: else if (fmds[i].getName().equals("childC"))
338: assertEquals(childC, loaded.get(i));
339: else if (fmds[i].getName().equals("childD"))
340: assertEquals(childD, loaded.get(i));
341: }
342: }
343:
344: protected FetchGroupTestObject getO1(OpenJPAEntityManager pm) {
345: return pm.find(FetchGroupTestObject.class, oid1);
346: }
347:
348: protected FetchGroupTestObject getO2(OpenJPAEntityManager pm) {
349: return pm.find(FetchGroupTestObject.class, oid2);
350: }
351:
352: protected FetchGroupTestObjectChild getC1(OpenJPAEntityManager pm) {
353: return pm.find(FetchGroupTestObjectChild.class, oidc1);
354: }
355:
356: /**
357: * Tests that named fetch groups actually bring in the
358: * managed object.
359: */
360: public void testFetchGroupInstantiated() {
361: deleteAll(AttachA.class);
362: deleteAll(AttachB.class);
363: deleteAll(AttachC.class);
364: deleteAll(AttachD.class);
365: deleteAll(AttachE.class);
366: deleteAll(AttachF.class);
367:
368: OpenJPAEntityManager pm;
369:
370: pm = getPM();
371: startTx(pm);
372: AttachE e = new AttachE();
373: AttachB b = new AttachB();
374: e.setB(b);
375: pm.persist(e);
376:
377: endTx(pm);
378: endEm(pm);
379:
380: Object ob;
381:
382: pm = getPM();
383: startTx(pm);
384: assertSize(0, pm.getManagedObjects());
385: ob = pm.createExtent(AttachE.class, true).iterator().next();
386: // make sure relation is not loaded
387: assertSize(1, pm.getManagedObjects());
388: rollbackTx(pm);
389: endEm(pm);
390:
391: pm = getPM();
392: startTx(pm);
393: // now make sure we load relations
394: pm.getFetchPlan().addFetchGroup("all");
395: assertSize(0, pm.getManagedObjects());
396: ob = pm.createExtent(AttachE.class, true).iterator().next();
397: // make sure relation is loaded
398: assertSize(2, pm.getManagedObjects());
399: rollbackTx(pm);
400: endEm(pm);
401: }
402: }
|