PageRenderTime 164ms CodeModel.GetById 40ms app.highlight 114ms RepoModel.GetById 0ms app.codeStats 1ms

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

http://datanucleus-appengine.googlecode.com/
Java | 1266 lines | 1052 code | 157 blank | 57 comment | 4 complexity | 35797b1bba0ef64ca27b0f4ad185b788 MD5 | raw file

Large files files are truncated, but you can click here to view the full 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.DatastoreService;
  19import com.google.appengine.api.datastore.Entity;
  20import com.google.appengine.api.datastore.EntityNotFoundException;
  21import com.google.appengine.api.datastore.Key;
  22import com.google.appengine.api.datastore.KeyFactory;
  23import com.google.appengine.api.datastore.Transaction;
  24import com.google.appengine.api.datastore.TransactionOptions;
  25import com.google.appengine.datanucleus.DatastoreServiceFactoryInternal;
  26import com.google.appengine.datanucleus.DatastoreServiceInterceptor;
  27import com.google.appengine.datanucleus.TestUtils;
  28import com.google.appengine.datanucleus.Utils;
  29import com.google.appengine.datanucleus.test.jdo.Flight;
  30import com.google.appengine.datanucleus.test.jdo.HasEncodedStringPkJDO;
  31import com.google.appengine.datanucleus.test.jdo.HasKeyPkJDO;
  32import com.google.appengine.datanucleus.test.jdo.HasOneToOneChildAtMultipleLevelsJDO;
  33import com.google.appengine.datanucleus.test.jdo.HasOneToOneJDO;
  34import com.google.appengine.datanucleus.test.jdo.HasOneToOneLongPkJDO;
  35import com.google.appengine.datanucleus.test.jdo.HasOneToOneLongPkParentJDO;
  36import com.google.appengine.datanucleus.test.jdo.HasOneToOneLongPkParentKeyPkJDO;
  37import com.google.appengine.datanucleus.test.jdo.HasOneToOneParentJDO;
  38import com.google.appengine.datanucleus.test.jdo.HasOneToOneParentKeyPkJDO;
  39import com.google.appengine.datanucleus.test.jdo.HasOneToOneStringPkJDO;
  40import com.google.appengine.datanucleus.test.jdo.HasOneToOneStringPkParentJDO;
  41import com.google.appengine.datanucleus.test.jdo.HasOneToOneStringPkParentKeyPkJDO;
  42
  43import org.easymock.EasyMock;
  44
  45import java.lang.reflect.Method;
  46import java.util.List;
  47
  48import javax.jdo.JDOFatalUserException;
  49import javax.jdo.Query;
  50
  51import static com.google.appengine.datanucleus.TestUtils.assertKeyParentEquals;
  52
  53/**
  54 * @author Max Ross <maxr@google.com>
  55 */
  56public class JDOOneToOneTest extends JDOTestCase {
  57
  58  public void testInsert_NewParentAndChild() throws EntityNotFoundException {
  59    testInsert_NewParentAndChild(TXN_START_END);
  60  }
  61  public void testInsert_NewParentAndChild_NoTxn() throws EntityNotFoundException {
  62    switchDatasource(PersistenceManagerFactoryName.nontransactional);
  63    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
  64    testInsert_NewParentAndChild(NEW_PM_START_END);
  65  }
  66  private void testInsert_NewParentAndChild(StartEnd startEnd) throws EntityNotFoundException {
  67    Flight f = newFlight();
  68    HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
  69    HasOneToOneParentJDO hasParent = new HasOneToOneParentJDO();
  70    HasOneToOneParentKeyPkJDO hasParentKeyPk = new HasOneToOneParentKeyPkJDO();
  71    HasEncodedStringPkJDO notDependent = new HasEncodedStringPkJDO();
  72
  73    HasOneToOneJDO pojo = new HasOneToOneJDO();
  74    pojo.setFlight(f);
  75    pojo.setHasKeyPK(hasKeyPk);
  76    pojo.setHasParent(hasParent);
  77    hasParent.setParent(pojo);
  78    pojo.setHasParentKeyPK(hasParentKeyPk);
  79    hasParentKeyPk.setParent(pojo);
  80    pojo.setNotDependent(notDependent);
  81
  82    makePersistentInTxn(pojo, startEnd);
  83
  84    assertNotNull(f.getId());
  85    assertNotNull(hasKeyPk.getKey());
  86    assertNotNull(hasParent.getKey());
  87    assertNotNull(hasParentKeyPk.getKey());
  88    assertNotNull(notDependent.getId());
  89    assertNotNull(pojo.getId());
  90
  91    Entity flightEntity = ds.get(KeyFactory.stringToKey(f.getId()));
  92    assertNotNull(flightEntity);
  93    assertEquals("jimmy", flightEntity.getProperty("name"));
  94    assertEquals("bos", flightEntity.getProperty("origin"));
  95    assertEquals("mia", flightEntity.getProperty("dest"));
  96    assertEquals(2L, flightEntity.getProperty("me"));
  97    assertEquals(3L, flightEntity.getProperty("you"));
  98    assertEquals(44L, flightEntity.getProperty("flight_number"));
  99    assertEquals(KeyFactory.stringToKey(f.getId()), flightEntity.getKey());
 100    assertKeyParentEquals(pojo.getId(), flightEntity, f.getId());
 101
 102    Entity hasKeyPkEntity = ds.get(hasKeyPk.getKey());
 103    assertNotNull(hasKeyPkEntity);
 104    assertEquals(hasKeyPk.getKey(), hasKeyPkEntity.getKey());
 105    assertKeyParentEquals(pojo.getId(), hasKeyPkEntity, hasKeyPk.getKey());
 106
 107    Entity hasParentEntity = ds.get(KeyFactory.stringToKey(hasParent.getKey()));
 108    assertNotNull(hasParentEntity);
 109    assertEquals(KeyFactory.stringToKey(hasParent.getKey()), hasParentEntity.getKey());
 110    assertKeyParentEquals(pojo.getId(), hasParentEntity, hasParent.getKey());
 111
 112    Entity hasParentKeyPkEntity = ds.get(hasParentKeyPk.getKey());
 113    assertNotNull(hasParentKeyPkEntity);
 114    assertEquals(hasParentKeyPk.getKey(), hasParentKeyPkEntity.getKey());
 115    assertKeyParentEquals(pojo.getId(), hasParentKeyPkEntity, hasParentKeyPk.getKey());
 116
 117    Entity notDependentEntity = ds.get(KeyFactory.stringToKey(notDependent.getId()));
 118    assertNotNull(notDependentEntity);
 119
 120    Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 121    assertNotNull(pojoEntity);
 122    assertEquals(flightEntity.getKey(), pojoEntity.getProperty("flight_id_OID"));
 123    assertEquals(hasKeyPkEntity.getKey(), pojoEntity.getProperty("hasKeyPK_key_OID"));
 124    assertEquals(hasParentEntity.getKey(), pojoEntity.getProperty("hasParent_key_OID"));
 125    assertEquals(hasParentKeyPkEntity.getKey(), pojoEntity.getProperty("hasParentKeyPK_key_OID"));
 126    assertEquals(notDependentEntity.getKey(), pojoEntity.getProperty("notDependent_id_OID"));
 127
 128    assertCountsInDatastore(1, 1);
 129    assertEquals(1, countForClass(notDependent.getClass()));
 130  }
 131
 132  public void testInsert_NewParentExistingChild_Unidirectional() throws EntityNotFoundException {
 133    testInsert_NewParentExistingChild_Unidirectional(TXN_START_END);
 134  }
 135  public void testInsert_NewParentExistingChild_Unidirectional_NoTxn() throws EntityNotFoundException {
 136    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 137    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 138    testInsert_NewParentExistingChild_Unidirectional(NEW_PM_START_END);
 139  }
 140  private void testInsert_NewParentExistingChild_Unidirectional(StartEnd startEnd) throws EntityNotFoundException {
 141    Flight f = newFlight();
 142    HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
 143    HasOneToOneParentJDO hasParent = new HasOneToOneParentJDO();
 144    HasOneToOneParentKeyPkJDO hasParentKeyPk = new HasOneToOneParentKeyPkJDO();
 145
 146    startEnd.start();
 147    pm.makePersistent(f);
 148    startEnd.end();
 149    startEnd.start();
 150    pm.makePersistent(hasKeyPk);
 151    startEnd.end();
 152    startEnd.start();
 153    pm.makePersistent(hasParent);
 154    startEnd.end();
 155    startEnd.start();
 156    pm.makePersistent(hasParentKeyPk);
 157    startEnd.end();
 158    assertNotNull(f.getId());
 159    assertNotNull(hasKeyPk.getKey());
 160    assertNotNull(hasParent.getKey());
 161    assertNotNull(hasParentKeyPk.getKey());
 162
 163    HasOneToOneJDO pojo = new HasOneToOneJDO();
 164
 165    startEnd.start();
 166    f = pm.makePersistent(f);
 167    hasKeyPk = pm.makePersistent(hasKeyPk);
 168    pojo.setFlight(f);
 169    pojo.setHasKeyPK(hasKeyPk);
 170    try {
 171      // this fails because it attempts to establish a parent for an object
 172      // that was originally saved without a parent
 173      pm.makePersistent(pojo);
 174      fail("expected exception");
 175    } catch (JDOFatalUserException e) {
 176      // good
 177      if (pm.currentTransaction().isActive()) {
 178        rollbackTxn();
 179      }
 180    }
 181    assertCountsInDatastore(0, 1);
 182  }
 183
 184  public void testInsert_NewParentExistingChild_Bidirectional() throws EntityNotFoundException {
 185    testInsert_NewParentExistingChild_Bidirectional(TXN_START_END);
 186  }
 187  public void testInsert_NewParentExistingChild_Bidirectional_NoTxn() throws EntityNotFoundException {
 188    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 189    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 190    testInsert_NewParentExistingChild_Bidirectional(NEW_PM_START_END);
 191  }
 192  private void testInsert_NewParentExistingChild_Bidirectional(StartEnd startEnd) throws EntityNotFoundException {
 193    Flight f = newFlight();
 194    HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
 195    HasOneToOneParentJDO hasParent = new HasOneToOneParentJDO();
 196    HasOneToOneParentKeyPkJDO hasParentKeyPk = new HasOneToOneParentKeyPkJDO();
 197
 198    makePersistentInTxn(f, startEnd);
 199    makePersistentInTxn(hasKeyPk, startEnd);
 200    makePersistentInTxn(hasParent, startEnd);
 201    makePersistentInTxn(hasParentKeyPk, startEnd);
 202    assertNotNull(f.getId());
 203    assertNotNull(hasKeyPk.getKey());
 204    assertNotNull(hasParent.getKey());
 205    assertNotNull(hasParentKeyPk.getKey());
 206
 207    HasOneToOneJDO pojo = new HasOneToOneJDO();
 208    pojo.setFlight(f);
 209    pojo.setHasKeyPK(hasKeyPk);
 210    pojo.setHasParent(hasParent);
 211    pojo.setHasParentKeyPK(hasParentKeyPk);
 212
 213    startEnd.start();
 214    try {
 215      // this fails because it tries to establish a parent for an object that
 216      // was originally saved without a parent
 217      pm.makePersistent(pojo);
 218      fail("expected exception");
 219    } catch (JDOFatalUserException e) {
 220      // good
 221      if (pm.currentTransaction().isActive()) {
 222        rollbackTxn();
 223      }
 224    }
 225  }
 226
 227  public void testInsert_ExistingParentNewChild() throws EntityNotFoundException {
 228    testInsert_ExistingParentNewChild(TXN_START_END);
 229  }
 230  public void testInsert_ExistingParentNewChild_NoTxn() throws EntityNotFoundException {
 231    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 232    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 233    testInsert_ExistingParentNewChild(NEW_PM_START_END);
 234  }
 235  private void testInsert_ExistingParentNewChild(StartEnd startEnd) throws EntityNotFoundException {
 236    HasOneToOneJDO pojo = new HasOneToOneJDO();
 237
 238    startEnd.start();
 239    pm.makePersistent(pojo);
 240    assertNotNull(pojo.getId());
 241    assertNull(pojo.getFlight());
 242    assertNull(pojo.getHasKeyPK());
 243    assertNull(pojo.getHasParent());
 244    assertNull(pojo.getHasParentKeyPK());
 245    pojo = pm.detachCopy(pojo);
 246    startEnd.end();
 247    
 248    Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 249    assertNotNull(pojoEntity);
 250
 251    Flight f = newFlight();
 252    HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
 253    HasOneToOneParentJDO hasParent = new HasOneToOneParentJDO();
 254    HasOneToOneParentKeyPkJDO hasParentKeyPk = new HasOneToOneParentKeyPkJDO();
 255    startEnd.start();
 256    pojo = pm.makePersistent(pojo);
 257    pojo.setFlight(f);
 258    pojo.setHasKeyPK(hasKeyPk);
 259    pojo.setHasParent(hasParent);
 260    hasParent.setParent(pojo);
 261    pojo.setHasParentKeyPK(hasParentKeyPk);
 262    hasParent.setParent(pojo);
 263    startEnd.end();
 264
 265    assertNotNull(f.getId());
 266    assertNotNull(hasKeyPk.getKey());
 267    assertNotNull(hasParent.getKey());
 268    assertNotNull(hasParentKeyPk.getKey());
 269
 270    Entity flightEntity = ds.get(KeyFactory.stringToKey(f.getId()));
 271    assertNotNull(flightEntity);
 272    assertKeyParentEquals(pojo.getId(), flightEntity, f.getId());
 273
 274    Entity hasKeyPkEntity = ds.get(hasKeyPk.getKey());
 275    assertNotNull(hasKeyPkEntity);
 276    assertKeyParentEquals(pojo.getId(), hasKeyPkEntity, hasKeyPk.getKey());
 277
 278    Entity hasParentEntity = ds.get(KeyFactory.stringToKey(hasParent.getKey()));
 279    assertNotNull(hasParentEntity);
 280    assertKeyParentEquals(pojo.getId(), hasParentEntity, hasParent.getKey());
 281
 282    Entity hasParentKeyPkEntity = ds.get(hasParentKeyPk.getKey());
 283    assertNotNull(hasParentKeyPkEntity);
 284    assertKeyParentEquals(pojo.getId(), hasParentKeyPkEntity, hasParentKeyPk.getKey());
 285
 286    pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 287    assertNotNull(pojoEntity);
 288    assertEquals(flightEntity.getKey(), pojoEntity.getProperty("flight_id_OID"));
 289    assertEquals(hasKeyPkEntity.getKey(), pojoEntity.getProperty("hasKeyPK_key_OID"));
 290    assertEquals(hasParentEntity.getKey(), pojoEntity.getProperty("hasParent_key_OID"));
 291    assertEquals(hasParentKeyPkEntity.getKey(), pojoEntity.getProperty("hasParentKeyPK_key_OID"));
 292    assertTrue(pojoEntity.hasProperty("notDependent_id_OID"));
 293    assertNull(pojoEntity.getProperty("notDependent_id_OID"));
 294
 295    assertCountsInDatastore(1, 1);
 296  }
 297
 298  // These tests fail because we are inserting a new child object as part
 299  // of attaching the parent.  Since we're attaching the parent, the children
 300  // get inserted first, which associates the entity group of the children
 301  // with the txn and then causes an exception when we go to update the
 302  // parent.  We need some way to force the parent to update first.
 303  public void fail_testInsert_ExistingParentNewChild_UpdateDetached() throws EntityNotFoundException {
 304    testInsert_ExistingParentNewChild_UpdateDetached(TXN_START_END);
 305  }
 306  public void fail_testInsert_ExistingParentNewChild_UpdateDetached_NoTxn() throws EntityNotFoundException {
 307    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 308    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 309    testInsert_ExistingParentNewChild_UpdateDetached(NEW_PM_START_END);
 310  }
 311  private void testInsert_ExistingParentNewChild_UpdateDetached(StartEnd startEnd) throws EntityNotFoundException {
 312    HasOneToOneJDO pojo = new HasOneToOneJDO();
 313
 314    startEnd.start();
 315    pm.makePersistent(pojo);
 316    assertNotNull(pojo.getId());
 317    assertNull(pojo.getFlight());
 318    assertNull(pojo.getHasKeyPK());
 319    assertNull(pojo.getHasParent());
 320    assertNull(pojo.getHasParentKeyPK());
 321    pojo = pm.detachCopy(pojo);
 322    startEnd.end();
 323
 324    Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 325    assertNotNull(pojoEntity);
 326
 327    Flight f = newFlight();
 328    HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
 329    HasOneToOneParentJDO hasParent = new HasOneToOneParentJDO();
 330    HasOneToOneParentKeyPkJDO hasParentKeyPk = new HasOneToOneParentKeyPkJDO();
 331    startEnd.start();
 332    pojo.setFlight(f);
 333    pojo.setHasKeyPK(hasKeyPk);
 334    pojo.setHasParent(hasParent);
 335    hasParent.setParent(pojo);
 336    pojo.setHasParentKeyPK(hasParentKeyPk);
 337    hasParent.setParent(pojo);
 338    pojo = pm.makePersistent(pojo);
 339    startEnd.end();
 340
 341    assertNotNull(f.getId());
 342    assertNotNull(hasKeyPk.getKey());
 343    assertNotNull(hasParent.getKey());
 344    assertNotNull(hasParentKeyPk.getKey());
 345
 346    Entity flightEntity = ds.get(KeyFactory.stringToKey(f.getId()));
 347    assertNotNull(flightEntity);
 348    assertKeyParentEquals(pojo.getId(), flightEntity, f.getId());
 349
 350    Entity hasKeyPkEntity = ds.get(hasKeyPk.getKey());
 351    assertNotNull(hasKeyPkEntity);
 352    assertKeyParentEquals(pojo.getId(), hasKeyPkEntity, hasKeyPk.getKey());
 353
 354    Entity hasParentEntity = ds.get(KeyFactory.stringToKey(hasParent.getKey()));
 355    assertNotNull(hasParentEntity);
 356    assertKeyParentEquals(pojo.getId(), hasParentEntity, hasParent.getKey());
 357
 358    Entity hasParentKeyPkEntity = ds.get(hasParentKeyPk.getKey());
 359    assertNotNull(hasParentKeyPkEntity);
 360    assertKeyParentEquals(pojo.getId(), hasParentKeyPkEntity, hasParentKeyPk.getKey());
 361
 362    pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 363    assertNotNull(pojoEntity);
 364    assertEquals(flightEntity.getKey(), pojoEntity.getProperty("flight_id_OID"));
 365    assertEquals(hasKeyPkEntity.getKey(), pojoEntity.getProperty("hasKeyPK_key_OID"));
 366    assertEquals(hasParentEntity.getKey(), pojoEntity.getProperty("hasParent_key_OID"));
 367    assertEquals(hasParentKeyPkEntity.getKey(), pojoEntity.getProperty("hasParentKeyPK_key_OID"));
 368    assertTrue(pojoEntity.hasProperty("notDependent_id_OID"));
 369    assertNull(pojoEntity.getProperty("notDependent_id_OID"));
 370
 371    assertCountsInDatastore(1, 1);
 372  }
 373
 374  public void testUpdate_UpdateChildWithMerge() throws EntityNotFoundException {
 375    testUpdate_UpdateChildWithMerge(TXN_START_END);
 376  }
 377  public void testUpdate_UpdateChildWithMerge_NoTxn() throws EntityNotFoundException {
 378    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 379    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 380    testUpdate_UpdateChildWithMerge(NEW_PM_START_END);
 381  }
 382  private void testUpdate_UpdateChildWithMerge(StartEnd startEnd) throws EntityNotFoundException {
 383    Flight f = newFlight();
 384    HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
 385
 386    HasOneToOneJDO pojo = new HasOneToOneJDO();
 387    pojo.setFlight(f);
 388    pojo.setHasKeyPK(hasKeyPk);
 389
 390    HasOneToOneParentJDO hasParent = new HasOneToOneParentJDO();
 391    pojo.setHasParent(hasParent);
 392    hasParent.setParent(pojo);
 393
 394    HasOneToOneParentKeyPkJDO hasParentKeyPk = new HasOneToOneParentKeyPkJDO();
 395    pojo.setHasParentKeyPK(hasParentKeyPk);
 396    hasParent.setParent(pojo);
 397
 398    startEnd.start();
 399    pm.makePersistent(pojo);
 400
 401    assertNotNull(f.getId());
 402    assertNotNull(hasKeyPk.getKey());
 403    assertNotNull(hasParent.getKey());
 404    assertNotNull(hasParentKeyPk.getKey());
 405    assertNotNull(pojo.getId());
 406    f = pm.detachCopy(f);
 407    hasKeyPk = pm.detachCopy(hasKeyPk);
 408    hasParent = pm.detachCopy(hasParent);
 409    hasParentKeyPk = pm.detachCopy(hasParentKeyPk);
 410    startEnd.end();
 411    startEnd.start();
 412    f.setOrigin("yam");
 413    hasKeyPk.setStr("yar");
 414    hasParent.setStr("yag");
 415    hasParentKeyPk.setStr("yap");
 416    f = pm.makePersistent(f);
 417    hasKeyPk = pm.makePersistent(hasKeyPk);
 418    hasParent = pm.makePersistent(hasParent);
 419    hasParentKeyPk = pm.makePersistent(hasParentKeyPk);
 420    startEnd.end();
 421
 422    Entity flightEntity = ds.get(KeyFactory.stringToKey(f.getId()));
 423    assertNotNull(flightEntity);
 424    assertEquals("yam", flightEntity.getProperty("origin"));
 425    assertKeyParentEquals(pojo.getId(), flightEntity, f.getId());
 426
 427    Entity hasKeyPkEntity = ds.get(hasKeyPk.getKey());
 428    assertNotNull(hasKeyPkEntity);
 429    assertEquals("yar", hasKeyPkEntity.getProperty("str"));
 430    assertKeyParentEquals(pojo.getId(), hasKeyPkEntity, hasKeyPk.getKey());
 431
 432    Entity hasParentEntity = ds.get(KeyFactory.stringToKey(hasParent.getKey()));
 433    assertNotNull(hasParentEntity);
 434    assertEquals("yag", hasParentEntity.getProperty("str"));
 435    assertKeyParentEquals(pojo.getId(), hasParentEntity, hasParent.getKey());
 436
 437    Entity hasParentPkEntity = ds.get(hasParentKeyPk.getKey());
 438    assertNotNull(hasParentPkEntity);
 439    assertEquals("yap", hasParentPkEntity.getProperty("str"));
 440    assertKeyParentEquals(pojo.getId(), hasParentPkEntity, hasParentKeyPk.getKey());
 441
 442    Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 443    assertNotNull(pojoEntity);
 444    assertEquals(flightEntity.getKey(), pojoEntity.getProperty("flight_id_OID"));
 445    assertEquals(hasKeyPkEntity.getKey(), pojoEntity.getProperty("hasKeyPK_key_OID"));
 446    assertEquals(hasParentEntity.getKey(), pojoEntity.getProperty("hasParent_key_OID"));
 447    assertEquals(hasParentPkEntity.getKey(), pojoEntity.getProperty("hasParentKeyPK_key_OID"));
 448    assertTrue(pojoEntity.hasProperty("notDependent_id_OID"));
 449    assertNull(pojoEntity.getProperty("notDependent_id_OID"));
 450
 451    assertCountsInDatastore(1, 1);
 452  }
 453
 454  public void testUpdate_UpdateChild() throws EntityNotFoundException {
 455    testUpdate_UpdateChild(TXN_START_END);
 456  }
 457  public void testUpdate_UpdateChild_NoTxn() throws EntityNotFoundException {
 458    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 459    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 460    testUpdate_UpdateChild(NEW_PM_START_END);
 461  }
 462  public void testUpdate_UpdateChild(StartEnd startEnd) throws EntityNotFoundException {
 463    Flight f = newFlight();
 464    HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
 465    HasOneToOneParentJDO hasParent = new HasOneToOneParentJDO();
 466    HasOneToOneParentKeyPkJDO hasParentKeyPk = new HasOneToOneParentKeyPkJDO();
 467    HasOneToOneJDO pojo = new HasOneToOneJDO();
 468
 469    pojo.setFlight(f);
 470    pojo.setHasKeyPK(hasKeyPk);
 471    pojo.setHasParent(hasParent);
 472    hasParent.setParent(pojo);
 473    pojo.setHasParentKeyPK(hasParentKeyPk);
 474    hasParent.setParent(pojo);
 475
 476    startEnd.start();
 477    pm.makePersistent(pojo);
 478
 479    assertNotNull(f.getId());
 480    assertNotNull(hasKeyPk.getKey());
 481    assertNotNull(hasParentKeyPk.getKey());
 482    assertNotNull(hasParent.getKey());
 483    assertNotNull(pojo.getId());
 484    startEnd.end();
 485
 486    startEnd.start();
 487    pojo = pm.getObjectById(HasOneToOneJDO.class, pojo.getId());
 488    pojo.getFlight().setOrigin("yam");
 489    pojo.getHasKeyPK().setStr("yar");
 490    pojo.getHasParent().setStr("yag");
 491    pojo.getHasParentKeyPK().setStr("yap");
 492    startEnd.end();
 493
 494    Entity flightEntity = ds.get(KeyFactory.stringToKey(f.getId()));
 495    assertNotNull(flightEntity);
 496    assertEquals("yam", flightEntity.getProperty("origin"));
 497    assertKeyParentEquals(pojo.getId(), flightEntity, f.getId());
 498
 499    Entity hasKeyPkEntity = ds.get(hasKeyPk.getKey());
 500    assertNotNull(hasKeyPkEntity);
 501    assertEquals("yar", hasKeyPkEntity.getProperty("str"));
 502    assertKeyParentEquals(pojo.getId(), hasKeyPkEntity, hasKeyPk.getKey());
 503
 504    Entity hasParentEntity = ds.get(KeyFactory.stringToKey(hasParent.getKey()));
 505    assertNotNull(hasParentEntity);
 506    assertEquals("yag", hasParentEntity.getProperty("str"));
 507    assertKeyParentEquals(pojo.getId(), hasParentEntity, hasParent.getKey());
 508
 509    Entity hasParentKeyPkEntity = ds.get(hasParentKeyPk.getKey());
 510    assertNotNull(hasParentKeyPkEntity);
 511    assertEquals("yap", hasParentKeyPkEntity.getProperty("str"));
 512    assertKeyParentEquals(pojo.getId(), hasParentKeyPkEntity, hasParentKeyPk.getKey());
 513
 514    Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 515    assertNotNull(pojoEntity);
 516    assertEquals(flightEntity.getKey(), pojoEntity.getProperty("flight_id_OID"));
 517    assertEquals(hasKeyPkEntity.getKey(), pojoEntity.getProperty("hasKeyPK_key_OID"));
 518    assertEquals(hasParentEntity.getKey(), pojoEntity.getProperty("hasParent_key_OID"));
 519    assertEquals(hasParentKeyPkEntity.getKey(), pojoEntity.getProperty("hasParentKeyPK_key_OID"));
 520    assertTrue(pojoEntity.hasProperty("notDependent_id_OID"));
 521    assertNull(pojoEntity.getProperty("notDependent_id_OID"));
 522
 523    assertCountsInDatastore(1, 1);
 524  }
 525
 526  public void testUpdate_NullOutChild() throws EntityNotFoundException {
 527    testUpdate_NullOutChild(TXN_START_END);
 528  }
 529  public void testUpdate_NullOutChild_NoTxn() throws EntityNotFoundException {
 530    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 531    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 532    testUpdate_NullOutChild(NEW_PM_START_END);
 533  }
 534  private void testUpdate_NullOutChild(StartEnd startEnd) throws EntityNotFoundException {
 535    Flight f = newFlight();
 536    HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
 537    HasOneToOneParentJDO hasParent = new HasOneToOneParentJDO();
 538    HasOneToOneParentKeyPkJDO hasParentKeyPk = new HasOneToOneParentKeyPkJDO();
 539
 540    HasOneToOneJDO pojo = new HasOneToOneJDO();
 541    pojo.setFlight(f);
 542    pojo.setHasKeyPK(hasKeyPk);
 543    pojo.setHasParent(hasParent);
 544    hasParent.setParent(pojo);
 545    pojo.setHasParentKeyPK(hasParentKeyPk);
 546    hasParent.setParent(pojo);
 547
 548    startEnd.start();
 549    pm.makePersistent(pojo);
 550    String flightId = f.getId();
 551    Key hasKeyPkKey = hasKeyPk.getKey();
 552    String hasParentKey = hasParent.getKey();
 553    Key hasParentKeyPkKey = hasParentKeyPk.getKey();
 554    startEnd.end();
 555
 556    startEnd.start();
 557    try {
 558      pojo = pm.makePersistent(pojo);
 559      pojo.setFlight(null);
 560      pojo.setHasKeyPK(null);
 561      pojo.setHasParent(null);
 562      pojo.setHasParentKeyPK(null);
 563    } finally {
 564      startEnd.end();
 565    }
 566
 567    try {
 568      ds.get(KeyFactory.stringToKey(flightId));
 569      fail("expected enfe");
 570    } catch (EntityNotFoundException enfe) {
 571      // good
 572    }
 573
 574    try {
 575      ds.get(hasKeyPkKey);
 576      fail("expected enfe");
 577    } catch (EntityNotFoundException enfe) {
 578      // good
 579    }
 580
 581    try {
 582      ds.get(KeyFactory.stringToKey(hasParentKey));
 583      fail("expected enfe");
 584    } catch (EntityNotFoundException enfe) {
 585      // good
 586    }
 587
 588    try {
 589      ds.get(hasParentKeyPkKey);
 590      fail("expected enfe");
 591    } catch (EntityNotFoundException enfe) {
 592      // good
 593    }
 594
 595    Entity parentEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
 596    assertEquals(6, parentEntity.getProperties().size());
 597    assertTrue(parentEntity.hasProperty("str"));
 598    assertTrue(parentEntity.hasProperty("flight_id_OID"));
 599    assertNull(parentEntity.getProperty("flight_id_OID"));
 600    assertTrue(parentEntity.hasProperty("hasKeyPK_key_OID"));
 601    assertNull(parentEntity.getProperty("hasKeyPK_key_OID"));
 602    assertTrue(parentEntity.hasProperty("hasParent_key_OID"));
 603    assertNull(parentEntity.getProperty("hasParent_key_OID"));
 604    assertTrue(parentEntity.hasProperty("hasParentKeyPK_key_OID"));
 605    assertNull(parentEntity.getProperty("hasParentKeyPK_key_OID"));
 606    assertTrue(parentEntity.hasProperty("notDependent_id_OID"));
 607    assertNull(parentEntity.getProperty("notDependent_id_OID"));
 608    assertCountsInDatastore(1, 0);
 609  }
 610
 611  public void testFind() throws EntityNotFoundException {
 612    testFind(TXN_START_END);
 613  }
 614  public void testFind_NoTxn() throws EntityNotFoundException {
 615    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 616    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 617    testFind(NEW_PM_START_END);
 618  }
 619  private void testFind(StartEnd startEnd) throws EntityNotFoundException {
 620    Entity pojoEntity = new Entity(HasOneToOneJDO.class.getSimpleName());
 621    ds.put(pojoEntity);
 622
 623    Entity flightEntity = Flight.newFlightEntity(
 624        pojoEntity.getKey(), null, "jimmy", "bos", "mia", 5, 4, 33);
 625    ds.put(flightEntity);
 626
 627    Entity hasKeyPkEntity = new Entity(HasKeyPkJDO.class.getSimpleName(), pojoEntity.getKey());
 628    hasKeyPkEntity.setProperty("str", "yar");
 629    ds.put(hasKeyPkEntity);
 630
 631    Entity hasParentEntity =
 632        new Entity(HasOneToOneParentJDO.class.getSimpleName(), pojoEntity.getKey());
 633    hasParentEntity.setProperty("str", "yap");
 634    ds.put(hasParentEntity);
 635
 636    Entity hasParentKeyPkEntity =
 637        new Entity(HasOneToOneParentKeyPkJDO.class.getSimpleName(), pojoEntity.getKey());
 638    hasParentKeyPkEntity.setProperty("str", "yag");
 639    ds.put(hasParentKeyPkEntity);
 640
 641    startEnd.start();
 642    HasOneToOneJDO pojo =
 643        pm.getObjectById(HasOneToOneJDO.class, KeyFactory.keyToString(pojoEntity.getKey()));
 644    assertNotNull(pojo);
 645    assertNotNull(pojo.getFlight());
 646    assertEquals("bos", pojo.getFlight().getOrigin());
 647    assertEquals("mia", pojo.getFlight().getDest());
 648    assertNotNull(pojo.getHasKeyPK());
 649    assertEquals("yar", pojo.getHasKeyPK().getStr());
 650    assertNotNull(pojo.getHasParent());
 651    assertEquals("yap", pojo.getHasParent().getStr());
 652    assertNotNull(pojo.getHasParentKeyPK());
 653    assertEquals(pojo, pojo.getHasParent().getParent());
 654    assertEquals("yag", pojo.getHasParentKeyPK().getStr());
 655    assertEquals(pojo, pojo.getHasParentKeyPK().getParent());
 656    startEnd.end();
 657  }
 658
 659  public void testQuery() {
 660    testQuery(TXN_START_END);
 661  }
 662  public void testQuery_NoTxn() {
 663    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 664    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 665    testQuery(NEW_PM_START_END);
 666  }
 667  public void testQuery(StartEnd startEnd) {
 668    Entity pojoEntity = new Entity(HasOneToOneJDO.class.getSimpleName());
 669    ds.put(pojoEntity);
 670
 671    Entity flightEntity = Flight.newFlightEntity(
 672        pojoEntity.getKey(), null, "jimmy", "bos", "mia", 5, 4, 33);
 673    ds.put(flightEntity);
 674
 675    Entity hasKeyPkEntity = new Entity(HasKeyPkJDO.class.getSimpleName(), pojoEntity.getKey());
 676    hasKeyPkEntity.setProperty("str", "yar");
 677    ds.put(hasKeyPkEntity);
 678
 679    Entity hasParentEntity =
 680        new Entity(HasOneToOneParentJDO.class.getSimpleName(), pojoEntity.getKey());
 681    hasParentEntity.setProperty("str", "yap");
 682    ds.put(hasParentEntity);
 683
 684    Entity hasParentKeyPkEntity =
 685        new Entity(HasOneToOneParentKeyPkJDO.class.getSimpleName(), pojoEntity.getKey());
 686    hasParentKeyPkEntity.setProperty("str", "yag");
 687    ds.put(hasParentKeyPkEntity);
 688
 689    Query q = pm.newQuery("select from " + HasOneToOneJDO.class.getName()
 690        + " where id == key parameters String key");
 691    startEnd.start();
 692    @SuppressWarnings("unchecked")
 693    List<HasOneToOneJDO> result =
 694        (List<HasOneToOneJDO>) q.execute(KeyFactory.keyToString(pojoEntity.getKey()));
 695    assertEquals(1, result.size());
 696    HasOneToOneJDO pojo = result.get(0);
 697    assertNotNull(pojo.getFlight());
 698    assertEquals("bos", pojo.getFlight().getOrigin());
 699    assertNotNull(pojo.getHasKeyPK());
 700    assertEquals("yar", pojo.getHasKeyPK().getStr());
 701    assertNotNull(pojo.getHasParent());
 702    assertEquals("yap", pojo.getHasParent().getStr());
 703    assertNotNull(pojo.getHasParentKeyPK());
 704    assertEquals("yag", pojo.getHasParentKeyPK().getStr());
 705    startEnd.end();
 706  }
 707
 708
 709  public void testChildFetchedLazily() throws Exception {
 710    // force a new pmf to get created after we've installed our own
 711    // DatastoreService mock
 712    pmf.close();
 713    tearDown();
 714    DatastoreService mockDatastore = EasyMock.createMock(DatastoreService.class);
 715    DatastoreServiceFactoryInternal.setDatastoreService(mockDatastore);
 716    Transaction txn;
 717    try {
 718      setUp();
 719
 720      Entity pojoEntity = new Entity(HasOneToOneJDO.class.getSimpleName());
 721      ds.put(pojoEntity);
 722
 723      Entity flightEntity = Flight.newFlightEntity(
 724          pojoEntity.getKey(), null, "jimmy", "bos", "mia", 5, 4, 33);
 725      ds.put(flightEntity);
 726
 727      Entity hasKeyPkEntity = new Entity(HasKeyPkJDO.class.getSimpleName(), pojoEntity.getKey());
 728      hasKeyPkEntity.setProperty("str", "yar");
 729      ds.put(hasKeyPkEntity);
 730
 731      Entity hasParentEntity =
 732          new Entity(HasOneToOneParentJDO.class.getSimpleName(), pojoEntity.getKey());
 733      hasParentEntity.setProperty("str", "yap");
 734      ds.put(hasParentEntity);
 735
 736      Entity hasParentKeyPkEntity =
 737          new Entity(HasOneToOneParentKeyPkJDO.class.getSimpleName(), pojoEntity.getKey());
 738      hasParentKeyPkEntity.setProperty("str", "yag");
 739      ds.put(hasParentKeyPkEntity);
 740
 741      // the only get we're going to perform is for the pojo
 742      txn = EasyMock.createMock(Transaction.class);
 743      EasyMock.expect(txn.getId()).andReturn("1").times(2);
 744      txn.commit();
 745      EasyMock.expectLastCall();
 746      EasyMock.replay(txn);
 747      EasyMock.expect(mockDatastore.beginTransaction(EasyMock.isA(TransactionOptions.class))).andReturn(txn);
 748      EasyMock.expect(mockDatastore.get(txn, pojoEntity.getKey())).andReturn(pojoEntity);
 749      EasyMock.replay(mockDatastore);
 750
 751      beginTxn();
 752      HasOneToOneJDO pojo = pm.getObjectById(HasOneToOneJDO.class, KeyFactory.keyToString(pojoEntity.getKey()));
 753      assertNotNull(pojo);
 754      pojo.getId();
 755      commitTxn();
 756    } finally {
 757      // need to close the pmf before we restore the original datastore service
 758      pmf.close();
 759      DatastoreServiceFactoryInternal.setDatastoreService(null);
 760    }
 761    EasyMock.verify(mockDatastore);
 762    EasyMock.verify(txn);
 763  }
 764
 765  public void testDeleteParentDeletesChild() {
 766    testDeleteParentDeletesChild(TXN_START_END);
 767  }
 768  public void testDeleteParentDeletesChild_NoTxn() {
 769    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 770    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 771    testDeleteParentDeletesChild(NEW_PM_START_END);
 772  }
 773  private void testDeleteParentDeletesChild(StartEnd startEnd) {
 774    Entity pojoEntity = new Entity(HasOneToOneJDO.class.getSimpleName());
 775    ds.put(pojoEntity);
 776
 777    Entity flightEntity = new Entity(Flight.class.getSimpleName(), pojoEntity.getKey());
 778    Flight.addData(flightEntity, "jimmy", "bos", "mia", 5, 4, 33);
 779    ds.put(flightEntity);
 780
 781    Entity hasKeyPkEntity = new Entity(HasKeyPkJDO.class.getSimpleName(), pojoEntity.getKey());
 782    hasKeyPkEntity.setProperty("str", "yar");
 783    ds.put(hasKeyPkEntity);
 784
 785    Entity hasParentEntity = new Entity(HasOneToOneParentJDO.class.getSimpleName(), pojoEntity.getKey());
 786    hasParentEntity.setProperty("str", "yap");
 787    ds.put(hasParentEntity);
 788
 789    Entity hasParentPkEntity = new Entity(HasOneToOneParentKeyPkJDO.class.getSimpleName(), pojoEntity.getKey());
 790    hasParentPkEntity.setProperty("str", "yag");
 791    ds.put(hasParentPkEntity);
 792
 793    Entity notDependentEntity = new Entity(HasEncodedStringPkJDO.class.getSimpleName(), pojoEntity.getKey());
 794    ds.put(notDependentEntity);
 795
 796    startEnd.start();
 797    HasOneToOneJDO pojo = pm.getObjectById(HasOneToOneJDO.class, KeyFactory.keyToString(pojoEntity.getKey()));
 798    pm.deletePersistent(pojo);
 799    startEnd.end();
 800    assertCountsInDatastore(0, 0);
 801    assertEquals(1, countForClass(HasEncodedStringPkJDO.class));
 802  }
 803
 804  public void testNonTransactionalUpdate() throws EntityNotFoundException {
 805    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 806
 807    Flight f = newFlight();
 808    HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
 809    HasOneToOneParentJDO hasParent = new HasOneToOneParentJDO();
 810    HasOneToOneParentKeyPkJDO hasParentKeyPk = new HasOneToOneParentKeyPkJDO();
 811
 812    HasOneToOneJDO pojo = new HasOneToOneJDO();
 813    pojo.setFlight(f);
 814    pojo.setHasKeyPK(hasKeyPk);
 815    pojo.setHasParent(hasParent);
 816    hasParent.setParent(pojo);
 817    pojo.setHasParentKeyPK(hasParentKeyPk);
 818    hasParentKeyPk.setParent(pojo);
 819
 820    pm.makePersistent(pojo);
 821
 822    pm.close();
 823
 824    assertCountsInDatastore(1, 1);
 825
 826    pm = pmf.getPersistenceManager();
 827    pojo = pm.getObjectById(HasOneToOneJDO.class, pojo.getId());
 828    pojo.setFlight(null);
 829    pojo.setHasKeyPK(null);
 830    pojo.setHasParent(null);
 831    pojo.setHasParentKeyPK(null);
 832    pm.close();
 833    pm = pmf.getPersistenceManager();
 834    
 835    assertCountsInDatastore(1, 0);
 836  }
 837
 838  public void testChangeParent() {
 839    testChangeParent(TXN_START_END);
 840  }
 841  public void testChangeParent_NoTxn() {
 842    testChangeParent(NEW_PM_START_END);
 843  }
 844  private void testChangeParent(StartEnd startEnd) {
 845    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 846    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 847    Flight f1 = newFlight();
 848
 849    HasOneToOneJDO pojo = new HasOneToOneJDO();
 850    pojo.setFlight(f1);
 851    startEnd.start();
 852    pm.makePersistent(pojo);
 853    f1 = pm.detachCopy(f1);
 854    startEnd.end();
 855
 856    HasOneToOneJDO pojo2 = new HasOneToOneJDO();
 857    startEnd.start();
 858    pojo2.setFlight(f1);
 859    try {
 860      pm.makePersistent(pojo2);
 861      fail("expected exception");
 862    } catch (JDOFatalUserException e) {
 863      // good
 864      if (pm.currentTransaction().isActive()) {
 865        rollbackTxn();
 866      }
 867    }
 868  }
 869
 870  public void testNewParentNewChild_SetNamedKeyOnChild() throws EntityNotFoundException {
 871    testNewParentNewChild_SetNamedKeyOnChild(TXN_START_END);
 872  }
 873  public void testNewParentNewChild_SetNamedKeyOnChild_NoTxn() throws EntityNotFoundException {
 874    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 875    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 876    testNewParentNewChild_SetNamedKeyOnChild(NEW_PM_START_END);
 877  }
 878  private void testNewParentNewChild_SetNamedKeyOnChild(StartEnd startEnd) throws EntityNotFoundException {
 879    HasOneToOneJDO pojo = new HasOneToOneJDO();
 880    Flight f1 = newFlight();
 881    pojo.setFlight(f1);
 882    f1.setId(KeyFactory.keyToString(KeyFactory.createKey(Flight.class.getSimpleName(), "named key")));
 883    startEnd.start();
 884    pm.makePersistent(pojo);
 885    startEnd.end();
 886
 887    Entity flightEntity = ds.get(KeyFactory.stringToKey(f1.getId()));
 888    assertEquals("named key", flightEntity.getKey().getName());
 889  }
 890
 891  public void testNewParentNewChild_LongKeyOnParent() throws EntityNotFoundException {
 892    testNewParentNewChild_LongKeyOnParent(TXN_START_END);
 893  }
 894  public void testNewParentNewChild_LongKeyOnParent_NoTxn() throws EntityNotFoundException {
 895    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 896    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 897    testNewParentNewChild_LongKeyOnParent(NEW_PM_START_END);
 898  }
 899  private void testNewParentNewChild_LongKeyOnParent(StartEnd startEnd) throws EntityNotFoundException {
 900    Flight f = newFlight();
 901    HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
 902    HasOneToOneLongPkParentJDO hasParent = new HasOneToOneLongPkParentJDO();
 903    HasOneToOneLongPkParentKeyPkJDO hasParentKeyPk = new HasOneToOneLongPkParentKeyPkJDO();
 904
 905    HasOneToOneLongPkJDO pojo = new HasOneToOneLongPkJDO();
 906    pojo.setFlight(f);
 907    pojo.setHasKeyPK(hasKeyPk);
 908    pojo.setHasParent(hasParent);
 909    hasParent.setParent(pojo);
 910    pojo.setHasParentKeyPK(hasParentKeyPk);
 911    hasParentKeyPk.setParent(pojo);
 912
 913    makePersistentInTxn(pojo, startEnd);
 914
 915    assertNotNull(f.getId());
 916    assertNotNull(hasKeyPk.getKey());
 917    assertNotNull(hasParent.getKey());
 918    assertNotNull(hasParentKeyPk.getKey());
 919    assertNotNull(pojo.getId());
 920
 921    Entity flightEntity = ds.get(KeyFactory.stringToKey(f.getId()));
 922    assertNotNull(flightEntity);
 923    assertEquals("jimmy", flightEntity.getProperty("name"));
 924    assertEquals("bos", flightEntity.getProperty("origin"));
 925    assertEquals("mia", flightEntity.getProperty("dest"));
 926    assertEquals(2L, flightEntity.getProperty("me"));
 927    assertEquals(3L, flightEntity.getProperty("you"));
 928    assertEquals(44L, flightEntity.getProperty("flight_number"));
 929    assertEquals(KeyFactory.stringToKey(f.getId()), flightEntity.getKey());
 930    assertKeyParentEquals(pojo.getClass(), pojo.getId(), flightEntity, f.getId());
 931
 932    Entity hasKeyPkEntity = ds.get(hasKeyPk.getKey());
 933    assertNotNull(hasKeyPkEntity);
 934    assertEquals(hasKeyPk.getKey(), hasKeyPkEntity.getKey());
 935    assertKeyParentEquals(pojo.getClass(), pojo.getId(), hasKeyPkEntity, hasKeyPk.getKey());
 936
 937    Entity hasParentEntity = ds.get(KeyFactory.stringToKey(hasParent.getKey()));
 938    assertNotNull(hasParentEntity);
 939    assertEquals(KeyFactory.stringToKey(hasParent.getKey()), hasParentEntity.getKey());
 940    assertKeyParentEquals(pojo.getClass(), pojo.getId(), hasParentEntity, hasParent.getKey());
 941
 942    Entity hasParentKeyPkEntity = ds.get(hasParentKeyPk.getKey());
 943    assertNotNull(hasParentKeyPkEntity);
 944    assertEquals(hasParentKeyPk.getKey(), hasParentKeyPkEntity.getKey());
 945    assertKeyParentEquals(pojo.getClass(), pojo.getId(), hasParentKeyPkEntity, hasParentKeyPk.getKey());
 946
 947    Entity pojoEntity = ds.get(TestUtils.createKey(pojo, pojo.getId()));
 948    assertNotNull(pojoEntity);
 949    assertEquals(flightEntity.getKey(), pojoEntity.getProperty("flight_id_OID"));
 950    assertEquals(hasKeyPkEntity.getKey(), pojoEntity.getProperty("hasKeyPK_key_OID"));
 951    assertEquals(hasParentEntity.getKey(), pojoEntity.getProperty("hasParent_key_OID"));
 952    assertEquals(hasParentKeyPkEntity.getKey(), pojoEntity.getProperty("hasParentKeyPK_key_OID"));
 953
 954    assertEquals(1, countForClass(HasOneToOneLongPkJDO.class));
 955    assertEquals(1, countForClass(Flight.class));
 956    assertEquals(1, countForClass(HasKeyPkJDO.class));
 957    assertEquals(1, countForClass(HasOneToOneLongPkParentJDO.class));
 958    assertEquals(1, countForClass(HasOneToOneLongPkParentKeyPkJDO.class));
 959  }
 960
 961  public void testNewParentNewChild_StringKeyOnParent() throws EntityNotFoundException {
 962    testNewParentNewChild_StringKeyOnParent(TXN_START_END);
 963  }
 964  public void testNewParentNewChild_StringKeyOnParent_NoTxn() throws EntityNotFoundException {
 965    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 966    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
 967    testNewParentNewChild_StringKeyOnParent(NEW_PM_START_END);
 968  }
 969  private void testNewParentNewChild_StringKeyOnParent(StartEnd startEnd) throws EntityNotFoundException {
 970    Flight f = newFlight();
 971    HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
 972    HasOneToOneStringPkParentJDO hasParent = new HasOneToOneStringPkParentJDO();
 973    HasOneToOneStringPkParentKeyPkJDO hasParentKeyPk = new HasOneToOneStringPkParentKeyPkJDO();
 974
 975    HasOneToOneStringPkJDO pojo = new HasOneToOneStringPkJDO();
 976    pojo.setId("yar");
 977    pojo.setFlight(f);
 978    pojo.setHasKeyPK(hasKeyPk);
 979    pojo.setHasParent(hasParent);
 980    hasParent.setParent(pojo);
 981    pojo.setHasParentKeyPK(hasParentKeyPk);
 982    hasParentKeyPk.setParent(pojo);
 983
 984    makePersistentInTxn(pojo, startEnd);
 985
 986    assertNotNull(f.getId());
 987    assertNotNull(hasKeyPk.getKey());
 988    assertNotNull(hasParent.getKey());
 989    assertNotNull(hasParentKeyPk.getKey());
 990    assertNotNull(pojo.getId());
 991
 992    Entity flightEntity = ds.get(KeyFactory.stringToKey(f.getId()));
 993    assertNotNull(flightEntity);
 994    assertEquals("jimmy", flightEntity.getProperty("name"));
 995    assertEquals("bos", flightEntity.getProperty("origin"));
 996    assertEquals("mia", flightEntity.getProperty("dest"));
 997    assertEquals(2L, flightEntity.getProperty("me"));
 998    assertEquals(3L, flightEntity.getProperty("you"));
 999    assertEquals(44L, flightEntity.getProperty("flight_number"));
1000    assertEquals(KeyFactory.stringToKey(f.getId()), flightEntity.getKey());
1001    assertKeyParentEquals(pojo.getClass(), pojo.getId(), flightEntity, f.getId());
1002
1003    Entity hasKeyPkEntity = ds.get(hasKeyPk.getKey());
1004    assertNotNull(hasKeyPkEntity);
1005    assertEquals(hasKeyPk.getKey(), hasKeyPkEntity.getKey());
1006    assertKeyParentEquals(pojo.getClass(), pojo.getId(), hasKeyPkEntity, hasKeyPk.getKey());
1007
1008    Entity hasParentEntity = ds.get(KeyFactory.stringToKey(hasParent.getKey()));
1009    assertNotNull(hasParentEntity);
1010    assertEquals(KeyFactory.stringToKey(hasParent.getKey()), hasParentEntity.getKey());
1011    assertKeyParentEquals(pojo.getClass(), pojo.getId(), hasParentEntity, hasParent.getKey());
1012
1013    Entity hasParentKeyPkEntity = ds.get(hasParentKeyPk.getKey());
1014    assertNotNull(hasParentKeyPkEntity);
1015    assertEquals(hasParentKeyPk.getKey(), hasParentKeyPkEntity.getKey());
1016    assertKeyParentEquals(pojo.getClass(), pojo.getId(), hasParentKeyPkEntity, hasParentKeyPk.getKey());
1017
1018    Entity pojoEntity = ds.get(TestUtils.createKey(pojo, pojo.getId()));
1019    assertNotNull(pojoEntity);
1020    assertEquals(flightEntity.getKey(), pojoEntity.getProperty("flight_id_OID"));
1021    assertEquals(hasKeyPkEntity.getKey(), pojoEntity.getProperty("hasKeyPK_key_OID"));
1022    assertEquals(hasParentEntity.getKey(), pojoEntity.getProperty("hasParent_key_OID"));
1023    assertEquals(hasParentKeyPkEntity.getKey(), pojoEntity.getProperty("hasParentKeyPK_key_OID"));
1024
1025    assertEquals(1, countForClass(HasOneToOneStringPkJDO.class));
1026    assertEquals(1, countForClass(Flight.class));
1027    assertEquals(1, countForClass(HasKeyPkJDO.class));
1028    assertEquals(1, countForClass(HasOneToOneStringPkParentJDO.class));
1029    assertEquals(1, countForClass(HasOneToOneStringPkParentKeyPkJDO.class));
1030  }
1031
1032  public void testAddAlreadyPersistedChildToParent_NoTxnDifferentPm() {
1033    switchDatasource(PersistenceManagerFactoryName.nontransactional);
1034    Flight f1 = new Flight();
1035    HasOneToOneJDO pojo = new HasOneToOneJDO();
1036    pm.makePersistent(f1);
1037    f1 = pm.detachCopy(f1);
1038    pm.close();
1039    pm = pmf.getPersistenceManager();
1040    pojo.setFlight(f1);
1041    try {
1042      pm.makePersistent(pojo);
1043      fail("expected exception");
1044    } catch (JDOFatalUserException e) {
1045      // good
1046    }
1047    pm.close();
1048
1049    assertEquals(0, countForClass(pojo.getClass()));
1050    assertEquals(1, countForClass(Flight.class));
1051  }
1052
1053  public void testAddAlreadyPersistedChildToParent_NoTxnSamePm() {
1054    switchDatasource(PersistenceManagerFactoryName.nontransactional);
1055    Flight f1 = new Flight();
1056    HasOneToOneJDO pojo = new HasOneToOneJDO();
1057    pm.makePersistent(f1);
1058    pojo.setFlight(f1);
1059    try {
1060      pm.makePersistent(pojo);
1061      fail("expected exception");
1062    } catch (JDOFatalUserException e) {
1063      // good
1064    }
1065    pm.close();
1066
1067    assertEquals(0, countForClass(pojo.getClass()));
1068    assertEquals(1, countForClass(Flight.class));
1069  }
1070
1071  public void testChildAtMultipleLevels() throws EntityNotFoundException {
1072    testChildAtMultipleLevels(TXN_START_END);
1073  }
1074  public void testChildAtMultipleLevels_NoTxn() throws EntityNotFoundException {
1075    switchDatasource(PersistenceManagerFactoryName.nontransactional);
1076    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
1077    pm.getFetchPlan().setMaxFetchDepth(3);
1078    testChildAtMultipleLevels(NEW_PM_START_END);
1079  }
1080  private void testChildAtMultipleLevels(StartEnd startEnd) throws EntityNotFoundException {
1081    HasOneToOneChildAtMultipleLevelsJDO pojo = new HasOneToOneChildAtMultipleLevelsJDO();
1082    Flight f1 = new Flight();
1083    pojo.setFlight(f1);
1084    HasOneToOneChildAtMultipleLevelsJDO child = new HasOneToOneChildAtMultipleLevelsJDO();
1085    Flight f2 = new Flight();
1086    child.setFlight(f2);
1087    pojo.setChild(child);
1088    startEnd.start();
1089    pm.makePersistent(pojo);
1090    startEnd.end();
1091    startEnd.start();
1092    pojo = pm.getObjectById(HasOneToOneChildAtMultipleLevelsJDO.class, pojo.getId());
1093    assertEquals(f1.getId(), pojo.getFlight().getId());
1094    assertEquals(child.getId(), pojo.getChild().getId());
1095    assertEquals(child.getFlight(), f2);
1096    assertNull(child.getChild());
1097    startEnd.end();
1098
1099    Entity pojoEntity = ds.get(pojo.getId());
1100    Entity childEntity = ds.get(child.getId());
1101    Entity flight1Entity = ds.get(KeyFactory.stringToKey(f1.getId()));
1102    Entity flight2Entity = ds.get(KeyFactory.stringToKey(f2.getId()));
1103    assertEquals(flight1Entity.getKey(), pojoEntity.getProperty("flight_id_OID"));
1104    assertEquals(childEntity.getKey(), pojoEntity.getProperty("child_id_OID"));
1105    assertEquals(flight2Entity.getKey(), childEntity.getProperty("flight_id_OID"));
1106    assertTrue(childEntity.hasProperty("child_id_OID"));
1107    assertNull(childEntity.getProperty("child_id_OID"));
1108  }
1109
1110  private static final class PutPolicy implements DatastoreServiceInterceptor.Policy {
1111    private final List<Object[]> putParamList = Utils.newArrayList();
1112    public void intercept(Object o, Method method, Object[] params) {
1113      if (method.getName().equals("put")) {
1114        putParamList.add(params);
1115      }
1116    }
1117  }
1118
1119  PutPolicy setupPutPolicy(HasOneToOneJDO pojo, HasOneToOneParentJDO hasParent, StartEnd startEnd,
1120                           int expectedPuts)
1121      throws Throwable {
1122    PutPolicy policy = new PutPolicy();
1123    DatastoreServiceInterceptor.install(getStoreManager(), policy);
1124    try {
1125      pmf.close();
1126      switchDatasource(startEnd.getPmfName());
1127      Flight flight = new Flight();
1128      pojo.setFlight(flight);
1129      pojo.setHasParent(hasParent);
1130      HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
1131      pojo.setHasKeyPK(hasKeyPk);
1132
1133      startEnd.start();
1134      pm.makePersistent(pojo);
1135      startEnd.end();
1136      assertEquals(expectedPuts, policy.putParamList.size());
1137      policy.putParamList.clear();
1138      return policy;
1139    } catch (Throwable t) {
1140      DatastoreServiceInterceptor.uninstall();
1141      throw t;
1142    }
1143  }
1144
1145  public void testOnlyOnePutOnChildUpdate() throws Throwable {
1146    // 1 put for the parent, 3 puts for the children, 1 more put
1147    // to add the child keys back on the parent
1148    int expectedPutsInSetup = 5;
1149    testOnlyOnePutOnChildUpdate(TXN_START_END, expectedPutsInSetup);
1150  }
1151
1152  public void testOnlyOnePutOnChildUpdate_NoTxn() throws Throwable {
1153    // 1 put for the parent, 3 puts for the children, 1 more put
1154    // to add the child keys back on the parent
1155    int expectedPutsInSetup = 5;
1156    testOnlyOnePutOnChildUpdate(NEW_PM_START_END, expectedPutsInSetup);
1157  }
1158
1159  private void testOnlyOnePutOnChildUpdate(StartEnd startEnd, int expectedPutsInSetup)
1160      throws Throwable {
1161    HasOneToOneJDO pojo = new HasOneToOneJDO();
1162    HasOneToOneParentJDO hasParent = new HasOneToOneParentJDO();
1163    PutPolicy policy = setupPutPolicy(pojo, hasParent, startEnd, expectedPutsInSetup);
1164    try {
1165      startEnd.start();
1166      pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
1167      pojo.getFlight().setMe(88);
1168      pojo.getHasParent().setStr("blarg");
1169      pojo.getHasKeyPK().setStr("double blarg");
1170      startEnd.end();
1171    } finally {
1172      DatastoreServiceInterceptor.uninstall();
1173    }
1174    // 1 put for each child update
1175    assertEquals(3, policy.putParamList.size());
1176  }
1177
1178  public void testOnlyOneParentPutOnParentAndChildUpdate() throws Throwable {
1179    // 1 put for the parent, 3 puts for the children, 1 more put
1180    // to add the child keys back on the parent
1181    int expectedPutsInSetup = 5;
1182    testOnlyOneParentPutOnParentAndChildUpdate(TXN_START_END, expectedPutsInSetup);
1183  }
1184  public void testOnlyOneParentPutOnParentAndChildUpdate_NoTxn() throws Throwable {
1185    // 1 put for the parent, 3 puts for the children, 1 more put
1186    // to add the child keys back on the parent
1187    int expectedPutsInSetup = 5;
1188    testOnlyOneParentPutOnParentAndChildUpdate(NEW_PM_START_END, expectedPutsInSetup);
1189  }
1190  private void testOnlyOneParentPutOnParentAndChildUpdate(StartEnd startEnd, int expectedPutsInSetup)
1191      throws Throwable {
1192    HasOneToOneJDO pojo = new HasOneToOneJDO();
1193    HasOneToOneParentJDO hasParent = new HasOneToOneParentJDO();
1194    PutPolicy policy = setupPutPolicy(pojo, hasParent, startEnd, expectedPutsInSetup);
1195    try {
1196      startEnd.start();
1197      pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
1198      pojo.setStr("another val");
1199      pojo.getFlight().setMe(88);
1200      pojo.getHasParent().setStr("blarg");
1201      pojo.getHasKeyPK().setStr("double blarg");
1202      startEnd.end();
1203    } finally {
1204      DatastoreServiceInterceptor.uninstall();
1205    }
1206    // 1 put for the parent update, 1 put for each child update
1207    assertEquals(4, policy.putParamList.size());
1208  }
1209
1210  public void testOnlyOneParentPutOnChildDelete() throws Throwable {
1211    // 1 put for the pare

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