PageRenderTime 120ms CodeModel.GetById 62ms app.highlight 50ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/com/google/appengine/datanucleus/jdo/JDOOneToManyListTest.java

http://datanucleus-appengine.googlecode.com/
Java | 858 lines | 749 code | 83 blank | 26 comment | 12 complexity | 54cc8dac252467da9376eda2891dad0a MD5 | raw file
  1/**********************************************************************
  2Copyright (c) 2009 Google Inc.
  3
  4Licensed under the Apache License, Version 2.0 (the "License");
  5you may not use this file except in compliance with the License.
  6You may obtain a copy of the License at
  7
  8http://www.apache.org/licenses/LICENSE-2.0
  9
 10Unless required by applicable law or agreed to in writing, software
 11distributed under the License is distributed on an "AS IS" BASIS,
 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13See the License for the specific language governing permissions and
 14limitations under the License.
 15**********************************************************************/
 16package com.google.appengine.datanucleus.jdo;
 17
 18import com.google.appengine.api.datastore.Entity;
 19import com.google.appengine.api.datastore.EntityNotFoundException;
 20import com.google.appengine.api.datastore.KeyFactory;
 21import com.google.appengine.datanucleus.StorageVersion;
 22import com.google.appengine.datanucleus.TestUtils;
 23import com.google.appengine.datanucleus.Utils;
 24import com.google.appengine.datanucleus.test.jdo.BidirectionalChildJDO;
 25import com.google.appengine.datanucleus.test.jdo.BidirectionalChildListJDO;
 26import com.google.appengine.datanucleus.test.jdo.BidirectionalChildLongPkListJDO;
 27import com.google.appengine.datanucleus.test.jdo.BidirectionalChildStringPkListJDO;
 28import com.google.appengine.datanucleus.test.jdo.BidirectionalChildUnencodedStringPkListJDO;
 29import com.google.appengine.datanucleus.test.jdo.Flight;
 30import com.google.appengine.datanucleus.test.jdo.HasChildWithSeparateNameFieldJDO;
 31import com.google.appengine.datanucleus.test.jdo.HasEncodedStringPkSeparateNameFieldJDO;
 32import com.google.appengine.datanucleus.test.jdo.HasKeyPkJDO;
 33import com.google.appengine.datanucleus.test.jdo.HasLongPkOneToManyBidirChildrenJDO;
 34import com.google.appengine.datanucleus.test.jdo.HasMultipleBidirChildrenJDO;
 35import com.google.appengine.datanucleus.test.jdo.HasOneToManyChildAtMultipleLevelsJDO;
 36import com.google.appengine.datanucleus.test.jdo.HasOneToManyKeyPkListJDO;
 37import com.google.appengine.datanucleus.test.jdo.HasOneToManyListJDO;
 38import com.google.appengine.datanucleus.test.jdo.HasOneToManyListWithOrderByJDO;
 39import com.google.appengine.datanucleus.test.jdo.HasOneToManyLongPkListJDO;
 40import com.google.appengine.datanucleus.test.jdo.HasOneToManyStringPkListJDO;
 41import com.google.appengine.datanucleus.test.jdo.HasOneToManyUnencodedStringPkListJDO;
 42import com.google.appengine.datanucleus.test.jdo.HasUnencodedStringPkOneToManyBidirChildrenJDO;
 43import com.google.appengine.repackaged.com.google.common.collect.Lists;
 44
 45import static com.google.appengine.datanucleus.TestUtils.assertKeyParentEquals;
 46
 47import java.util.Collection;
 48
 49/**
 50 * @author Max Ross <maxr@google.com>
 51 */
 52public class JDOOneToManyListTest extends JDOOneToManyTestCase {
 53
 54  public void testInsertNewParentAndChild() throws EntityNotFoundException {
 55    testInsertNewParentAndChild(TXN_START_END);
 56  }
 57  public void testInsertNewParentAndChild_NoTxn() throws EntityNotFoundException {
 58    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 59    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 60    testInsertNewParentAndChild(NEW_PM_START_END);
 61  }
 62  private void testInsertNewParentAndChild(StartEnd startEnd) throws EntityNotFoundException {
 63    HasOneToManyListJDO parent = new HasOneToManyListJDO();
 64    BidirectionalChildListJDO bidirChild = new BidirectionalChildListJDO();
 65    testInsert_NewParentAndChild(parent, bidirChild, startEnd);
 66  }
 67
 68  public void testInsertExistingParentNewChild() throws EntityNotFoundException {
 69    testInsertExistingParentNewChild(TXN_START_END);
 70  }
 71  public void testInsertExistingParentNewChild_NoTxn() throws EntityNotFoundException {
 72    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 73    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 74    testInsertExistingParentNewChild(NEW_PM_START_END);
 75  }
 76  private void testInsertExistingParentNewChild(StartEnd startEnd) throws EntityNotFoundException {
 77    HasOneToManyListJDO parent = new HasOneToManyListJDO();
 78    BidirectionalChildListJDO bidirChild = new BidirectionalChildListJDO();
 79    testInsert_ExistingParentNewChild(parent, bidirChild, startEnd);
 80  }
 81
 82  public void testSwapAtPosition() throws EntityNotFoundException {
 83    testSwapAtPosition(TXN_START_END);
 84  }
 85  public void testSwapAtPosition_NoTxn() throws EntityNotFoundException {
 86    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 87    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 88    testSwapAtPosition(NEW_PM_START_END);
 89  }
 90  private void testSwapAtPosition(StartEnd startEnd) throws EntityNotFoundException {
 91    HasOneToManyListJDO parent = new HasOneToManyListJDO();
 92    BidirectionalChildListJDO bidirChild = new BidirectionalChildListJDO();
 93    BidirectionalChildListJDO bidirChild2 = new BidirectionalChildListJDO();
 94    testSwapAtPosition(parent, bidirChild, bidirChild2, startEnd);
 95  }
 96
 97  public void testRemoveAtPosition() throws EntityNotFoundException {
 98    testRemoveAtPosition(TXN_START_END);
 99  }
100  public void testRemoveAtPosition_NoTxn() throws EntityNotFoundException {
101    switchDatasource(PersistenceManagerFactoryName.nontransactional);
102    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
103    testRemoveAtPosition(NEW_PM_START_END);
104  }
105  private void testRemoveAtPosition(StartEnd startEnd) throws EntityNotFoundException {
106    HasOneToManyListJDO parent = new HasOneToManyListJDO();
107    BidirectionalChildListJDO bidirChild = new BidirectionalChildListJDO();
108    BidirectionalChildListJDO bidirChild2 = new BidirectionalChildListJDO();
109    BidirectionalChildListJDO bidirChild3 = new BidirectionalChildListJDO();
110    testRemoveAtPosition(parent, bidirChild, bidirChild2, bidirChild3, startEnd);
111  }
112
113  public void testAddAtPosition() throws EntityNotFoundException {
114    testAddAtPosition(TXN_START_END);
115  }
116  public void testAddAtPosition_NoTxn() throws EntityNotFoundException {
117    switchDatasource(PersistenceManagerFactoryName.nontransactional);
118    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
119    testAddAtPosition(NEW_PM_START_END);
120  }
121  private void testAddAtPosition(StartEnd startEnd) throws EntityNotFoundException {
122    HasOneToManyListJDO parent = new HasOneToManyListJDO();
123    BidirectionalChildListJDO bidirChild = new BidirectionalChildListJDO();
124    BidirectionalChildListJDO bidirChild2 = new BidirectionalChildListJDO();
125    testAddAtPosition(parent, bidirChild, bidirChild2, startEnd);
126  }
127
128  public void testUpdateUpdateChildWithMerge() throws EntityNotFoundException {
129    testUpdateUpdateChildWithMerge(TXN_START_END);
130  }
131  public void testUpdateUpdateChildWithMerge_NoTxn() throws EntityNotFoundException {
132    switchDatasource(PersistenceManagerFactoryName.nontransactional);
133    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
134    testUpdateUpdateChildWithMerge(NEW_PM_START_END);
135  }
136  private void testUpdateUpdateChildWithMerge(StartEnd startEnd) throws EntityNotFoundException {
137    HasOneToManyListJDO pojo = new HasOneToManyListJDO();
138    BidirectionalChildListJDO bidir = new BidirectionalChildListJDO();
139    testUpdate_UpdateChildWithMerge(pojo, bidir, startEnd);
140  }
141
142  public void testUpdateUpdateChild() throws EntityNotFoundException {
143    testUpdateUpdateChild(TXN_START_END);
144  }
145  public void testUpdateUpdateChild_NoTxn() throws EntityNotFoundException {
146    switchDatasource(PersistenceManagerFactoryName.nontransactional);
147    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
148    testUpdateUpdateChild(NEW_PM_START_END);
149  }
150  private void testUpdateUpdateChild(StartEnd startEnd) throws EntityNotFoundException {
151    HasOneToManyListJDO pojo = new HasOneToManyListJDO();
152    BidirectionalChildListJDO bidir = new BidirectionalChildListJDO();
153    testUpdate_UpdateChild(pojo, bidir, startEnd);
154  }
155
156  public void testUpdateNullOutChildren() throws EntityNotFoundException {
157    testUpdateNullOutChildren(TXN_START_END);
158  }
159  public void testUpdateNullOutChildren_NoTxn() throws EntityNotFoundException {
160    switchDatasource(PersistenceManagerFactoryName.nontransactional);
161    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
162    testUpdateNullOutChildren(NEW_PM_START_END);
163  }
164  private void testUpdateNullOutChildren(StartEnd startEnd) throws EntityNotFoundException {
165    HasOneToManyListJDO pojo = new HasOneToManyListJDO();
166    BidirectionalChildListJDO bidir = new BidirectionalChildListJDO();
167    testUpdate_NullOutChildren(pojo, bidir, startEnd);
168  }
169
170  public void testUpdateClearOutChildren() throws EntityNotFoundException {
171    testUpdateClearOutChildren(TXN_START_END);
172  }
173  public void testUpdateClearOutChildren_NoTxn() throws EntityNotFoundException {
174    switchDatasource(PersistenceManagerFactoryName.nontransactional);
175    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
176    testUpdateClearOutChildren(NEW_PM_START_END);
177  }
178  private void testUpdateClearOutChildren(StartEnd startEnd) throws EntityNotFoundException {
179    HasOneToManyListJDO pojo = new HasOneToManyListJDO();
180    BidirectionalChildListJDO bidir = new BidirectionalChildListJDO();
181    testUpdate_ClearOutChildren(pojo, bidir, startEnd);
182  }
183
184  public void testFindWithOrderBy() throws EntityNotFoundException {
185    testFindWithOrderBy(TXN_START_END);
186  }
187  public void testFindWithOrderBy_NoTxn() throws EntityNotFoundException {
188    switchDatasource(PersistenceManagerFactoryName.nontransactional);
189    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
190    testFindWithOrderBy(NEW_PM_START_END);
191  }
192  private void testFindWithOrderBy(StartEnd startEnd) throws EntityNotFoundException {
193    testFindWithOrderBy(HasOneToManyListWithOrderByJDO.class, startEnd);
194  }
195
196  public void testSaveWithOrderBy() throws EntityNotFoundException {
197    testSaveWithOrderBy(TXN_START_END);
198  }
199  public void testSaveWithOrderBy_NoTxn() throws EntityNotFoundException {
200    switchDatasource(PersistenceManagerFactoryName.nontransactional);
201    testSaveWithOrderBy(NEW_PM_START_END);
202  }
203  private void testSaveWithOrderBy(StartEnd startEnd) throws EntityNotFoundException {
204    testSaveWithOrderBy(new HasOneToManyListWithOrderByJDO(), startEnd);
205  }
206
207  public void testFind() throws EntityNotFoundException {
208    testFind(TXN_START_END);
209  }
210  public void testFind_NoTxn() throws EntityNotFoundException {
211    switchDatasource(PersistenceManagerFactoryName.nontransactional);
212    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
213    testFind(NEW_PM_START_END);
214  }
215  private void testFind(StartEnd startEnd) throws EntityNotFoundException {
216    testFind(HasOneToManyListJDO.class, BidirectionalChildListJDO.class, startEnd);
217  }
218
219  public void testQuery() throws EntityNotFoundException {
220    testQuery(TXN_START_END);
221  }
222  public void testQuery_NoTxn() throws EntityNotFoundException {
223    switchDatasource(PersistenceManagerFactoryName.nontransactional);
224    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
225    testQuery(NEW_PM_START_END);
226  }
227  private void testQuery(StartEnd startEnd) throws EntityNotFoundException {
228    testQuery(HasOneToManyListJDO.class, BidirectionalChildListJDO.class, startEnd);
229  }
230
231  public void testChildFetchedLazily() throws Exception {
232    testChildFetchedLazily(HasOneToManyListJDO.class, BidirectionalChildListJDO.class);
233  }
234
235  public void testDeleteParentDeletesChild() throws Exception {
236    testDeleteParentDeletesChild(TXN_START_END);
237  }
238  public void testDeleteParentDeletesChild_NoTxn() throws Exception {
239    switchDatasource(PersistenceManagerFactoryName.nontransactional);
240    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
241    testDeleteParentDeletesChild(NEW_PM_START_END);
242  }
243  private void testDeleteParentDeletesChild(StartEnd startEnd) throws Exception {
244    testDeleteParentDeletesChild(HasOneToManyListJDO.class, BidirectionalChildListJDO.class, startEnd);
245  }
246
247  public void testIndexOf() throws Exception {
248    testIndexOf(TXN_START_END);
249  }
250  public void testIndexOf_NoTxn() throws Exception {
251    switchDatasource(PersistenceManagerFactoryName.nontransactional);
252    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
253    testIndexOf(NEW_PM_START_END);
254  }
255  public void testIndexOf(StartEnd startEnd) throws Exception {
256    HasOneToManyListJDO pojo = new HasOneToManyListJDO();
257    BidirectionalChildListJDO bidir1 = new BidirectionalChildListJDO();
258    BidirectionalChildListJDO bidir2 = new BidirectionalChildListJDO();
259
260    Flight f1 = newFlight();
261    Flight f2 = newFlight();
262
263    HasKeyPkJDO hasKeyPk1 = new HasKeyPkJDO();
264    HasKeyPkJDO hasKeyPk2 = new HasKeyPkJDO();
265
266    pojo.addBidirChild(bidir1);
267    pojo.addBidirChild(bidir2);
268    pojo.addFlight(f1);
269    pojo.addFlight(f2);
270    pojo.addHasKeyPk(hasKeyPk1);
271    pojo.addHasKeyPk(hasKeyPk2);
272
273    startEnd.start();
274    pm.makePersistent(pojo);
275    startEnd.end();
276
277    startEnd.start();
278    pojo = pm.getObjectById(HasOneToManyListJDO.class, pojo.getId());
279    bidir1 = pm.getObjectById(bidir1.getClass(), bidir1.getId());
280    bidir2 = pm.getObjectById(bidir2.getClass(), bidir2.getId());
281    f1 = pm.getObjectById(f1.getClass(), f1.getId());
282    f2 = pm.getObjectById(f2.getClass(), f2.getId());
283    hasKeyPk1 = pm.getObjectById(hasKeyPk1.getClass(), hasKeyPk1.getKey());
284    hasKeyPk2 = pm.getObjectById(hasKeyPk2.getClass(), hasKeyPk2.getKey());
285    assertEquals(0, pojo.getBidirChildren().indexOf(bidir1));
286    assertEquals(1, pojo.getBidirChildren().indexOf(bidir2));
287    assertEquals(0, pojo.getFlights().indexOf(f1));
288    assertEquals(1, pojo.getFlights().indexOf(f2));
289    assertEquals(0, pojo.getHasKeyPks().indexOf(hasKeyPk1));
290    assertEquals(1, pojo.getHasKeyPks().indexOf(hasKeyPk2));
291    startEnd.end();
292  }
293
294  public void testRemoveAll() throws EntityNotFoundException {
295    testRemoveAll(TXN_START_END);
296  }
297  public void testRemoveAll_NoTxn() throws EntityNotFoundException {
298    switchDatasource(PersistenceManagerFactoryName.nontransactional);
299    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
300    testRemoveAll(NEW_PM_START_END);
301  }
302  private void testRemoveAll(StartEnd startEnd) throws EntityNotFoundException {
303    testRemoveAll(new HasOneToManyListJDO(), new BidirectionalChildListJDO(),
304                  new BidirectionalChildListJDO(), new BidirectionalChildListJDO(), startEnd);
305  }
306
307  public void testRemoveAll_LongPkOnParent() throws EntityNotFoundException {
308    testRemoveAll_LongPkOnParent(TXN_START_END);
309  }
310  public void testRemoveAll_LongPkOnParent_NoTxn() throws EntityNotFoundException {
311    switchDatasource(PersistenceManagerFactoryName.nontransactional);
312    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
313    testRemoveAll_LongPkOnParent(NEW_PM_START_END);
314  }
315  private void testRemoveAll_LongPkOnParent(StartEnd startEnd) throws EntityNotFoundException {
316    testRemoveAll_LongPkOnParent(new HasOneToManyLongPkListJDO(), new BidirectionalChildLongPkListJDO(),
317                  new BidirectionalChildLongPkListJDO(), new BidirectionalChildLongPkListJDO(),
318                  startEnd);
319  }
320
321  public void testRemoveAll_UnencodedStringPkOnParent() throws EntityNotFoundException {
322    testRemoveAll_UnencodedStringPkOnParent(TXN_START_END);
323  }
324  public void testRemoveAll_UnencodedStringPkOnParent_NoTxn() throws EntityNotFoundException {
325    switchDatasource(PersistenceManagerFactoryName.nontransactional);
326    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
327    testRemoveAll_UnencodedStringPkOnParent(NEW_PM_START_END);
328  }
329  private void testRemoveAll_UnencodedStringPkOnParent(StartEnd startEnd) throws EntityNotFoundException {
330    HasOneToManyUnencodedStringPkListJDO parent = new HasOneToManyUnencodedStringPkListJDO();
331    parent.setId("parent id");
332    testRemoveAll_UnencodedStringPkOnParent(parent, new BidirectionalChildUnencodedStringPkListJDO(),
333                  new BidirectionalChildUnencodedStringPkListJDO(), new BidirectionalChildUnencodedStringPkListJDO(),
334                  startEnd);
335  }
336
337  public void testChangeParent() {
338    testChangeParent(TXN_START_END);
339  }
340  public void testChangeParent_NoTxn() {
341    switchDatasource(PersistenceManagerFactoryName.nontransactional);
342    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
343    testChangeParent(NEW_PM_START_END);
344  }
345  private void testChangeParent(StartEnd startEnd) {
346    testChangeParent(new HasOneToManyListJDO(), new HasOneToManyListJDO(), startEnd);
347  }
348
349  public void testNewParentNewChild_NamedKeyOnChild() throws EntityNotFoundException {
350    testNewParentNewChild_NamedKeyOnChild(TXN_START_END);
351  }
352  public void testNewParentNewChild_NamedKeyOnChild_NoTxn() throws EntityNotFoundException {
353    switchDatasource(PersistenceManagerFactoryName.nontransactional);
354    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
355    testNewParentNewChild_NamedKeyOnChild(NEW_PM_START_END);
356  }
357  private void testNewParentNewChild_NamedKeyOnChild(StartEnd startEnd) throws EntityNotFoundException {
358    testNewParentNewChild_NamedKeyOnChild(new HasOneToManyListJDO(), startEnd);
359  }
360
361  public void testInsert_NewParentAndChild_LongPk() throws EntityNotFoundException {
362    testInsert_NewParentAndChild_LongPk(TXN_START_END);
363  }
364  public void testInsert_NewParentAndChild_LongPk_NoTxn() throws EntityNotFoundException {
365    switchDatasource(PersistenceManagerFactoryName.nontransactional);
366    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
367    testInsert_NewParentAndChild_LongPk(NEW_PM_START_END);
368  }
369  private void testInsert_NewParentAndChild_LongPk(StartEnd startEnd) throws EntityNotFoundException {
370    BidirectionalChildLongPkListJDO bidirChild = new BidirectionalChildLongPkListJDO();
371    bidirChild.setChildVal("yam");
372
373    Flight f = newFlight();
374
375    HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
376    hasKeyPk.setStr("yag");
377
378    HasOneToManyLongPkListJDO parent = new HasOneToManyLongPkListJDO();
379    parent.addBidirChild(bidirChild);
380    bidirChild.setParent(parent);
381    parent.addFlight(f);
382    parent.addHasKeyPk(hasKeyPk);
383    parent.setVal("yar");
384
385    startEnd.start();
386    pm.makePersistent(parent);
387    startEnd.end();
388
389    assertNotNull(bidirChild.getId());
390    assertNotNull(f.getId());
391    assertNotNull(hasKeyPk.getKey());
392
393    Entity bidirChildEntity = ds.get(KeyFactory.stringToKey(bidirChild.getId()));
394    assertNotNull(bidirChildEntity);
395    assertEquals("yam", bidirChildEntity.getProperty("childVal"));
396    assertEquals(KeyFactory.stringToKey(bidirChild.getId()), bidirChildEntity.getKey());
397    assertKeyParentEquals(parent.getClass(), parent.getId(), bidirChildEntity, bidirChild.getId());
398
399    // TODO This is only for older storage versions; check owner relation List positions for current
400    if (isIndexed() && 
401        getStorageVersion(pm).ordinal() < StorageVersion.READ_OWNED_CHILD_KEYS_FROM_PARENTS.ordinal()) {
402      assertEquals(0L, bidirChildEntity.getProperty("bidirChildren_INTEGER_IDX"));
403    }
404
405    Entity flightEntity = ds.get(KeyFactory.stringToKey(f.getId()));
406    assertNotNull(flightEntity);
407    assertEquals("bos", flightEntity.getProperty("origin"));
408    assertEquals("mia", flightEntity.getProperty("dest"));
409    assertEquals("jimmy", flightEntity.getProperty("name"));
410    assertEquals(KeyFactory.stringToKey(f.getId()), flightEntity.getKey());
411    assertKeyParentEquals(parent.getClass(), parent.getId(), flightEntity, f.getId());
412    if (isIndexed() && 
413        getStorageVersion(pm).ordinal() < StorageVersion.READ_OWNED_CHILD_KEYS_FROM_PARENTS.ordinal()) {
414      assertEquals(0L, flightEntity.getProperty("flights_INTEGER_IDX_longpk"));
415    }
416
417    Entity hasKeyPkEntity = ds.get(hasKeyPk.getKey());
418    assertNotNull(hasKeyPkEntity);
419    assertEquals("yag", hasKeyPkEntity.getProperty("str"));
420    assertEquals(hasKeyPk.getKey(), hasKeyPkEntity.getKey());
421    assertKeyParentEquals(parent.getClass(), parent.getId(), hasKeyPkEntity, hasKeyPk.getKey());
422    if (isIndexed() && 
423        getStorageVersion(pm).ordinal() < StorageVersion.READ_OWNED_CHILD_KEYS_FROM_PARENTS.ordinal()) {
424      assertEquals(0L, hasKeyPkEntity.getProperty("hasKeyPks_INTEGER_IDX_longpk"));
425    }
426
427    Entity parentEntity = ds.get(TestUtils.createKey(parent, parent.getId()));
428    assertNotNull(parentEntity);
429    assertEquals(4, parentEntity.getProperties().size());
430    assertEquals("yar", parentEntity.getProperty("val"));
431    assertEquals(Lists.newArrayList(bidirChildEntity.getKey()), parentEntity.getProperty("bidirChildren"));
432    assertEquals(Lists.newArrayList(flightEntity.getKey()), parentEntity.getProperty("flights"));
433    assertEquals(Lists.newArrayList(hasKeyPkEntity.getKey()), parentEntity.getProperty("hasKeyPks"));
434
435    assertEquals(HasOneToManyLongPkListJDO.class.getName(), 1, countForClass(HasOneToManyLongPkListJDO.class));
436    assertEquals(BidirectionalChildLongPkListJDO.class.getName(), 1, countForClass(
437        BidirectionalChildLongPkListJDO.class));
438    assertEquals(Flight.class.getName(), 1, countForClass(Flight.class));
439    assertEquals(HasKeyPkJDO.class.getName(), 1, countForClass(HasKeyPkJDO.class));
440  }
441
442  public void testInsert_NewParentAndChild_StringPk() throws EntityNotFoundException {
443    testInsert_NewParentAndChild_StringPk(TXN_START_END);
444  }
445  public void testInsert_NewParentAndChild_StringPk_NoTxn() throws EntityNotFoundException {
446    switchDatasource(PersistenceManagerFactoryName.nontransactional);
447    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
448    testInsert_NewParentAndChild_StringPk(NEW_PM_START_END);
449  }
450  private void testInsert_NewParentAndChild_StringPk(StartEnd startEnd) throws EntityNotFoundException {
451    BidirectionalChildStringPkListJDO bidirChild = new BidirectionalChildStringPkListJDO();
452    bidirChild.setChildVal("yam");
453
454    Flight f = newFlight();
455
456    HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
457    hasKeyPk.setStr("yag");
458
459    HasOneToManyStringPkListJDO parent = new HasOneToManyStringPkListJDO();
460    parent.setId("yar");
461    parent.addBidirChild(bidirChild);
462    bidirChild.setParent(parent);
463    parent.addFlight(f);
464    parent.addHasKeyPk(hasKeyPk);
465    parent.setVal("yar");
466
467    startEnd.start();
468    pm.makePersistent(parent);
469    startEnd.end();
470
471    assertNotNull(bidirChild.getId());
472    assertNotNull(f.getId());
473    assertNotNull(hasKeyPk.getKey());
474
475    Entity bidirChildEntity = ds.get(KeyFactory.stringToKey(bidirChild.getId()));
476    assertNotNull(bidirChildEntity);
477    assertEquals("yam", bidirChildEntity.getProperty("childVal"));
478    assertEquals(KeyFactory.stringToKey(bidirChild.getId()), bidirChildEntity.getKey());
479    assertKeyParentEquals(parent.getClass(), parent.getId(), bidirChildEntity, bidirChild.getId());
480
481    // TODO This is only for older storage versions; check owner relation List positions for current
482    if (isIndexed() && 
483        getStorageVersion(pm).ordinal() < StorageVersion.READ_OWNED_CHILD_KEYS_FROM_PARENTS.ordinal()) {
484      assertEquals(0L, bidirChildEntity.getProperty("bidirChildren_INTEGER_IDX"));
485    }
486
487    Entity flightEntity = ds.get(KeyFactory.stringToKey(f.getId()));
488    assertNotNull(flightEntity);
489    assertEquals("bos", flightEntity.getProperty("origin"));
490    assertEquals("mia", flightEntity.getProperty("dest"));
491    assertEquals("jimmy", flightEntity.getProperty("name"));
492    assertEquals(KeyFactory.stringToKey(f.getId()), flightEntity.getKey());
493    assertKeyParentEquals(parent.getClass(), parent.getId(), flightEntity, f.getId());
494    if (isIndexed() && 
495        getStorageVersion(pm).ordinal() < StorageVersion.READ_OWNED_CHILD_KEYS_FROM_PARENTS.ordinal()) {
496      assertEquals(0L, flightEntity.getProperty("flights_INTEGER_IDX"));
497    }
498
499    Entity hasKeyPkEntity = ds.get(hasKeyPk.getKey());
500    assertNotNull(hasKeyPkEntity);
501    assertEquals("yag", hasKeyPkEntity.getProperty("str"));
502    assertEquals(hasKeyPk.getKey(), hasKeyPkEntity.getKey());
503    assertKeyParentEquals(parent.getClass(), parent.getId(), hasKeyPkEntity, hasKeyPk.getKey());
504    if (isIndexed() && 
505        getStorageVersion(pm).ordinal() < StorageVersion.READ_OWNED_CHILD_KEYS_FROM_PARENTS.ordinal()) {
506      assertEquals(0L, hasKeyPkEntity.getProperty("hasKeyPks_INTEGER_IDX"));
507    }
508
509    Entity parentEntity = ds.get(TestUtils.createKey(parent, parent.getId()));
510    assertNotNull(parentEntity);
511    assertEquals(4, parentEntity.getProperties().size());
512    assertEquals("yar", parentEntity.getProperty("val"));
513    assertEquals(Lists.newArrayList(bidirChildEntity.getKey()), parentEntity.getProperty("bidirChildren"));
514    assertEquals(Lists.newArrayList(flightEntity.getKey()), parentEntity.getProperty("flights"));
515    assertEquals(Lists.newArrayList(hasKeyPkEntity.getKey()), parentEntity.getProperty("hasKeyPks"));
516
517    assertEquals(HasOneToManyStringPkListJDO.class.getName(), 1, countForClass(
518        HasOneToManyStringPkListJDO.class));
519    assertEquals(BidirectionalChildStringPkListJDO.class.getName(), 1, countForClass(
520        BidirectionalChildStringPkListJDO.class));
521    assertEquals(Flight.class.getName(), 1, countForClass(Flight.class));
522    assertEquals(HasKeyPkJDO.class.getName(), 1, countForClass(HasKeyPkJDO.class));
523  }
524
525  public void testAddAlreadyPersistedChildToParent_NoTxnSamePm() {
526    testAddAlreadyPersistedChildToParent_NoTxnSamePm(new HasOneToManyListJDO());
527  }
528
529  public void testAddAlreadyPersistedChildToParent_NoTxnDifferentPm() {
530    testAddAlreadyPersistedChildToParent_NoTxnDifferentPm(new HasOneToManyListJDO());
531  }
532
533  public void testLongPkOneToManyBidirChildren() {
534    testLongPkOneToManyBidirChildren(TXN_START_END);
535  }
536  public void testLongPkOneToManyBidirChildren_NoTxn() {
537    switchDatasource(PersistenceManagerFactoryName.nontransactional);
538    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
539    testLongPkOneToManyBidirChildren(NEW_PM_START_END);
540  }
541  private void testLongPkOneToManyBidirChildren(StartEnd startEnd) {
542    HasLongPkOneToManyBidirChildrenJDO pojo = new HasLongPkOneToManyBidirChildrenJDO();
543    HasLongPkOneToManyBidirChildrenJDO.ChildA
544        a = new HasLongPkOneToManyBidirChildrenJDO.ChildA();
545    pojo.setChildAList(Utils.newArrayList(a));
546    startEnd.start();
547    pm.makePersistent(pojo);
548    startEnd.end();
549    startEnd.start();
550    pojo = pm.getObjectById(HasLongPkOneToManyBidirChildrenJDO.class, pojo.getId());
551    assertEquals(1, pojo.getChildAList().size());
552    assertEquals(pojo, pojo.getChildAList().get(0).getParent());
553    startEnd.end();
554  }
555
556  public void testUnencodedStringPkOneToManyBidirChildren() {
557    testUnencodedStringPkOneToManyBidirChildren(TXN_START_END);
558  }
559  public void testUnencodedStringPkOneToManyBidirChildren_NoTxn() {
560    switchDatasource(PersistenceManagerFactoryName.nontransactional);
561    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
562    testUnencodedStringPkOneToManyBidirChildren(NEW_PM_START_END);
563  }
564  private void testUnencodedStringPkOneToManyBidirChildren(StartEnd startEnd) {
565    HasUnencodedStringPkOneToManyBidirChildrenJDO pojo = new HasUnencodedStringPkOneToManyBidirChildrenJDO();
566    pojo.setId("yar");
567    HasUnencodedStringPkOneToManyBidirChildrenJDO.ChildA
568        a = new HasUnencodedStringPkOneToManyBidirChildrenJDO.ChildA();
569    pojo.setChildAList(Utils.newArrayList(a));
570    startEnd.start();
571    pm.makePersistent(pojo);
572    startEnd.end();
573    startEnd.start();
574    pojo = pm.getObjectById(HasUnencodedStringPkOneToManyBidirChildrenJDO.class, pojo.getId());
575    assertEquals(1, pojo.getChildAList().size());
576    assertEquals(pojo, pojo.getChildAList().get(0).getParent());
577    startEnd.end();
578  }
579
580  public void testFetchOfOneToManyParentWithKeyPk() {
581    testFetchOfOneToManyParentWithKeyPk(TXN_START_END);
582  }
583  public void testFetchOfOneToManyParentWithKeyPk_NoTxn() {
584    switchDatasource(PersistenceManagerFactoryName.nontransactional);
585    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
586    testFetchOfOneToManyParentWithKeyPk(NEW_PM_START_END);
587  }
588  private void testFetchOfOneToManyParentWithKeyPk(StartEnd startEnd) {
589    testFetchOfOneToManyParentWithKeyPk(new HasOneToManyKeyPkListJDO(), startEnd);
590  }
591
592  public void testFetchOfOneToManyParentWithLongPk() {
593    testFetchOfOneToManyParentWithLongPk(TXN_START_END);
594  }
595  public void testFetchOfOneToManyParentWithLongPk_NoTxn() {
596    switchDatasource(PersistenceManagerFactoryName.nontransactional);
597    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
598    testFetchOfOneToManyParentWithLongPk(NEW_PM_START_END);
599  }
600  private void testFetchOfOneToManyParentWithLongPk(StartEnd startEnd) {
601    testFetchOfOneToManyParentWithLongPk(new HasOneToManyLongPkListJDO(), startEnd);
602  }
603
604  public void testFetchOfOneToManyParentWithUnencodedStringPk() {
605    testFetchOfOneToManyParentWithUnencodedStringPk(TXN_START_END);
606  }
607  public void testFetchOfOneToManyParentWithUnencodedStringPk_NoTxn() {
608    switchDatasource(PersistenceManagerFactoryName.nontransactional);
609    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
610    testFetchOfOneToManyParentWithUnencodedStringPk(NEW_PM_START_END);
611  }
612  private void testFetchOfOneToManyParentWithUnencodedStringPk(StartEnd startEnd) {
613    testFetchOfOneToManyParentWithUnencodedStringPk(
614        new HasOneToManyUnencodedStringPkListJDO(), startEnd);
615  }
616
617  public void testAddChildToOneToManyParentWithLongPk() throws EntityNotFoundException {
618    testAddChildToOneToManyParentWithLongPk(TXN_START_END);
619  }
620  public void testAddChildToOneToManyParentWithLongPk_NoTxn() throws EntityNotFoundException {
621    switchDatasource(PersistenceManagerFactoryName.nontransactional);
622    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
623    testAddChildToOneToManyParentWithLongPk(NEW_PM_START_END);
624  }
625  private void testAddChildToOneToManyParentWithLongPk(StartEnd startEnd) throws EntityNotFoundException {
626    testAddChildToOneToManyParentWithLongPk(
627        new HasOneToManyLongPkListJDO(), new BidirectionalChildLongPkListJDO(), startEnd);
628  }
629
630  public void testAddChildToOneToManyParentWithUnencodedStringPk() throws EntityNotFoundException {
631    testAddChildToOneToManyParentWithUnencodedStringPk(TXN_START_END);
632  }
633  public void testAddChildToOneToManyParentWithUnencodedStringPk_NoTxn() throws EntityNotFoundException {
634    switchDatasource(PersistenceManagerFactoryName.nontransactional);
635    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
636    testAddChildToOneToManyParentWithUnencodedStringPk(NEW_PM_START_END);
637  }
638  private void testAddChildToOneToManyParentWithUnencodedStringPk(StartEnd startEnd) throws EntityNotFoundException {
639    testAddChildToOneToManyParentWithUnencodedStringPk(
640        new HasOneToManyUnencodedStringPkListJDO(), new BidirectionalChildUnencodedStringPkListJDO(),
641        startEnd);
642  }
643
644  public void testOneToManyChildAtMultipleLevels() {
645    testOneToManyChildAtMultipleLevels(TXN_START_END);
646  }
647  public void testOneToManyChildAtMultipleLevels_NoTxn() {
648    switchDatasource(PersistenceManagerFactoryName.nontransactional);
649    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
650    testOneToManyChildAtMultipleLevels(NEW_PM_START_END);
651  }
652  public void testOneToManyChildAtMultipleLevels(StartEnd startEnd) {
653    HasOneToManyChildAtMultipleLevelsJDO pojo = new HasOneToManyChildAtMultipleLevelsJDO();
654    Flight f1 = new Flight();
655    pojo.setFlights(Utils.newArrayList(f1));
656    HasOneToManyChildAtMultipleLevelsJDO child = new HasOneToManyChildAtMultipleLevelsJDO();
657    Flight f2 = new Flight();
658    child.setFlights(Utils.newArrayList(f2));
659    pojo.setChild(child);
660    startEnd.start();
661    pm.makePersistent(pojo);
662    startEnd.end();
663    startEnd.start();
664    assertEquals(2, countForClass(Flight.class));
665    pojo = pm.getObjectById(HasOneToManyChildAtMultipleLevelsJDO.class, pojo.getId());
666    assertEquals(child.getId(), pojo.getChild().getId());
667    assertEquals(1, pojo.getFlights().size());
668    assertTrue(pojo.getFlights().get(0).customEquals(f1));
669    assertTrue(child.getFlights().get(0).customEquals(f2));
670    assertEquals(1, child.getFlights().size());
671    startEnd.end();
672  }
673
674  public void testAddQueriedParentToBidirChild() throws EntityNotFoundException {
675    testAddQueriedParentToBidirChild(TXN_START_END);
676  }
677  public void testAddQueriedParentToBidirChild_NoTxn() throws EntityNotFoundException {
678    switchDatasource(PersistenceManagerFactoryName.nontransactional);
679    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
680    testAddQueriedParentToBidirChild(NEW_PM_START_END);
681  }
682  private void testAddQueriedParentToBidirChild(StartEnd startEnd) throws EntityNotFoundException {
683    testAddQueriedParentToBidirChild(
684        new HasOneToManyListJDO(), new BidirectionalChildListJDO(), startEnd);
685  }
686
687  public void testAddFetchedParentToBidirChild() throws EntityNotFoundException {
688    testAddFetchedParentToBidirChild(TXN_START_END);
689  }
690  public void testAddFetchedParentToBidirChild_NoTxn() throws EntityNotFoundException {
691    switchDatasource(PersistenceManagerFactoryName.nontransactional);
692    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
693    testAddFetchedParentToBidirChild(NEW_PM_START_END);
694  }
695  private void testAddFetchedParentToBidirChild(StartEnd startEnd) throws EntityNotFoundException {
696    testAddFetchedParentToBidirChild(
697        new HasOneToManyListJDO(), new BidirectionalChildListJDO(), startEnd);
698  }
699
700  public void testMultipleBidirChildren() {
701    testMultipleBidirChildren(TXN_START_END);
702  }
703  public void testMultipleBidirChildren_NoTxn() {
704    switchDatasource(PersistenceManagerFactoryName.nontransactional);
705    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
706    testMultipleBidirChildren(NEW_PM_START_END);
707  }
708  private void testMultipleBidirChildren(StartEnd startEnd) {
709    HasMultipleBidirChildrenJDO pojo = new HasMultipleBidirChildrenJDO();
710
711    HasMultipleBidirChildrenJDO.BidirChild1 c1 = new HasMultipleBidirChildrenJDO.BidirChild1();
712    HasMultipleBidirChildrenJDO.BidirChild2 c2 = new HasMultipleBidirChildrenJDO.BidirChild2();
713
714    pojo.getChild1().add(c1);
715    pojo.getChild2().add(c2);
716
717    startEnd.start();
718    pm.makePersistent(pojo);
719    startEnd.end();
720    startEnd.start();
721    pojo = pm.getObjectById(HasMultipleBidirChildrenJDO.class, pojo.getId());
722    assertEquals(1, pojo.getChild1().size());
723    assertEquals(1, pojo.getChild2().size());
724    startEnd.end();
725  }
726
727  public void testReplaceBidirColl() {
728    testReplaceBidirColl(TXN_START_END);
729  }
730  public void testReplaceBidirColl_NoTxn() {
731    switchDatasource(PersistenceManagerFactoryName.nontransactional);
732    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
733    testReplaceBidirColl(NEW_PM_START_END);
734  }
735  private void testReplaceBidirColl(StartEnd startEnd) {
736    Collection<BidirectionalChildJDO> childList = Utils.<BidirectionalChildJDO>newArrayList(
737        new BidirectionalChildListJDO(), new BidirectionalChildListJDO());
738    testReplaceBidirColl(
739        new HasOneToManyListJDO(), new BidirectionalChildListJDO(), childList, startEnd);
740  }
741
742  public void testDeleteChildWithSeparateNameField() {
743    testDeleteChildWithSeparateNameField(TXN_START_END);
744  }
745  public void testDeleteChildWithSeparateNameField_NoTxn() {
746    switchDatasource(PersistenceManagerFactoryName.nontransactional);
747    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
748    testDeleteChildWithSeparateNameField(NEW_PM_START_END);
749  }
750  private void testDeleteChildWithSeparateNameField(StartEnd startEnd) {
751    HasChildWithSeparateNameFieldJDO parent = new HasChildWithSeparateNameFieldJDO();
752    HasEncodedStringPkSeparateNameFieldJDO child = new HasEncodedStringPkSeparateNameFieldJDO();
753    child.setName("the name");
754    parent.getChildren().add(child);
755    startEnd.start();
756    pm.makePersistent(parent);
757    startEnd.end();
758    startEnd.start();
759    parent = pm.getObjectById(HasChildWithSeparateNameFieldJDO.class, parent.getId());
760    pm.deletePersistent(parent);
761    startEnd.end();
762  }
763
764  public void testOnlyOneParentPutOnParentAndChildUpdate() throws Throwable {
765    testOnlyOneParentPutOnParentAndChildUpdate(TXN_START_END);
766  }
767  public void testOnlyOneParentPutOnParentAndChildUpdate_NoTxn() throws Throwable {
768    switchDatasource(PersistenceManagerFactoryName.nontransactional);
769    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
770    testOnlyOneParentPutOnParentAndChildUpdate(NEW_PM_START_END);
771  }
772  private void testOnlyOneParentPutOnParentAndChildUpdate(StartEnd startEnd) throws Throwable {
773    testOnlyOneParentPutOnParentAndChildUpdate(
774        new HasOneToManyListJDO(), new BidirectionalChildListJDO(), startEnd);
775  }
776
777  public void testOnlyOnePutOnChildUpdate() throws Throwable {
778    testOnlyOnePutOnChildUpdate(TXN_START_END);
779  }
780  public void testOnlyOnePutOnChildUpdate_NoTxn() throws Throwable {
781    switchDatasource(PersistenceManagerFactoryName.nontransactional);
782    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
783    testOnlyOnePutOnChildUpdate(NEW_PM_START_END);
784  }
785  private void testOnlyOnePutOnChildUpdate(StartEnd startEnd) throws Throwable {
786    testOnlyOnePutOnChildUpdate(
787        new HasOneToManyListJDO(), new BidirectionalChildListJDO(), startEnd);
788  }
789
790  public void testOnlyOneParentPutOnChildDelete() throws Throwable {
791    testOnlyOneParentPutOnChildDelete(TXN_START_END);
792  }
793  public void testOnlyOneParentPutOnChildDelete_NoTxn() throws Throwable {
794    switchDatasource(PersistenceManagerFactoryName.nontransactional);
795    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
796    testOnlyOneParentPutOnChildDelete(NEW_PM_START_END);
797  }
798  private void testOnlyOneParentPutOnChildDelete(StartEnd startEnd) throws Throwable {
799    testOnlyOneParentPutOnChildDelete(
800        new HasOneToManyListJDO(), new BidirectionalChildListJDO(), startEnd);
801  }
802
803  public void testNonTxnAddOfChildToParentFailsPartwayThrough() throws Throwable {
804    testNonTxnAddOfChildToParentFailsPartwayThrough(new HasOneToManyListJDO());
805  }
806
807  public void xtestRemove2ObjectsAtIndex() {
808    testRemove2ObjectsAtIndex(TXN_START_END);
809  }
810  public void xtestRemove2ObjectsAtIndex_NoTxn() {
811    testRemove2ObjectsAtIndex(NEW_PM_START_END);
812  }
813  private void testRemove2ObjectsAtIndex(StartEnd startEnd) {
814    BidirectionalChildListJDO bidirChild1 = new BidirectionalChildListJDO();
815    BidirectionalChildListJDO bidirChild2 = new BidirectionalChildListJDO();
816    Flight f1 = newFlight();
817    Flight f2 = newFlight();
818
819    HasKeyPkJDO hasKeyPk1 = new HasKeyPkJDO();
820    HasKeyPkJDO hasKeyPk2 = new HasKeyPkJDO();
821
822    HasOneToManyListJDO parent = new HasOneToManyListJDO();
823    parent.addBidirChild(bidirChild1);
824    bidirChild1.setParent(parent);
825    parent.addBidirChild(bidirChild2);
826    bidirChild2.setParent(parent);
827    parent.addFlight(f1);
828    parent.addFlight(f2);
829    parent.addHasKeyPk(hasKeyPk1);
830    parent.addHasKeyPk(hasKeyPk2);
831
832    startEnd.start();
833    pm.makePersistent(parent);
834    startEnd.end();
835
836    startEnd.start();
837    parent = pm.getObjectById(parent.getClass(), parent.getId());
838    parent.getFlights().remove(0);
839    parent.getFlights().remove(0);
840//    parent.getBidirChildren().remove(0);
841//    parent.getBidirChildren().remove(0);
842//    parent.getHasKeyPks().remove(0);
843//    parent.getHasKeyPks().remove(0);
844    startEnd.end();
845
846    startEnd.start();
847    parent = pm.getObjectById(parent.getClass(), parent.getId());
848    assertTrue(parent.getFlights().isEmpty());
849//    assertTrue(parent.getBidirChildren().isEmpty());
850//    assertTrue(parent.getHasKeyPks().isEmpty());
851    startEnd.end();
852  }
853
854  @Override
855  boolean isIndexed() {
856    return true;
857  }
858}