PageRenderTime 116ms CodeModel.GetById 2ms app.highlight 105ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://datanucleus-appengine.googlecode.com/
Java | 1766 lines | 1488 code | 233 blank | 45 comment | 71 complexity | 89e8a951a15e466707cf5781702462f5 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/**********************************************************************
   2Copyright (c) 2011 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.DatastoreService;
  19import com.google.appengine.api.datastore.DatastoreServiceConfig;
  20import com.google.appengine.api.datastore.Entity;
  21import com.google.appengine.api.datastore.EntityNotFoundException;
  22import com.google.appengine.api.datastore.Key;
  23import com.google.appengine.api.datastore.KeyFactory;
  24import com.google.appengine.api.datastore.Query;
  25import com.google.appengine.api.datastore.Transaction;
  26import com.google.appengine.api.datastore.TransactionOptions;
  27import com.google.appengine.datanucleus.DatastoreServiceFactoryInternal;
  28import com.google.appengine.datanucleus.DatastoreServiceInterceptor;
  29import com.google.appengine.datanucleus.PolymorphicTestUtils;
  30import com.google.appengine.datanucleus.StorageVersion;
  31import com.google.appengine.datanucleus.Utils;
  32import com.google.appengine.datanucleus.Utils.Function;
  33import com.google.appengine.datanucleus.test.jdo.BidirectionalSuperclassTableChildJDO;
  34import com.google.appengine.datanucleus.test.jdo.UnidirectionalSuperclassTableChildJDO;
  35import com.google.appengine.datanucleus.test.jdo.BidirectionalSuperclassTableChildJDO.BidirTop;
  36import com.google.appengine.datanucleus.test.jdo.BidirectionalSuperclassTableChildJDO.BidirTopLongPk;
  37import com.google.appengine.datanucleus.test.jdo.BidirectionalSuperclassTableChildJDO.BidirTopUnencodedStringPkJDO;
  38import com.google.appengine.datanucleus.test.jdo.HasPolymorphicRelationsJDO.HasOneToManyJDO;
  39import com.google.appengine.datanucleus.test.jdo.HasPolymorphicRelationsJDO.HasOneToManyKeyPkJDO;
  40import com.google.appengine.datanucleus.test.jdo.HasPolymorphicRelationsJDO.HasOneToManyLongPkJDO;
  41import com.google.appengine.datanucleus.test.jdo.HasPolymorphicRelationsJDO.HasOneToManyUnencodedStringPkJDO;
  42import com.google.appengine.datanucleus.test.jdo.HasPolymorphicRelationsJDO.HasOneToManyWithOrderByJDO;
  43import com.google.appengine.datanucleus.test.jdo.UnidirectionalSuperclassTableChildJDO.UnidirBottom;
  44import com.google.appengine.datanucleus.test.jdo.UnidirectionalSuperclassTableChildJDO.UnidirMiddle;
  45import com.google.appengine.datanucleus.test.jdo.UnidirectionalSuperclassTableChildJDO.UnidirTop;
  46import com.google.appengine.datanucleus.test.jdo.UnidirectionalSuperclassTableChildJDO.UnidirTopWithIndexColumn;
  47
  48import org.easymock.EasyMock;
  49
  50import java.lang.reflect.Method;
  51import java.util.Collection;
  52import java.util.Collections;
  53import java.util.ConcurrentModificationException;
  54import java.util.Date;
  55import java.util.Iterator;
  56import java.util.List;
  57import java.util.Set;
  58
  59import javax.jdo.JDOFatalUserException;
  60import javax.jdo.PersistenceManager;
  61
  62import static com.google.appengine.datanucleus.PolymorphicTestUtils.getEntityKind;
  63
  64abstract class JDOOneToManyPolymorphicTestCase extends JDOTestCase {
  65  
  66  public enum UnidirLevel {
  67    Top(UnidirectionalSuperclassTableChildJDO.DISCRIMINATOR_TOP, UnidirTop.class),
  68    Middle(UnidirectionalSuperclassTableChildJDO.DISCRIMINATOR_MIDDLE, UnidirMiddle.class),
  69    Bottom(UnidirectionalSuperclassTableChildJDO.DISCRIMINATOR_BOTTOM, UnidirBottom.class);
  70
  71    final String discriminator;
  72    final Class<?> clazz;
  73    
  74    UnidirLevel(String discriminator,  Class<?> clazz) {
  75      this.discriminator = discriminator;
  76      this.clazz = clazz;
  77    }
  78    
  79  }
  80  
  81  public final StartEnd NEW_PM_DETACH_ON_CLOSE_START_END = new StartEnd() {
  82    public void start() {
  83      if (pm.isClosed()) {
  84        pm = pmf.getPersistenceManager();
  85        getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
  86      }
  87    }
  88
  89    public void end() {
  90      pm.close();
  91    }
  92
  93    public PersistenceManagerFactoryName getPmfName() {
  94      return PersistenceManagerFactoryName.nontransactional;
  95    }
  96  };
  97
  98  protected boolean hasIndexPropertyInChild(PersistenceManager pm) {
  99    return getStorageVersion(pm).ordinal() < StorageVersion.READ_OWNED_CHILD_KEYS_FROM_PARENTS.ordinal();
 100  }
 101
 102  @Override
 103  protected void tearDown() throws Exception {
 104    try {
 105      if (!pm.isClosed() && pm.currentTransaction().isActive()) {
 106        pm.currentTransaction().rollback();
 107      }
 108      pmf.close();
 109    } finally {
 110      super.tearDown();
 111    }
 112  }
 113
 114  void testInsert_NewParentAndChild(HasOneToManyJDO parent,
 115      BidirTop bidirChild, StartEnd startEnd, UnidirLevel unidirLevel,
 116      String expectedBidirKind, String expectedUnidirKind,
 117      int expectedParent, int expectedChildren) throws EntityNotFoundException {
 118    bidirChild.setChildVal("yam");
 119
 120    UnidirTop unidirChild = newUnidir(unidirLevel);
 121    String expectedStr = unidirChild.getStr();
 122
 123    parent.addBidirChild(bidirChild);
 124    bidirChild.setParent(parent);
 125    parent.addUnidirChild(unidirChild);
 126    parent.setVal("yar");
 127
 128    startEnd.start();
 129    pm.makePersistent(parent);
 130    startEnd.end();
 131
 132    assertNotNull(bidirChild.getId());
 133    assertNotNull(unidirChild.getId());
 134
 135    Entity bidirChildEntity = ds.get(KeyFactory.stringToKey(bidirChild.getId()));
 136    assertEquals(expectedBidirKind, bidirChildEntity.getKind());
 137    assertNotNull(bidirChildEntity);
 138    assertEquals(bidirChild.getClass().getName(), bidirChildEntity.getProperty("DISCRIMINATOR"));
 139
 140    int numProps = bidirChild.getPropertyCount();
 141    if (hasIndexPropertyInChild(pm)) {
 142      numProps += getIndexPropertyCount();
 143    }
 144    assertEquals(numProps, bidirChildEntity.getProperties().size());
 145
 146    assertEquals("yam", bidirChildEntity.getProperty("childVal"));
 147    assertEquals(KeyFactory.stringToKey(bidirChild.getId()), bidirChildEntity.getKey());
 148    PolymorphicTestUtils.assertKeyParentEquals(parent.getId(), bidirChildEntity, bidirChild.getId());
 149    if (isIndexed() && hasIndexPropertyInChild(pm)) {
 150      assertEquals(0L, bidirChildEntity.getProperty("bidirChildren_INTEGER_IDX"));
 151    }
 152
 153    Entity unidirEntity = ds.get(KeyFactory.stringToKey(unidirChild.getId()));
 154    assertEquals(expectedUnidirKind, unidirEntity.getKind());
 155    assertNotNull(unidirEntity);
 156    assertEquals(unidirLevel.discriminator, unidirEntity.getProperty("TYPE"));
 157    numProps = unidirChild.getPropertyCount();
 158    if (hasIndexPropertyInChild(pm)) {
 159      numProps += getIndexPropertyCount();
 160    }
 161    assertEquals(numProps, unidirEntity.getProperties().size());
 162    assertEquals(expectedStr, unidirEntity.getProperty("str"));
 163    assertEquals(KeyFactory.stringToKey(unidirChild.getId()), unidirEntity.getKey());
 164    PolymorphicTestUtils.assertKeyParentEquals(parent.getId(), unidirEntity, unidirChild.getId());
 165    if (isIndexed() && hasIndexPropertyInChild(pm)) {
 166      assertEquals(0L, unidirEntity.getProperty("unidirChildren_INTEGER_IDX"));
 167    }
 168
 169    Entity parentEntity = ds.get(KeyFactory.stringToKey(parent.getId()));
 170    assertNotNull(parentEntity);
 171    assertEquals(3, parentEntity.getProperties().size());
 172    assertEquals("yar", parentEntity.getProperty("val"));
 173    assertEquals(Utils.newArrayList(bidirChildEntity.getKey()), parentEntity.getProperty("bidirChildren"));
 174    assertEquals(Utils.newArrayList(unidirEntity.getKey()), parentEntity.getProperty("unidirChildren"));
 175
 176    assertCountsInDatastore(parent.getClass(), bidirChild.getClass(), expectedParent, expectedChildren);
 177  }
 178
 179  void testInsert_ExistingParentNewChild(HasOneToManyJDO pojo,
 180      BidirectionalSuperclassTableChildJDO.BidirTop bidirChild, StartEnd startEnd, UnidirLevel unidirLevel,
 181      String expectedBidirKind, String expectedUnidirKind,
 182      int expectedParent, int expectedChildren) throws EntityNotFoundException {
 183    pojo.setVal("yar");
 184
 185    startEnd.start();
 186    pm.makePersistent(pojo);
 187    startEnd.end();
 188    
 189    startEnd.start();
 190    assertNotNull(pojo.getId());
 191    assertTrue(pojo.getUnidirChildren().isEmpty());
 192    assertTrue(pojo.getBidirChildren().isEmpty());
 193
 194    Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 195    assertNotNull(pojoEntity);
 196    assertEquals(3, pojoEntity.getProperties().size());
 197    assertEquals("yar", pojoEntity.getProperty("val"));
 198    assertTrue(pojoEntity.hasProperty("bidirChildren"));
 199    assertNull(pojoEntity.getProperty("bidirChildren"));
 200    assertTrue(pojoEntity.hasProperty("unidirChildren"));
 201    assertNull(pojoEntity.getProperty("unidirChildren"));
 202    startEnd.end();
 203    
 204    startEnd.start();
 205    pojo = pm.makePersistent(pojo);
 206    assertEquals("yar", pojo.getVal());
 207    UnidirTop unidirChild = newUnidir(unidirLevel);
 208    String exepectedStr = unidirChild.getStr();
 209    pojo.addUnidirChild(unidirChild);
 210    bidirChild.setChildVal("yam");
 211    pojo.addBidirChild(bidirChild);
 212    startEnd.end();
 213
 214    startEnd.start();
 215    assertNotNull(bidirChild.getId());
 216    assertNotNull(bidirChild.getParent());
 217    assertNotNull(unidirChild.getId());
 218    startEnd.end();
 219    
 220    Entity bidirChildEntity = ds.get(KeyFactory.stringToKey(bidirChild.getId()));
 221    assertNotNull(bidirChildEntity);
 222    assertEquals(expectedBidirKind, bidirChildEntity.getKind());
 223
 224    int numProps = bidirChild.getPropertyCount();
 225    if (hasIndexPropertyInChild(pm)) {
 226      numProps += getIndexPropertyCount();
 227    }
 228    assertEquals(numProps, bidirChildEntity.getProperties().size());
 229
 230    assertEquals(bidirChild.getClass().getName(), bidirChildEntity.getProperty("DISCRIMINATOR"));
 231    assertEquals("yam", bidirChildEntity.getProperty("childVal"));
 232    assertEquals(KeyFactory.stringToKey(bidirChild.getId()), bidirChildEntity.getKey());
 233    PolymorphicTestUtils.assertKeyParentEquals(pojo.getId(), bidirChildEntity, bidirChild.getId());
 234    if (isIndexed() && hasIndexPropertyInChild(pm)) {
 235      assertEquals(0L, bidirChildEntity.getProperty("bidirChildren_INTEGER_IDX"));
 236    }
 237
 238    Entity unidirChildEntity = ds.get(KeyFactory.stringToKey(unidirChild.getId()));
 239    assertNotNull(unidirChildEntity);
 240    assertEquals(expectedUnidirKind, unidirChildEntity.getKind());
 241    numProps = unidirChild.getPropertyCount();
 242    if (hasIndexPropertyInChild(pm)) {
 243      numProps += getIndexPropertyCount();
 244    }
 245    assertEquals(numProps, unidirChildEntity.getProperties().size());
 246    assertEquals(unidirLevel.discriminator, unidirChildEntity.getProperty("TYPE"));
 247    assertEquals(exepectedStr, unidirChildEntity.getProperty("str"));
 248    assertEquals(KeyFactory.stringToKey(unidirChild.getId()), unidirChildEntity.getKey());
 249    PolymorphicTestUtils.assertKeyParentEquals(pojo.getId(), unidirChildEntity, unidirChild.getId());
 250    if (isIndexed() && hasIndexPropertyInChild(pm)) {
 251      assertEquals(0L, unidirChildEntity.getProperty("unidirChildren_INTEGER_IDX"));
 252    }
 253
 254    Entity parentEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 255    assertNotNull(parentEntity);
 256    assertEquals(3, parentEntity.getProperties().size());
 257    assertEquals("yar", parentEntity.getProperty("val"));
 258    assertEquals(Utils.newArrayList(bidirChildEntity.getKey()), parentEntity.getProperty("bidirChildren"));
 259    assertEquals(Utils.newArrayList(unidirChildEntity.getKey()), parentEntity.getProperty("unidirChildren"));
 260
 261    assertCountsInDatastore(pojo.getClass(), bidirChild.getClass(), expectedParent, expectedChildren);
 262  }
 263
 264  void testSwapAtPosition(HasOneToManyJDO pojo,
 265      BidirectionalSuperclassTableChildJDO.BidirTop bidir1,
 266      BidirectionalSuperclassTableChildJDO.BidirTop bidir2, StartEnd startEnd,
 267      String expectedBidirKind, String expectedUnidirKind,
 268      int expectedParent, int expectedChildren) throws EntityNotFoundException {
 269    pojo.setVal("yar");
 270    bidir2.setChildVal("yam");
 271    UnidirTop unidir = newUnidir(UnidirLevel.Middle);
 272
 273    pojo.addUnidirChild(unidir);
 274    pojo.addBidirChild(bidir1);
 275    bidir1.setParent(pojo);
 276
 277    startEnd.start();
 278    pm.makePersistent(pojo);
 279    startEnd.end();
 280
 281    assertCountsInDatastore(pojo.getClass(), bidir1.getClass(), expectedParent, expectedChildren);
 282
 283    startEnd.start();
 284    pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
 285    String bidir1Id = pojo.getBidirChildren().iterator().next().getId();
 286    String unidir1Id = pojo.getUnidirChildren().iterator().next().getId();
 287    pojo.addBidirChildAtPosition(bidir2, 0);
 288
 289    UnidirTop unidir2 = newUnidir(UnidirLevel.Top);
 290    unidir2.setStr("another str");
 291    pojo.addUnidirAtPosition(unidir2, 0);
 292    startEnd.end();
 293
 294    startEnd.start();
 295    pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
 296    assertNotNull(pojo.getId());
 297    assertEquals(1, pojo.getUnidirChildren().size());
 298    assertEquals(1, pojo.getBidirChildren().size());
 299    assertNotNull(bidir2.getId());
 300    assertNotNull(bidir2.getParent());
 301    assertNotNull(unidir2.getId());
 302
 303    Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 304    assertNotNull(pojoEntity);
 305    assertEquals(3, pojoEntity.getProperties().size());
 306    assertEquals(Utils.newArrayList(KeyFactory.stringToKey(bidir2.getId())), pojoEntity.getProperty("bidirChildren"));
 307    assertEquals(Utils.newArrayList(KeyFactory.stringToKey(unidir2.getId())), pojoEntity.getProperty("unidirChildren"));
 308    startEnd.end();
 309
 310    try {
 311      ds.get(KeyFactory.stringToKey(bidir1Id));
 312      fail("expected EntityNotFoundException");
 313    } catch (EntityNotFoundException enfe) {
 314      // good
 315    }
 316    try {
 317      ds.get(KeyFactory.stringToKey(unidir1Id));
 318      fail("expected EntityNotFoundException");
 319    } catch (EntityNotFoundException enfe) {
 320      // good
 321    }
 322
 323    Entity bidirChildEntity = ds.get(KeyFactory.stringToKey(bidir2.getId()));
 324    assertNotNull(bidirChildEntity);
 325    assertEquals(expectedBidirKind, bidirChildEntity.getKind());
 326    int numProps = bidir2.getPropertyCount();
 327    if (hasIndexPropertyInChild(pm)) {
 328      numProps += getIndexPropertyCount();
 329    }
 330    assertEquals(numProps, bidirChildEntity.getProperties().size());
 331    assertEquals(bidir2.getClass().getName(), bidirChildEntity.getProperty("DISCRIMINATOR"));
 332    assertEquals("yam", bidirChildEntity.getProperty("childVal"));
 333    assertEquals(KeyFactory.stringToKey(bidir2.getId()), bidirChildEntity.getKey());
 334    PolymorphicTestUtils.assertKeyParentEquals(pojo.getId(), bidirChildEntity, bidir2.getId());
 335    if (isIndexed() && hasIndexPropertyInChild(pm)) {
 336      assertEquals(0L, bidirChildEntity.getProperty("bidirChildren_INTEGER_IDX"));
 337    }
 338
 339    Entity unidirChildEntity = ds.get(KeyFactory.stringToKey(unidir2.getId()));
 340    assertNotNull(unidirChildEntity);
 341    assertEquals(expectedUnidirKind, unidirChildEntity.getKind());
 342    numProps = unidir2.getPropertyCount();
 343    if (hasIndexPropertyInChild(pm)) {
 344      numProps += getIndexPropertyCount();
 345    }
 346    assertEquals(numProps, unidirChildEntity.getProperties().size());
 347    assertEquals(UnidirLevel.Top.discriminator, unidirChildEntity.getProperty("TYPE"));
 348    assertEquals("another str", unidirChildEntity.getProperty("str"));
 349    assertEquals(KeyFactory.stringToKey(unidir2.getId()), unidirChildEntity.getKey());
 350    PolymorphicTestUtils.assertKeyParentEquals(pojo.getId(), unidirChildEntity, unidir2.getId());
 351    if (isIndexed() && hasIndexPropertyInChild(pm)) {
 352      assertEquals(0L, unidirChildEntity.getProperty("unidirChildren_INTEGER_IDX"));
 353    }
 354
 355    Entity parentEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 356    assertNotNull(parentEntity);
 357    assertEquals(3, parentEntity.getProperties().size());
 358    assertEquals("yar", parentEntity.getProperty("val"));
 359    assertEquals(Utils.newArrayList(bidirChildEntity.getKey()), parentEntity.getProperty("bidirChildren"));
 360    assertEquals(Utils.newArrayList(unidirChildEntity.getKey()), parentEntity.getProperty("unidirChildren"));
 361
 362    assertCountsInDatastore(pojo.getClass(), bidir2.getClass(), expectedParent, expectedChildren);
 363  }
 364
 365  void testRemoveAtPosition(HasOneToManyJDO pojo,
 366      BidirectionalSuperclassTableChildJDO.BidirTop bidir1,
 367      BidirectionalSuperclassTableChildJDO.BidirTop bidir2,
 368      BidirectionalSuperclassTableChildJDO.BidirTop bidir3, StartEnd startEnd,
 369      String expectedBidirKind, String expectedUnidirKind,
 370      int count) throws EntityNotFoundException {
 371    pojo.setVal("yar");
 372    bidir2.setChildVal("another yam");
 373    bidir3.setChildVal("yet another yam");
 374    UnidirTop unidir = newUnidir(UnidirLevel.Top);
 375    UnidirTop unidir2 = newUnidir(UnidirLevel.Bottom);
 376    UnidirTop unidir3 = newUnidir(UnidirLevel.Middle);
 377    unidir2.setStr("another str");
 378    unidir3.setStr("yet another str");
 379
 380    pojo.addUnidirChild(unidir);
 381    pojo.addUnidirChild(unidir2);
 382    pojo.addUnidirChild(unidir3);
 383    pojo.addBidirChild(bidir1);
 384    pojo.addBidirChild(bidir2);
 385    pojo.addBidirChild(bidir3);
 386
 387    startEnd.start();
 388    pm.makePersistent(pojo);
 389    startEnd.end();
 390
 391    assertCountsInDatastore(pojo.getClass(), bidir1.getClass(), count, (count-1) * 2 + 3);
 392
 393    startEnd.start();
 394    pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
 395    String bidir1Id = pojo.getBidirChildren().iterator().next().getId();
 396    String unidir1Id = pojo.getUnidirChildren().iterator().next().getId();
 397    pojo.removeBidirChildAtPosition(0);
 398    pojo.removeUnidirChildAtPosition(0);
 399    startEnd.end();
 400
 401    startEnd.start();
 402    assertNotNull(pojo.getId());
 403    assertEquals(2, pojo.getUnidirChildren().size());
 404    assertEquals(2, pojo.getBidirChildren().size());
 405
 406    Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 407    assertNotNull(pojoEntity);
 408    assertEquals(3, pojoEntity.getProperties().size());
 409    assertEquals(Utils.newArrayList(
 410        KeyFactory.stringToKey(bidir2.getId()),
 411        KeyFactory.stringToKey(bidir3.getId())), pojoEntity.getProperty("bidirChildren"));
 412    assertEquals(Utils.newArrayList(
 413        KeyFactory.stringToKey(unidir2.getId()),
 414        KeyFactory.stringToKey(unidir3.getId())), pojoEntity.getProperty("unidirChildren"));
 415    startEnd.end();
 416
 417    try {
 418      ds.get(KeyFactory.stringToKey(bidir1Id));
 419      fail("expected EntityNotFoundException");
 420    } catch (EntityNotFoundException enfe) {
 421      // good
 422    }
 423    try {
 424      ds.get(KeyFactory.stringToKey(unidir1Id));
 425      fail("expected EntityNotFoundException");
 426    } catch (EntityNotFoundException enfe) {
 427      // good
 428    }
 429
 430    Entity bidirChildEntity = ds.get(KeyFactory.stringToKey(bidir2.getId()));
 431    assertNotNull(bidirChildEntity);
 432    assertEquals(expectedBidirKind, bidirChildEntity.getKind());
 433    int numProps = bidir2.getPropertyCount();
 434    if (hasIndexPropertyInChild(pm)) {
 435      numProps += getIndexPropertyCount();
 436    }
 437    assertEquals(numProps, bidirChildEntity.getProperties().size());
 438    assertEquals(bidir2.getClass().getName(), bidirChildEntity.getProperty("DISCRIMINATOR"));
 439    assertEquals("another yam", bidirChildEntity.getProperty("childVal"));
 440    assertEquals(KeyFactory.stringToKey(bidir2.getId()), bidirChildEntity.getKey());
 441    PolymorphicTestUtils.assertKeyParentEquals(pojo.getId(), bidirChildEntity, bidir2.getId());
 442    if (isIndexed() && hasIndexPropertyInChild(pm)) {
 443      assertEquals(0L, bidirChildEntity.getProperty("bidirChildren_INTEGER_IDX"));
 444    }
 445
 446    bidirChildEntity = ds.get(KeyFactory.stringToKey(bidir3.getId()));
 447    assertNotNull(bidirChildEntity);
 448    assertEquals(expectedBidirKind, bidirChildEntity.getKind());
 449    numProps = bidir3.getPropertyCount();
 450    if (hasIndexPropertyInChild(pm)) {
 451      numProps += getIndexPropertyCount();
 452    }
 453    assertEquals(numProps, bidirChildEntity.getProperties().size());
 454    assertEquals(bidir3.getClass().getName(), bidirChildEntity.getProperty("DISCRIMINATOR"));
 455    assertEquals("yet another yam", bidirChildEntity.getProperty("childVal"));
 456    assertEquals(KeyFactory.stringToKey(bidir3.getId()), bidirChildEntity.getKey());
 457    PolymorphicTestUtils.assertKeyParentEquals(pojo.getId(), bidirChildEntity, bidir2.getId());
 458    if (isIndexed() && hasIndexPropertyInChild(pm)) {
 459      assertEquals(1L, bidirChildEntity.getProperty("bidirChildren_INTEGER_IDX"));
 460    }
 461
 462    Entity unidirChildEntity = ds.get(KeyFactory.stringToKey(unidir2.getId()));
 463    assertNotNull(unidirChildEntity);
 464    assertEquals(expectedUnidirKind, unidirChildEntity.getKind());
 465    numProps = unidir2.getPropertyCount();
 466    if (hasIndexPropertyInChild(pm)) {
 467      numProps += getIndexPropertyCount();
 468    }
 469    assertEquals(numProps, unidirChildEntity.getProperties().size());
 470    assertEquals(UnidirLevel.Bottom.discriminator, unidirChildEntity.getProperty("TYPE"));
 471    assertEquals("another str", unidirChildEntity.getProperty("str"));
 472    assertEquals(KeyFactory.stringToKey(unidir2.getId()), unidirChildEntity.getKey());
 473    PolymorphicTestUtils.assertKeyParentEquals(pojo.getId(), unidirChildEntity, unidir2.getId());
 474    if (isIndexed() && hasIndexPropertyInChild(pm)) {
 475      assertEquals(0L, unidirChildEntity.getProperty("unidirChildren_INTEGER_IDX"));
 476    }
 477
 478    unidirChildEntity = ds.get(KeyFactory.stringToKey(unidir3.getId()));
 479    assertNotNull(unidirChildEntity);
 480    assertEquals(expectedUnidirKind, unidirChildEntity.getKind());
 481    assertEquals(UnidirLevel.Middle.discriminator, unidirChildEntity.getProperty("TYPE"));
 482    assertEquals("yet another str", unidirChildEntity.getProperty("str"));
 483    assertEquals(KeyFactory.stringToKey(unidir3.getId()), unidirChildEntity.getKey());
 484    PolymorphicTestUtils.assertKeyParentEquals(pojo.getId(), unidirChildEntity, unidir2.getId());
 485    if (isIndexed() && hasIndexPropertyInChild(pm)) {
 486      assertEquals(1L, unidirChildEntity.getProperty("unidirChildren_INTEGER_IDX"));
 487    }
 488
 489    Entity parentEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 490    assertNotNull(parentEntity);
 491    assertEquals(3, parentEntity.getProperties().size());
 492    assertEquals("yar", parentEntity.getProperty("val"));
 493    assertEquals(Utils.newArrayList(
 494        KeyFactory.stringToKey(bidir2.getId()),
 495        KeyFactory.stringToKey(bidir3.getId())), parentEntity.getProperty("bidirChildren"));
 496    assertEquals(Utils.newArrayList(
 497        KeyFactory.stringToKey(unidir2.getId()),
 498        KeyFactory.stringToKey(unidir3.getId())), parentEntity.getProperty("unidirChildren"));
 499
 500    assertCountsInDatastore(pojo.getClass(), bidir2.getClass(), count, 2 * count);
 501  }
 502
 503  void testAddAtPosition(HasOneToManyJDO pojo,
 504      BidirectionalSuperclassTableChildJDO.BidirTop bidir1,
 505      BidirectionalSuperclassTableChildJDO.BidirTop bidir2, StartEnd startEnd,
 506      String expectedBidirKind, String expectedUnidirKind, int count) throws EntityNotFoundException {
 507    pojo.setVal("yar");
 508    bidir2.setChildVal("yam");
 509    UnidirTop unidir = newUnidir(UnidirLevel.Middle);
 510    UnidirTop unidir2 = newUnidir(UnidirLevel.Bottom);
 511    unidir2.setStr("another str");
 512
 513    pojo.addUnidirChild(unidir);
 514    pojo.addBidirChild(bidir1);
 515
 516    startEnd.start();
 517    pm.makePersistent(pojo);
 518    startEnd.end();
 519
 520    assertCountsInDatastore(pojo.getClass(), bidir1.getClass(), count, 2 *(count-1) + 1);
 521
 522    startEnd.start();
 523    pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
 524    String bidir1Id = pojo.getBidirChildren().iterator().next().getId();
 525    String unidir1Id = pojo.getUnidirChildren().iterator().next().getId();
 526    pojo.addAtPosition(0, bidir2);
 527    pojo.addAtPosition(0, unidir2);
 528    startEnd.end();
 529
 530    startEnd.start();
 531    pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
 532    assertNotNull(pojo.getId());
 533    assertEquals(2, pojo.getUnidirChildren().size());
 534    assertEquals(2, pojo.getBidirChildren().size());
 535    assertNotNull(bidir2.getId());
 536    assertNotNull(bidir2.getParent());
 537    assertNotNull(unidir2.getId());
 538
 539    Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 540    assertNotNull(pojoEntity);
 541    assertEquals(3, pojoEntity.getProperties().size());
 542    assertEquals(Utils.newArrayList(
 543        KeyFactory.stringToKey(bidir2.getId()),
 544        KeyFactory.stringToKey(bidir1.getId())), pojoEntity.getProperty("bidirChildren"));
 545    assertEquals(Utils.newArrayList(
 546        KeyFactory.stringToKey(unidir2.getId()),
 547        KeyFactory.stringToKey(unidir.getId())), pojoEntity.getProperty("unidirChildren"));
 548    startEnd.end();
 549
 550    ds.get(KeyFactory.stringToKey(bidir1Id));
 551    ds.get(KeyFactory.stringToKey(unidir1Id));
 552    Entity bidirChildEntity = ds.get(KeyFactory.stringToKey(bidir2.getId()));
 553    assertNotNull(bidirChildEntity);
 554    assertEquals(expectedBidirKind, bidirChildEntity.getKind());
 555    int numProps = bidir2.getPropertyCount();
 556    if (hasIndexPropertyInChild(pm)) {
 557      numProps += getIndexPropertyCount();
 558    }
 559    assertEquals(numProps, bidirChildEntity.getProperties().size());
 560    assertEquals(bidir2.getClass().getName(), bidirChildEntity.getProperty("DISCRIMINATOR"));
 561    assertEquals("yam", bidirChildEntity.getProperty("childVal"));
 562    assertEquals(KeyFactory.stringToKey(bidir2.getId()), bidirChildEntity.getKey());
 563    PolymorphicTestUtils.assertKeyParentEquals(pojo.getId(), bidirChildEntity, bidir2.getId());
 564    if (isIndexed() && hasIndexPropertyInChild(pm)) {
 565      assertEquals(0L, bidirChildEntity.getProperty("bidirChildren_INTEGER_IDX"));
 566    }
 567
 568    Entity unidirChildEntity = ds.get(KeyFactory.stringToKey(unidir2.getId()));
 569    assertNotNull(unidirChildEntity);
 570    assertEquals(expectedUnidirKind, unidirChildEntity.getKind());
 571    numProps = unidir2.getPropertyCount();
 572    if (hasIndexPropertyInChild(pm)) {
 573      numProps += getIndexPropertyCount();
 574    }
 575    assertEquals(numProps, unidirChildEntity.getProperties().size());
 576    assertEquals(UnidirLevel.Bottom.discriminator, unidirChildEntity.getProperty("TYPE"));
 577    assertEquals("another str", unidirChildEntity.getProperty("str"));
 578    assertEquals(KeyFactory.stringToKey(unidir2.getId()), unidirChildEntity.getKey());
 579    PolymorphicTestUtils.assertKeyParentEquals(pojo.getId(), unidirChildEntity, unidir2.getId());
 580    if (isIndexed() && hasIndexPropertyInChild(pm)) {
 581      assertEquals(0L, unidirChildEntity.getProperty("unidirChildren_INTEGER_IDX"));
 582    }
 583
 584    Entity parentEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 585    assertNotNull(parentEntity);
 586    assertEquals(3, parentEntity.getProperties().size());
 587    assertEquals("yar", parentEntity.getProperty("val"));
 588    assertEquals(Utils.newArrayList(
 589        KeyFactory.stringToKey(bidir2.getId()),
 590        KeyFactory.stringToKey(bidir1.getId())), parentEntity.getProperty("bidirChildren"));
 591    assertEquals(Utils.newArrayList(
 592        KeyFactory.stringToKey(unidir2.getId()),
 593        KeyFactory.stringToKey(unidir.getId())), parentEntity.getProperty("unidirChildren"));
 594
 595    assertCountsInDatastore(pojo.getClass(), bidir2.getClass(), count, 2 * count);
 596  }
 597
 598  void testUpdate_UpdateChildWithMerge(HasOneToManyJDO pojo,
 599      BidirectionalSuperclassTableChildJDO.BidirTop bidir, StartEnd startEnd,
 600      String expectedBidirKind, String expectedUnidirKind, 
 601      UnidirLevel unidirLevel, int count) throws EntityNotFoundException {
 602    UnidirTop unidir = newUnidir(unidirLevel);
 603
 604    pojo.addUnidirChild(unidir);
 605    pojo.addBidirChild(bidir);
 606    bidir.setParent(pojo);
 607
 608    startEnd.start();
 609    pm.makePersistent(pojo);
 610    startEnd.end();
 611
 612    assertNotNull(unidir.getId());
 613    assertNotNull(bidir.getId());
 614    assertNotNull(pojo.getId());
 615
 616    startEnd.start();
 617    unidir.setStr("yam");
 618    bidir.setChildVal("yap");
 619    pm.makePersistent(pojo);
 620    startEnd.end();
 621
 622    Entity unidirChildEntity = ds.get(KeyFactory.stringToKey(unidir.getId()));
 623    assertNotNull(unidirChildEntity);
 624    assertEquals(expectedUnidirKind, unidirChildEntity.getKind());
 625    int numProps = unidir.getPropertyCount();
 626    if (hasIndexPropertyInChild(pm)) {
 627      numProps += getIndexPropertyCount();
 628    }
 629    assertEquals(numProps, unidirChildEntity.getProperties().size());
 630    assertEquals(unidirLevel.discriminator, unidirChildEntity.getProperty("TYPE"));
 631    assertEquals("yam", unidirChildEntity.getProperty("str"));
 632    PolymorphicTestUtils.assertKeyParentEquals(pojo.getId(), unidirChildEntity, unidir.getId());
 633    if (isIndexed() && hasIndexPropertyInChild(pm)) {
 634      assertEquals(0L, unidirChildEntity.getProperty("unidirChildren_INTEGER_IDX"));
 635    }
 636
 637    Entity bidirEntity = ds.get(KeyFactory.stringToKey(bidir.getId()));
 638    assertNotNull(bidirEntity);
 639    assertEquals(expectedBidirKind, bidirEntity.getKind());
 640    numProps = bidir.getPropertyCount();
 641    if (hasIndexPropertyInChild(pm)) {
 642      numProps += getIndexPropertyCount();
 643    }
 644    assertEquals(numProps, bidirEntity.getProperties().size());
 645    assertEquals(bidir.getClass().getName(), bidirEntity.getProperty("DISCRIMINATOR"));
 646    assertEquals("yap", bidirEntity.getProperty("childVal"));
 647    PolymorphicTestUtils.assertKeyParentEquals(pojo.getId(), bidirEntity, bidir.getId());
 648    if (isIndexed() && hasIndexPropertyInChild(pm)) {
 649      assertEquals(0L, bidirEntity.getProperty("bidirChildren_INTEGER_IDX"));
 650    }
 651
 652    assertCountsInDatastore(pojo.getClass(), bidir.getClass(), count, count);
 653  }
 654
 655  
 656  void testUpdate_UpdateChild(HasOneToManyJDO pojo,
 657      BidirectionalSuperclassTableChildJDO.BidirTop bidir, StartEnd startEnd,
 658      String expectedBidirKind, String expectedUnidirKind, 
 659      UnidirLevel unidirLevel, int count) throws EntityNotFoundException {
 660    UnidirTop unidir = newUnidir(unidirLevel);
 661
 662    pojo.addUnidirChild(unidir);
 663    pojo.addBidirChild(bidir);
 664    bidir.setParent(pojo);
 665
 666    startEnd.start();
 667    pm.makePersistent(pojo);
 668    startEnd.end();
 669
 670    assertNotNull(unidir.getId());
 671    assertNotNull(bidir.getId());
 672    assertNotNull(pojo.getId());
 673
 674    startEnd.start();
 675    pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
 676    pojo.getUnidirChildren().iterator().next().setStr("yam");
 677    pojo.getBidirChildren().iterator().next().setChildVal("yap");
 678    startEnd.end();
 679
 680    Entity unidirChildEntity = ds.get(KeyFactory.stringToKey(unidir.getId()));
 681    assertNotNull(unidirChildEntity);
 682    assertEquals(expectedUnidirKind, unidirChildEntity.getKind());
 683    int numProps = unidir.getPropertyCount();
 684    if (hasIndexPropertyInChild(pm)) {
 685      numProps += getIndexPropertyCount();
 686    }
 687    assertEquals(numProps, unidirChildEntity.getProperties().size());
 688    assertEquals(unidirLevel.discriminator, unidirChildEntity.getProperty("TYPE"));
 689    assertEquals("yam", unidirChildEntity.getProperty("str"));
 690    PolymorphicTestUtils.assertKeyParentEquals(pojo.getId(), unidirChildEntity, unidir.getId());
 691    if (isIndexed() && hasIndexPropertyInChild(pm)) {
 692      assertEquals(0L, unidirChildEntity.getProperty("unidirChildren_INTEGER_IDX"));
 693    }
 694
 695    Entity bidirEntity = ds.get(KeyFactory.stringToKey(bidir.getId()));
 696    assertNotNull(bidirEntity);
 697    assertEquals(expectedBidirKind, bidirEntity.getKind());
 698    numProps = bidir.getPropertyCount();
 699    if (hasIndexPropertyInChild(pm)) {
 700      numProps += getIndexPropertyCount();
 701    }
 702    assertEquals(numProps, bidirEntity.getProperties().size());
 703    assertEquals(bidir.getClass().getName(), bidirEntity.getProperty("DISCRIMINATOR"));
 704    assertEquals("yap", bidirEntity.getProperty("childVal"));
 705    PolymorphicTestUtils.assertKeyParentEquals(pojo.getId(), bidirEntity, bidir.getId());
 706    if (isIndexed() && hasIndexPropertyInChild(pm)) {
 707      assertEquals(0L, bidirEntity.getProperty("bidirChildren_INTEGER_IDX"));
 708    }
 709
 710    assertCountsInDatastore(pojo.getClass(), bidir.getClass(), count, count);
 711  }
 712
 713  
 714  void testUpdate_NullOutChildren(HasOneToManyJDO pojo,
 715    BidirectionalSuperclassTableChildJDO.BidirTop bidir, StartEnd startEnd,
 716    UnidirLevel unidirLevel, int count) throws EntityNotFoundException {
 717    UnidirTop unidir = newUnidir(unidirLevel);
 718
 719    pojo.addUnidirChild(unidir);
 720    pojo.addBidirChild(bidir);
 721    bidir.setParent(pojo);
 722
 723    startEnd.start();
 724    pm.makePersistent(pojo);
 725    startEnd.end();
 726
 727    assertCountsInDatastore(pojo.getClass(), bidir.getClass(), count, 1);
 728
 729    startEnd.start();
 730    String unidirId = unidir.getId();
 731    String bidirChildId = bidir.getId();
 732
 733    pojo.nullUnidirChildren();
 734    pojo.nullBidirChildren();
 735    pm.makePersistent(pojo);
 736    startEnd.end();
 737
 738    try {
 739      ds.get(KeyFactory.stringToKey(unidirId));
 740      fail("expected enfe");
 741    } catch (EntityNotFoundException enfe) {
 742      // good
 743    }
 744
 745    try {
 746      ds.get(KeyFactory.stringToKey(bidirChildId));
 747      fail("expected enfe");
 748    } catch (EntityNotFoundException enfe) {
 749      // good
 750    }
 751
 752    Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 753    assertEquals(3, pojoEntity.getProperties().size());
 754    assertTrue(pojoEntity.hasProperty("bidirChildren"));
 755    assertNull(pojoEntity.getProperty("bidirChildren"));
 756    assertTrue(pojoEntity.hasProperty("unidirChildren"));
 757    assertNull(pojoEntity.getProperty("unidirChildren"));
 758
 759    assertCountsInDatastore(pojo.getClass(), bidir.getClass(), count, 0);
 760  }
 761
 762  
 763  void testUpdate_ClearOutChildren(HasOneToManyJDO pojo,
 764      BidirectionalSuperclassTableChildJDO.BidirTop bidir, StartEnd startEnd,
 765      UnidirLevel unidirLevel, int count) throws EntityNotFoundException {
 766    UnidirTop unidir = newUnidir(unidirLevel);
 767
 768    pojo.addUnidirChild(unidir);
 769    pojo.addBidirChild(bidir);
 770    bidir.setParent(pojo);
 771
 772    startEnd.start();
 773    pm.makePersistent(pojo);
 774    startEnd.end();
 775    String unidirId = unidir.getId();
 776    String bidirChildId = bidir.getId();
 777    assertCountsInDatastore(pojo.getClass(), bidir.getClass(), count, 1);
 778
 779    startEnd.start();
 780    pojo = pm.makePersistent(pojo);
 781    pojo.clearUnidirChildren();
 782    pojo.clearBidirChildren();
 783    startEnd.end();
 784
 785    try {
 786      ds.get(KeyFactory.stringToKey(unidirId));
 787      fail("expected enfe");
 788    } catch (EntityNotFoundException enfe) {
 789      // good
 790    }
 791
 792    try {
 793      ds.get(KeyFactory.stringToKey(bidirChildId));
 794      fail("expected enfe");
 795    } catch (EntityNotFoundException enfe) {
 796      // good
 797    }
 798
 799    Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 800    assertEquals(3, pojoEntity.getProperties().size());
 801    assertTrue(pojoEntity.hasProperty("bidirChildren"));
 802    assertNull(pojoEntity.getProperty("bidirChildren"));
 803    assertTrue(pojoEntity.hasProperty("unidirChildren"));
 804    assertNull(pojoEntity.getProperty("unidirChildren"));
 805
 806    assertCountsInDatastore(pojo.getClass(), bidir.getClass(), count, 0);
 807  }
 808
 809  void testFindWithOrderBy(Class<? extends HasOneToManyWithOrderByJDO> pojoClass, StartEnd startEnd)
 810      throws EntityNotFoundException {
 811    getExecutionContext().getNucleusContext().getPersistenceConfiguration().setProperty(
 812        "datanucleus.appengine.allowMultipleRelationsOfSameType", true);
 813    Entity pojoEntity = new Entity(getEntityKind(pojoClass));
 814    ds.put(pojoEntity);
 815
 816    Entity unidirChildEntity1 = newUnidir(UnidirLevel.Bottom, pojoEntity.getKey(), "str1", "name 1", new Date(), 1);
 817    unidirChildEntity1.setProperty("unidirByStrAndName_INTEGER_IDX", 0);
 818    unidirChildEntity1.setProperty("unidirByIdAndStr_INTEGER_IDX", 0);
 819    unidirChildEntity1.setProperty("unidirByStrAndId_INTEGER_IDX", 0);
 820    ds.put(unidirChildEntity1);
 821
 822    Entity unidirChildEntity2 = newUnidir(UnidirLevel.Top, pojoEntity.getKey(), "str2", "name 2", null, null);
 823    unidirChildEntity2.setProperty("unidirByStrAndName_INTEGER_IDX", 1);
 824    unidirChildEntity2.setProperty("unidirByIdAndStr_INTEGER_IDX", 1);
 825    unidirChildEntity2.setProperty("unidirByStrAndId_INTEGER_IDX", 1);
 826    ds.put(unidirChildEntity2);
 827
 828    Entity unidirChildEntity3 = newUnidir(UnidirLevel.Middle, pojoEntity.getKey(), "str1", "name 0", new Date(), null);
 829    unidirChildEntity3.setProperty("unidirByStrAndName_INTEGER_IDX", 2);
 830    unidirChildEntity3.setProperty("unidirByIdAndStr_INTEGER_IDX", 2);
 831    unidirChildEntity3.setProperty("unidirByStrAndId_INTEGER_IDX", 2);
 832    ds.put(unidirChildEntity3);
 833
 834    Entity explicitIndexEntity1 =
 835        new Entity(getEntityKind(UnidirTopWithIndexColumn.class), pojoEntity.getKey());
 836    explicitIndexEntity1.setProperty("index", 3);
 837    ds.put(explicitIndexEntity1);
 838
 839    Entity explicitIndexEntity2 =
 840        new Entity(getEntityKind(UnidirTopWithIndexColumn.class), pojoEntity.getKey());
 841    explicitIndexEntity2.setProperty("index", 2);
 842    ds.put(explicitIndexEntity2);
 843
 844    Entity explicitIndexEntity3 =
 845        new Entity(getEntityKind(UnidirTopWithIndexColumn.class), pojoEntity.getKey());
 846    explicitIndexEntity3.setProperty("index", 1);
 847    ds.put(explicitIndexEntity3);
 848
 849    pojoEntity.setProperty("unidirByStrAndName", Utils.newArrayList(unidirChildEntity2.getKey(), unidirChildEntity3.getKey(), unidirChildEntity1.getKey()));
 850    pojoEntity.setProperty("unidirByIdAndStr", Utils.newArrayList(unidirChildEntity3.getKey(), unidirChildEntity2.getKey(), unidirChildEntity1.getKey()));
 851    pojoEntity.setProperty("unidirByStrAndId", Utils.newArrayList(unidirChildEntity2.getKey(), unidirChildEntity1.getKey(), unidirChildEntity3.getKey()));
 852    pojoEntity.setProperty("unidirWithIndexColumn", Utils.newArrayList(explicitIndexEntity3.getKey(), explicitIndexEntity2.getKey(), explicitIndexEntity1.getKey()));
 853    ds.put(pojoEntity);
 854
 855    startEnd.start();
 856    registerSubclasses();
 857
 858    HasOneToManyWithOrderByJDO pojo = pm.getObjectById(
 859        pojoClass, KeyFactory.keyToString(pojoEntity.getKey()));
 860    assertNotNull(pojo);
 861    assertNotNull(pojo.getUndirByStrAndName());
 862    assertEquals(3, pojo.getUndirByStrAndName().size());
 863    assertEquals("name 2", pojo.getUndirByStrAndName().get(0).getName());
 864    assertTrue(pojo.getUndirByStrAndName().get(0) instanceof UnidirTop);
 865    assertEquals("name 0", pojo.getUndirByStrAndName().get(1).getName());
 866    assertTrue(pojo.getUndirByStrAndName().get(1) instanceof UnidirMiddle);
 867    assertEquals("name 1", pojo.getUndirByStrAndName().get(2).getName());
 868    assertTrue(pojo.getUndirByStrAndName().get(2) instanceof UnidirBottom);
 869
 870    assertNotNull(pojo.getUnidirByIdAndStr());
 871    assertEquals(3, pojo.getUnidirByIdAndStr().size());
 872    assertEquals("name 0", pojo.getUnidirByIdAndStr().get(0).getName());
 873    assertTrue(pojo.getUnidirByIdAndStr().get(0) instanceof UnidirMiddle);
 874    assertEquals("name 2", pojo.getUnidirByIdAndStr().get(1).getName());
 875    assertTrue(pojo.getUnidirByIdAndStr().get(1) instanceof UnidirTop);
 876    assertEquals("name 1", pojo.getUnidirByIdAndStr().get(2).getName());
 877    assertTrue(pojo.getUnidirByIdAndStr().get(2) instanceof UnidirBottom);
 878
 879    assertNotNull(pojo.getUnidirByStrAndId());
 880    assertEquals(3, pojo.getUnidirByStrAndId().size());
 881    assertEquals("name 2", pojo.getUnidirByStrAndId().get(0).getName());
 882    assertTrue(pojo.getUnidirByStrAndId().get(0) instanceof UnidirTop);
 883    assertEquals("name 1", pojo.getUnidirByStrAndId().get(1).getName());
 884    assertTrue(pojo.getUnidirByStrAndId().get(1) instanceof UnidirBottom);
 885    assertEquals("name 0", pojo.getUnidirByStrAndId().get(2).getName());
 886    assertTrue(pojo.getUnidirByStrAndId().get(2) instanceof UnidirMiddle);
 887
 888    assertNotNull(pojo.getUnidirWithIndexColumn());
 889    assertEquals(3, pojo.getUnidirWithIndexColumn().size());
 890    assertEquals(explicitIndexEntity3.getKey(), KeyFactory.stringToKey(pojo.getUnidirWithIndexColumn().get(0).getId()));
 891    assertEquals(explicitIndexEntity2.getKey(), KeyFactory.stringToKey(pojo.getUnidirWithIndexColumn().get(1).getId()));
 892    assertEquals(explicitIndexEntity1.getKey(), KeyFactory.stringToKey(pojo.getUnidirWithIndexColumn().get(2).getId()));
 893
 894    startEnd.end();
 895  }
 896
 897  void testSaveWithOrderBy(HasOneToManyWithOrderByJDO pojo,
 898      StartEnd startEnd) throws EntityNotFoundException {
 899    getExecutionContext().getNucleusContext().getPersistenceConfiguration()
 900	.setProperty("datanucleus.appengine.allowMultipleRelationsOfSameType",
 901	    true);
 902    startEnd.start();
 903    pm.makePersistent(pojo);
 904    startEnd.end();
 905    
 906    startEnd.start();
 907    pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
 908    UnidirTop unidir = newUnidir(UnidirLevel.Bottom);
 909    unidir.setStr("str1");
 910    unidir.setName("name 1");
 911    pojo.getUndirByStrAndName().add(unidir);
 912    unidir = newUnidir(UnidirLevel.Top);
 913    unidir.setStr("str2");
 914    unidir.setName("name 2");
 915    pojo.getUndirByStrAndName().add(unidir);
 916    unidir = newUnidir(UnidirLevel.Bottom);
 917    unidir.setStr("str1");
 918    unidir.setName("name 0");
 919    pojo.getUndirByStrAndName().add(unidir);
 920    startEnd.end();
 921    
 922    startEnd.start();
 923    pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
 924    
 925    assertNotNull(pojo);
 926    assertNotNull(pojo.getUndirByStrAndName());
 927    assertEquals(3, pojo.getUndirByStrAndName().size());
 928    assertEquals("name 2", pojo.getUndirByStrAndName().get(0).getName());
 929    assertTrue(pojo.getUndirByStrAndName().get(0) instanceof UnidirTop);
 930    assertEquals("name 0", pojo.getUndirByStrAndName().get(1).getName());
 931    assertTrue(pojo.getUndirByStrAndName().get(1) instanceof UnidirMiddle);
 932    assertEquals("name 1", pojo.getUndirByStrAndName().get(2).getName());
 933    assertTrue(pojo.getUndirByStrAndName().get(2) instanceof UnidirBottom);
 934
 935    assertNotNull(pojo.getUnidirByIdAndStr());
 936    assertEquals(3, pojo.getUnidirByIdAndStr().size());
 937    assertEquals("name 0", pojo.getUnidirByIdAndStr().get(0).getName());
 938    assertTrue(pojo.getUnidirByIdAndStr().get(0) instanceof UnidirMiddle);
 939    assertEquals("name 2", pojo.getUnidirByIdAndStr().get(1).getName());
 940    assertTrue(pojo.getUnidirByIdAndStr().get(1) instanceof UnidirTop);
 941    assertEquals("name 1", pojo.getUnidirByIdAndStr().get(2).getName());
 942    assertTrue(pojo.getUnidirByIdAndStr().get(2) instanceof UnidirBottom);
 943
 944    assertNotNull(pojo.getUnidirByStrAndId());
 945    assertEquals(3, pojo.getUnidirByStrAndId().size());
 946    assertEquals("name 2", pojo.getUnidirByStrAndId().get(0).getName());
 947    assertTrue(pojo.getUnidirByStrAndId().get(0) instanceof UnidirTop);
 948    assertEquals("name 1", pojo.getUnidirByStrAndId().get(1).getName());
 949    assertTrue(pojo.getUnidirByStrAndId().get(1) instanceof UnidirBottom);
 950    assertEquals("name 0", pojo.getUnidirByStrAndId().get(2).getName());
 951    assertTrue(pojo.getUnidirByStrAndId().get(2) instanceof UnidirMiddle);
 952
 953    startEnd.end();    
 954  }
 955
 956 
 957  void testFind(Class<? extends HasOneToManyJDO> pojoClass,
 958      Class<? extends BidirectionalSuperclassTableChildJDO.BidirTop> bidirClass, StartEnd startEnd,
 959      String bidirKind, UnidirLevel unidirLevel) throws EntityNotFoundException {
 960    Entity pojoEntity = new Entity(getEntityKind(pojoClass));
 961    ds.put(pojoEntity);
 962
 963    Entity unidirChildEntity = newUnidir(unidirLevel, pojoEntity.getKey(), "str1", "name 1", null, null);
 964    ds.put(unidirChildEntity);
 965
 966    Entity bidirEntity = new Entity(bidirKind, pojoEntity.getKey());
 967    bidirEntity.setProperty("childVal", "yap");
 968    bidirEntity.setProperty("DISCRIMINATOR", bidirClass.getName());
 969    bidirEntity.setProperty("bidirChildren_INTEGER_IDX", 1);
 970    ds.put(bidirEntity);
 971
 972    pojoEntity.setProperty("bidirChildren", Utils.newArrayList(bidirEntity.getKey()));
 973    pojoEntity.setProperty("unidirChildren", Utils.newArrayList(unidirChildEntity.getKey()));
 974    ds.put(pojoEntity);
 975
 976    startEnd.start();
 977    registerSubclasses();
 978
 979    HasOneToManyJDO pojo =
 980        pm.getObjectById(pojoClass, KeyFactory.keyToString(pojoEntity.getKey()));
 981    assertNotNull(pojo);
 982    assertNotNull(pojo.getUnidirChildren());
 983    assertEquals(1, pojo.getUnidirChildren().size());
 984    assertEquals("str1", pojo.getUnidirChildren().iterator().next().getStr());
 985    assertEquals(unidirLevel.clazz, pojo.getUnidirChildren().iterator().next().getClass());
 986    assertNotNull(pojo.getBidirChildren());
 987    assertEquals(1, pojo.getBidirChildren().size());
 988    assertEquals("yap", pojo.getBidirChildren().iterator().next().getChildVal());
 989    assertEquals(pojo, pojo.getBidirChildren().iterator().next().getParent());
 990    assertEquals(bidirClass, pojo.getBidirChildren().iterator().next().getClass());
 991    startEnd.end();
 992  }
 993
 994  
 995  void testQuery(Class<? extends HasOneToManyJDO> pojoClass,
 996      Class<? extends BidirectionalSuperclassTableChildJDO.BidirTop> bidirClass, StartEnd startEnd,
 997      String bidirKind, UnidirLevel unidirLevel) throws EntityNotFoundException {
 998    Entity pojoEntity = new Entity(getEntityKind(pojoClass));
 999    ds.put(pojoEntity);
1000
1001    Entity unidirEntity = newUnidir(unidirLevel, pojoEntity.getKey(), "str", "name", null, null);
1002    ds.put(unidirEntity);
1003
1004    Entity bidirEntity = new Entity(bidirKind, pojoEntity.getKey());
1005    bidirEntity.setProperty("DISCRIMINATOR", bidirClass.getName());
1006    bidirEntity.setProperty("childVal", "yap");
1007    bidirEntity.setProperty("bidirChildren_INTEGER_IDX", 1);
1008    ds.put(bidirEntity);
1009
1010    pojoEntity.setProperty("bidirChildren", Utils.newArrayList(bidirEntity.getKey()));
1011    pojoEntity.setProperty("unidirChildren", Utils.newArrayList(unidirEntity.getKey()));
1012    ds.put(pojoEntity);
1013
1014    startEnd.start();
1015    registerSubclasses();
1016    javax.jdo.Query q = pm.newQuery(
1017        "select from " + pojoClass.getName() + " where id == key parameters String key");
1018    @SuppressWarnings("unchecked")
1019    List<HasOneToManyJDO> result =
1020        (List<HasOneToManyJDO>) q.execute(KeyFactory.keyToString(pojoEntity.getKey()));
1021    assertEquals(1, result.size());
1022    HasOneToManyJDO pojo = result.get(0);
1023    assertNotNull(pojo.getUnidirChildren());
1024    assertEquals(1, pojo.getUnidirChildren().size());
1025    assertEquals("str", pojo.getUnidirChildren().iterator().next().getStr());
1026    assertEquals("name", pojo.getUnidirChildren().iterator().next().getName());
1027    assertEquals(unidirLevel.clazz, pojo.getUnidirChildren().iterator().next().getClass());
1028    assertEquals(1, pojo.getUnidirChildren().size());
1029    assertNotNull(pojo.getBidirChildren());
1030    assertEquals(1, pojo.getBidirChildren().size());
1031    assertEquals("yap", pojo.getBidirChildren().iterator().next().getChildVal());
1032    assertEquals(pojo, pojo.getBidirChildren().iterator().next().getParent());
1033    assertEquals(bidirClass, pojo.getBidirChildren().iterator().next().getClass());
1034    startEnd.end();
1035  }
1036
1037  
1038  void testChildFetchedLazily(Class<? extends HasOneToManyJDO> pojoClass,
1039      Class<? extends BidirectionalSuperclassTableChildJDO.BidirTop> bidirClass) throws Exception {
1040    DatastoreServiceConfig config = getStoreManager().getDefaultDatastoreServiceConfigForReads();
1041    tearDown();
1042    DatastoreService mockDatastore = EasyMock.createMock(DatastoreService.class);
1043    DatastoreService original = DatastoreServiceFactoryInternal.getDatastoreService(config);
1044    DatastoreServiceFactoryInternal.setDatastoreService(mockDatastore);
1045    try {
1046      setUp();
1047
1048      Entity pojoEntity = new Entity(getEntityKind(pojoClass));
1049      ds.put(pojoEntity);
1050
1051      Entity unidirEntity = newUnidir(UnidirLevel.Top, pojoEntity.getKey(), "str", "name", null, null);
1052      ds.put(unidirEntity);
1053
1054      Entity bidirEntity = new Entity(bidirClass.getSimpleName(), pojoEntity.getKey());
1055      bidirEntity.setProperty("childVal", "yap");
1056      ds.put(bidirEntity);
1057
1058      Transaction txn = EasyMock.createMock(Transaction.class);
1059      EasyMock.expect(txn.getId()).andReturn("1").times(2);
1060      txn.commit();
1061      EasyMock.expectLastCall();
1062      EasyMock.replay(txn);
1063      EasyMock.expect(mockDatastore.beginTransaction(EasyMock.isA(TransactionOptions.class))).andReturn(txn);
1064      // the only get we're going to perform is for the pojo
1065      EasyMock.expect(mockDatastore.get(txn, pojoEntity.getKey())).andReturn(pojoEntity);
1066      EasyMock.replay(mockDatastore);
1067
1068      beginTxn();
1069      HasOneToManyJDO pojo =
1070          pm.getObjectById(pojoClass, KeyFactory.keyToString(pojoEntity.getKey()));
1071      assertNotNull(pojo);
1072      pojo.getId();
1073      commitTxn();
1074    } finally {
1075      DatastoreServiceFactoryInternal.setDatastoreService(original);
1076    }
1077    EasyMock.verify(mockDatastore);
1078  }
1079
1080  
1081  void testDeleteParentDeletesChild(Class<? extends HasOneToManyJDO> pojoClass,
1082      Class<? extends BidirectionalSuperclassTableChildJDO.BidirTop> bidirClass, StartEnd startEnd,
1083      String bidirKind, UnidirLevel unidirLevel) throws Exception {
1084    Entity pojoEntity = new Entity(getEntityKind(pojoClass));
1085    ds.put(pojoEntity);
1086
1087    Entity unidirEntity = newUnidir(unidirLevel, pojoEntity.getKey(), "str", "name", null, null);
1088    ds.put(unidirEntity);
1089
1090    Entity bidirEntity = new Entity(bidirKind, pojoEntity.getKey());
1091    bidirEntity.setProperty("childVal", "yap");
1092    bidirEntity.setProperty("bidirChildren_INTEGER_IDX", 1);
1093    bidirEntity.setProperty("DISCRIMINATOR", bidirClass.getName());
1094    ds.put(bidirEntity);
1095
1096    pojoEntity.setProperty("bidirChildren", Utils.newArrayList(bidirEntity.getKey()));
1097    pojoEntity.setProperty("unidirChildren", Utils.newArrayList(unidirEntity.getKey()));
1098    ds.put(pojoEntity);
1099
1100    startEnd.start();
1101    registerSubclasses();
1102    HasOneToManyJDO pojo = pm.getObjectById(pojoClass, KeyFactory.keyToString(pojoEntity.getKey()));
1103    pm.deletePersistent(pojo);
1104    startEnd.end();
1105    assertCountsInDatastore(pojoClass, bidirClass, 0, 0);
1106  }
1107
1108  void testRemoveAll(HasOneToManyJDO pojo, BidirectionalSuperclassTableChildJDO.BidirTop bidir1,
1109                     BidirectionalSuperclassTableChildJDO.BidirTop bidir2, BidirectionalSuperclassTableChildJDO.BidirTop bidir3, StartEnd startEnd)
1110      throws EntityNotFoundException {
1111    UnidirTop unidir1 = new UnidirTop();
1112    UnidirTop unidir2 = new UnidirMiddle();
1113    UnidirTop unidir3 = new UnidirBottom();
1114    pojo.addUnidirChild(unidir1);
1115    pojo.addUnidirChild(unidir2);
1116    pojo.addUnidirChild(unidir3);
1117
1118    pojo.addBidirChild(bidir1);
1119    pojo.addBidirChild(bidir2);
1120    pojo.addBidirChild(bidir3);
1121
1122    startE

Large files files are truncated, but you can click here to view the full file