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

http://datanucleus-appengine.googlecode.com/ · Java · 1713 lines · 1415 code · 213 blank · 85 comment · 96 complexity · dd56daf6ee210431500db8af72891577 MD5 · raw file

  1. /**********************************************************************
  2. Copyright (c) 2009 Google Inc.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. **********************************************************************/
  13. package com.google.appengine.datanucleus.jdo;
  14. import com.google.appengine.api.datastore.DatastoreService;
  15. import com.google.appengine.api.datastore.DatastoreServiceConfig;
  16. import com.google.appengine.api.datastore.Entity;
  17. import com.google.appengine.api.datastore.EntityNotFoundException;
  18. import com.google.appengine.api.datastore.Key;
  19. import com.google.appengine.api.datastore.KeyFactory;
  20. import com.google.appengine.api.datastore.Query;
  21. import com.google.appengine.api.datastore.Transaction;
  22. import com.google.appengine.api.datastore.TransactionOptions;
  23. import com.google.appengine.datanucleus.DatastoreServiceFactoryInternal;
  24. import com.google.appengine.datanucleus.DatastoreServiceInterceptor;
  25. import com.google.appengine.datanucleus.StorageVersion;
  26. import com.google.appengine.datanucleus.Utils;
  27. import com.google.appengine.datanucleus.test.jdo.BidirectionalChildJDO;
  28. import com.google.appengine.datanucleus.test.jdo.BidirectionalChildLongPkJDO;
  29. import com.google.appengine.datanucleus.test.jdo.BidirectionalChildUnencodedStringPkJDO;
  30. import com.google.appengine.datanucleus.test.jdo.Flight;
  31. import com.google.appengine.datanucleus.test.jdo.HasExplicitIndexColumnJDO;
  32. import com.google.appengine.datanucleus.test.jdo.HasKeyPkJDO;
  33. import com.google.appengine.datanucleus.test.jdo.HasOneToManyJDO;
  34. import com.google.appengine.datanucleus.test.jdo.HasOneToManyKeyPkJDO;
  35. import com.google.appengine.datanucleus.test.jdo.HasOneToManyListJDO;
  36. import com.google.appengine.datanucleus.test.jdo.HasOneToManyListWithOrderByJDO;
  37. import com.google.appengine.datanucleus.test.jdo.HasOneToManyLongPkJDO;
  38. import com.google.appengine.datanucleus.test.jdo.HasOneToManyUnencodedStringPkJDO;
  39. import com.google.appengine.datanucleus.test.jdo.HasOneToManyWithOrderByJDO;
  40. import org.easymock.EasyMock;
  41. import java.lang.reflect.Method;
  42. import java.util.Collection;
  43. import java.util.Collections;
  44. import java.util.ConcurrentModificationException;
  45. import java.util.Iterator;
  46. import java.util.List;
  47. import java.util.Set;
  48. import javax.jdo.JDOFatalUserException;
  49. import static com.google.appengine.datanucleus.TestUtils.assertKeyParentEquals;
  50. /**
  51. * @author Max Ross <maxr@google.com>
  52. */
  53. abstract class JDOOneToManyTestCase extends JDOTestCase {
  54. @Override
  55. protected void tearDown() throws Exception {
  56. try {
  57. if (!pm.isClosed() && pm.currentTransaction().isActive()) {
  58. pm.currentTransaction().rollback();
  59. }
  60. pmf.close();
  61. } finally {
  62. super.tearDown();
  63. }
  64. }
  65. void testInsert_NewParentAndChild(HasOneToManyJDO parent,
  66. BidirectionalChildJDO bidirChild, StartEnd startEnd) throws EntityNotFoundException {
  67. bidirChild.setChildVal("yam");
  68. Flight f = newFlight();
  69. HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
  70. hasKeyPk.setStr("yag");
  71. parent.addBidirChild(bidirChild);
  72. bidirChild.setParent(parent);
  73. parent.addFlight(f);
  74. parent.addHasKeyPk(hasKeyPk);
  75. parent.setVal("yar");
  76. startEnd.start();
  77. pm.makePersistent(parent);
  78. startEnd.end();
  79. assertNotNull(bidirChild.getId());
  80. assertNotNull(f.getId());
  81. assertNotNull(hasKeyPk.getKey());
  82. Entity bidirChildEntity = ds.get(KeyFactory.stringToKey(bidirChild.getId()));
  83. assertNotNull(bidirChildEntity);
  84. assertEquals("yam", bidirChildEntity.getProperty("childVal"));
  85. assertEquals(KeyFactory.stringToKey(bidirChild.getId()), bidirChildEntity.getKey());
  86. assertKeyParentEquals(parent.getId(), bidirChildEntity, bidirChild.getId());
  87. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  88. assertEquals(0L, bidirChildEntity.getProperty("bidirChildren_INTEGER_IDX"));
  89. }
  90. Entity flightEntity = ds.get(KeyFactory.stringToKey(f.getId()));
  91. assertNotNull(flightEntity);
  92. assertEquals("bos", flightEntity.getProperty("origin"));
  93. assertEquals("mia", flightEntity.getProperty("dest"));
  94. assertEquals("jimmy", flightEntity.getProperty("name"));
  95. assertEquals(KeyFactory.stringToKey(f.getId()), flightEntity.getKey());
  96. assertKeyParentEquals(parent.getId(), flightEntity, f.getId());
  97. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  98. assertEquals(0L, flightEntity.getProperty("flights_INTEGER_IDX"));
  99. }
  100. Entity hasKeyPkEntity = ds.get(hasKeyPk.getKey());
  101. assertNotNull(hasKeyPkEntity);
  102. assertEquals("yag", hasKeyPkEntity.getProperty("str"));
  103. assertEquals(hasKeyPk.getKey(), hasKeyPkEntity.getKey());
  104. assertKeyParentEquals(parent.getId(), hasKeyPkEntity, hasKeyPk.getKey());
  105. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  106. assertEquals(0L, hasKeyPkEntity.getProperty("hasKeyPks_INTEGER_IDX"));
  107. }
  108. Entity parentEntity = ds.get(KeyFactory.stringToKey(parent.getId()));
  109. assertNotNull(parentEntity);
  110. assertEquals(4, parentEntity.getProperties().size());
  111. assertEquals("yar", parentEntity.getProperty("val"));
  112. assertEquals(Utils.newArrayList(bidirChildEntity.getKey()), parentEntity.getProperty("bidirChildren"));
  113. assertEquals(Utils.newArrayList(flightEntity.getKey()), parentEntity.getProperty("flights"));
  114. assertEquals(Utils.newArrayList(hasKeyPkEntity.getKey()), parentEntity.getProperty("hasKeyPks"));
  115. assertCountsInDatastore(parent.getClass(), bidirChild.getClass(), 1, 1);
  116. }
  117. void testInsert_ExistingParentNewChild(HasOneToManyJDO pojo,
  118. BidirectionalChildJDO bidirChild, StartEnd startEnd) throws EntityNotFoundException {
  119. pojo.setVal("yar");
  120. startEnd.start();
  121. pm.makePersistent(pojo);
  122. startEnd.end();
  123. startEnd.start();
  124. assertNotNull(pojo.getId());
  125. assertTrue(pojo.getFlights().isEmpty());
  126. assertTrue(pojo.getHasKeyPks().isEmpty());
  127. assertTrue(pojo.getBidirChildren().isEmpty());
  128. Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
  129. assertNotNull(pojoEntity);
  130. assertEquals(4, pojoEntity.getProperties().size());
  131. assertEquals("yar", pojoEntity.getProperty("val"));
  132. assertTrue(pojoEntity.hasProperty("bidirChildren"));
  133. assertNull(pojoEntity.getProperty("bidirChildren"));
  134. assertTrue(pojoEntity.hasProperty("flights"));
  135. assertNull(pojoEntity.getProperty("flights"));
  136. assertTrue(pojoEntity.hasProperty("hasKeyPks"));
  137. assertNull(pojoEntity.getProperty("hasKeyPks"));
  138. startEnd.end();
  139. startEnd.start();
  140. pojo = pm.makePersistent(pojo);
  141. assertEquals("yar", pojo.getVal());
  142. Flight f = newFlight();
  143. pojo.addFlight(f);
  144. HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
  145. hasKeyPk.setStr("yag");
  146. pojo.addHasKeyPk(hasKeyPk);
  147. bidirChild.setChildVal("yam");
  148. pojo.addBidirChild(bidirChild);
  149. startEnd.end();
  150. startEnd.start();
  151. assertNotNull(bidirChild.getId());
  152. assertNotNull(bidirChild.getParent());
  153. assertNotNull(f.getId());
  154. assertNotNull(hasKeyPk.getKey());
  155. startEnd.end();
  156. Entity bidirChildEntity = ds.get(KeyFactory.stringToKey(bidirChild.getId()));
  157. assertNotNull(bidirChildEntity);
  158. assertEquals("yam", bidirChildEntity.getProperty("childVal"));
  159. assertEquals(KeyFactory.stringToKey(bidirChild.getId()), bidirChildEntity.getKey());
  160. assertKeyParentEquals(pojo.getId(), bidirChildEntity, bidirChild.getId());
  161. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  162. assertEquals(0L, bidirChildEntity.getProperty("bidirChildren_INTEGER_IDX"));
  163. }
  164. Entity flightEntity = ds.get(KeyFactory.stringToKey(f.getId()));
  165. assertNotNull(flightEntity);
  166. assertEquals("bos", flightEntity.getProperty("origin"));
  167. assertEquals("mia", flightEntity.getProperty("dest"));
  168. assertEquals("jimmy", flightEntity.getProperty("name"));
  169. assertEquals(KeyFactory.stringToKey(f.getId()), flightEntity.getKey());
  170. assertKeyParentEquals(pojo.getId(), flightEntity, f.getId());
  171. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  172. assertEquals(0L, flightEntity.getProperty("flights_INTEGER_IDX"));
  173. }
  174. Entity hasKeyPkEntity = ds.get(hasKeyPk.getKey());
  175. assertNotNull(hasKeyPkEntity);
  176. assertEquals("yag", hasKeyPkEntity.getProperty("str"));
  177. assertEquals(hasKeyPk.getKey(), hasKeyPkEntity.getKey());
  178. assertKeyParentEquals(pojo.getId(), hasKeyPkEntity, hasKeyPk.getKey());
  179. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  180. assertEquals(0L, hasKeyPkEntity.getProperty("hasKeyPks_INTEGER_IDX"));
  181. }
  182. Entity parentEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
  183. assertNotNull(parentEntity);
  184. assertEquals(4, parentEntity.getProperties().size());
  185. assertEquals("yar", parentEntity.getProperty("val"));
  186. assertEquals(Utils.newArrayList(bidirChildEntity.getKey()), parentEntity.getProperty("bidirChildren"));
  187. assertEquals(Utils.newArrayList(flightEntity.getKey()), parentEntity.getProperty("flights"));
  188. assertEquals(Utils.newArrayList(hasKeyPkEntity.getKey()), parentEntity.getProperty("hasKeyPks"));
  189. assertCountsInDatastore(pojo.getClass(), bidirChild.getClass(), 1, 1);
  190. }
  191. void testSwapAtPosition(HasOneToManyJDO pojo,
  192. BidirectionalChildJDO bidir1,
  193. BidirectionalChildJDO bidir2, StartEnd startEnd) throws EntityNotFoundException {
  194. pojo.setVal("yar");
  195. bidir2.setChildVal("yam");
  196. Flight f = newFlight();
  197. HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
  198. pojo.addFlight(f);
  199. pojo.addHasKeyPk(hasKeyPk);
  200. pojo.addBidirChild(bidir1);
  201. bidir1.setParent(pojo);
  202. startEnd.start();
  203. pm.makePersistent(pojo);
  204. startEnd.end();
  205. assertCountsInDatastore(pojo.getClass(), bidir1.getClass(), 1, 1);
  206. startEnd.start();
  207. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  208. String bidir1Id = pojo.getBidirChildren().iterator().next().getId();
  209. String flight1Id = pojo.getFlights().iterator().next().getId();
  210. Key hasKeyPk1Key = pojo.getHasKeyPks().iterator().next().getKey();
  211. pojo.addBidirChildAtPosition(bidir2, 0);
  212. Flight f2 = newFlight();
  213. f2.setName("another name");
  214. pojo.addFlightAtPosition(f2, 0);
  215. HasKeyPkJDO hasKeyPk2 = new HasKeyPkJDO();
  216. hasKeyPk2.setStr("another str");
  217. pojo.addHasKeyPkAtPosition(hasKeyPk2, 0);
  218. startEnd.end();
  219. startEnd.start();
  220. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  221. assertNotNull(pojo.getId());
  222. assertEquals(1, pojo.getFlights().size());
  223. assertEquals(1, pojo.getHasKeyPks().size());
  224. assertEquals(1, pojo.getBidirChildren().size());
  225. assertNotNull(bidir2.getId());
  226. assertNotNull(bidir2.getParent());
  227. assertNotNull(f2.getId());
  228. assertNotNull(hasKeyPk2.getKey());
  229. Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
  230. assertNotNull(pojoEntity);
  231. assertEquals(4, pojoEntity.getProperties().size());
  232. assertEquals(Utils.newArrayList(KeyFactory.stringToKey(bidir2.getId())), pojoEntity.getProperty("bidirChildren"));
  233. assertEquals(Utils.newArrayList(KeyFactory.stringToKey(f2.getId())), pojoEntity.getProperty("flights"));
  234. assertEquals(Utils.newArrayList(hasKeyPk2.getKey()), pojoEntity.getProperty("hasKeyPks"));
  235. startEnd.end();
  236. try {
  237. ds.get(KeyFactory.stringToKey(bidir1Id));
  238. fail("expected EntityNotFoundException");
  239. } catch (EntityNotFoundException enfe) {
  240. // good
  241. }
  242. try {
  243. ds.get(KeyFactory.stringToKey(flight1Id));
  244. fail("expected EntityNotFoundException");
  245. } catch (EntityNotFoundException enfe) {
  246. // good
  247. }
  248. try {
  249. ds.get(hasKeyPk1Key);
  250. fail("expected EntityNotFoundException");
  251. } catch (EntityNotFoundException enfe) {
  252. // good
  253. }
  254. Entity bidirChildEntity = ds.get(KeyFactory.stringToKey(bidir2.getId()));
  255. assertNotNull(bidirChildEntity);
  256. assertEquals("yam", bidirChildEntity.getProperty("childVal"));
  257. assertEquals(KeyFactory.stringToKey(bidir2.getId()), bidirChildEntity.getKey());
  258. assertKeyParentEquals(pojo.getId(), bidirChildEntity, bidir2.getId());
  259. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  260. assertEquals(0L, bidirChildEntity.getProperty("bidirChildren_INTEGER_IDX"));
  261. }
  262. Entity flightEntity = ds.get(KeyFactory.stringToKey(f2.getId()));
  263. assertNotNull(flightEntity);
  264. assertEquals("bos", flightEntity.getProperty("origin"));
  265. assertEquals("mia", flightEntity.getProperty("dest"));
  266. assertEquals("another name", flightEntity.getProperty("name"));
  267. assertEquals(KeyFactory.stringToKey(f2.getId()), flightEntity.getKey());
  268. assertKeyParentEquals(pojo.getId(), flightEntity, f2.getId());
  269. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  270. assertEquals(0L, flightEntity.getProperty("flights_INTEGER_IDX"));
  271. }
  272. Entity hasKeyPkEntity = ds.get(hasKeyPk2.getKey());
  273. assertNotNull(hasKeyPkEntity);
  274. assertEquals("another str", hasKeyPkEntity.getProperty("str"));
  275. assertEquals(hasKeyPk2.getKey(), hasKeyPkEntity.getKey());
  276. assertKeyParentEquals(pojo.getId(), hasKeyPkEntity, hasKeyPk2.getKey());
  277. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  278. assertEquals(0L, hasKeyPkEntity.getProperty("hasKeyPks_INTEGER_IDX"));
  279. }
  280. Entity parentEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
  281. assertNotNull(parentEntity);
  282. assertEquals(4, parentEntity.getProperties().size());
  283. assertEquals("yar", parentEntity.getProperty("val"));
  284. assertEquals(Utils.newArrayList(bidirChildEntity.getKey()), parentEntity.getProperty("bidirChildren"));
  285. assertEquals(Utils.newArrayList(flightEntity.getKey()), parentEntity.getProperty("flights"));
  286. assertEquals(Utils.newArrayList(hasKeyPkEntity.getKey()), parentEntity.getProperty("hasKeyPks"));
  287. assertCountsInDatastore(pojo.getClass(), bidir2.getClass(), 1, 1);
  288. }
  289. void testRemoveAtPosition(HasOneToManyJDO pojo,
  290. BidirectionalChildJDO bidir1,
  291. BidirectionalChildJDO bidir2,
  292. BidirectionalChildJDO bidir3, StartEnd startEnd) throws EntityNotFoundException {
  293. pojo.setVal("yar");
  294. bidir2.setChildVal("another yam");
  295. bidir3.setChildVal("yet another yam");
  296. Flight f = newFlight();
  297. Flight f2 = newFlight();
  298. Flight f3 = newFlight();
  299. f2.setName("another name");
  300. f3.setName("yet another name");
  301. HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
  302. HasKeyPkJDO hasKeyPk2 = new HasKeyPkJDO();
  303. HasKeyPkJDO hasKeyPk3 = new HasKeyPkJDO();
  304. hasKeyPk2.setStr("another str");
  305. hasKeyPk3.setStr("yet another str");
  306. pojo.addFlight(f);
  307. pojo.addFlight(f2);
  308. pojo.addFlight(f3);
  309. pojo.addHasKeyPk(hasKeyPk);
  310. pojo.addHasKeyPk(hasKeyPk2);
  311. pojo.addHasKeyPk(hasKeyPk3);
  312. pojo.addBidirChild(bidir1);
  313. pojo.addBidirChild(bidir2);
  314. pojo.addBidirChild(bidir3);
  315. startEnd.start();
  316. pm.makePersistent(pojo);
  317. startEnd.end();
  318. assertCountsInDatastore(pojo.getClass(), bidir1.getClass(), 1, 3);
  319. startEnd.start();
  320. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  321. String bidir1Id = pojo.getBidirChildren().iterator().next().getId();
  322. String flight1Id = pojo.getFlights().iterator().next().getId();
  323. Key hasKeyPk1Key = pojo.getHasKeyPks().iterator().next().getKey();
  324. pojo.removeBidirChildAtPosition(0);
  325. pojo.removeFlightAtPosition(0);
  326. pojo.removeHasKeyPkAtPosition(0);
  327. startEnd.end();
  328. startEnd.start();
  329. assertNotNull(pojo.getId());
  330. assertEquals(2, pojo.getFlights().size());
  331. assertEquals(2, pojo.getHasKeyPks().size());
  332. assertEquals(2, pojo.getBidirChildren().size());
  333. Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
  334. assertNotNull(pojoEntity);
  335. assertEquals(4, pojoEntity.getProperties().size());
  336. assertEquals(Utils.newArrayList(
  337. KeyFactory.stringToKey(bidir2.getId()),
  338. KeyFactory.stringToKey(bidir3.getId())), pojoEntity.getProperty("bidirChildren"));
  339. assertEquals(Utils.newArrayList(
  340. KeyFactory.stringToKey(f2.getId()),
  341. KeyFactory.stringToKey(f3.getId())), pojoEntity.getProperty("flights"));
  342. assertEquals(Utils.newArrayList(
  343. hasKeyPk2.getKey(),
  344. hasKeyPk3.getKey()), pojoEntity.getProperty("hasKeyPks"));
  345. startEnd.end();
  346. try {
  347. ds.get(KeyFactory.stringToKey(bidir1Id));
  348. fail("expected EntityNotFoundException");
  349. } catch (EntityNotFoundException enfe) {
  350. // good
  351. }
  352. try {
  353. ds.get(KeyFactory.stringToKey(flight1Id));
  354. fail("expected EntityNotFoundException");
  355. } catch (EntityNotFoundException enfe) {
  356. // good
  357. }
  358. try {
  359. ds.get(hasKeyPk1Key);
  360. fail("expected EntityNotFoundException");
  361. } catch (EntityNotFoundException enfe) {
  362. // good
  363. }
  364. Entity bidirChildEntity = ds.get(KeyFactory.stringToKey(bidir2.getId()));
  365. assertNotNull(bidirChildEntity);
  366. assertEquals("another yam", bidirChildEntity.getProperty("childVal"));
  367. assertEquals(KeyFactory.stringToKey(bidir2.getId()), bidirChildEntity.getKey());
  368. assertKeyParentEquals(pojo.getId(), bidirChildEntity, bidir2.getId());
  369. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  370. assertEquals(0L, bidirChildEntity.getProperty("bidirChildren_INTEGER_IDX"));
  371. }
  372. bidirChildEntity = ds.get(KeyFactory.stringToKey(bidir3.getId()));
  373. assertNotNull(bidirChildEntity);
  374. assertEquals("yet another yam", bidirChildEntity.getProperty("childVal"));
  375. assertEquals(KeyFactory.stringToKey(bidir3.getId()), bidirChildEntity.getKey());
  376. assertKeyParentEquals(pojo.getId(), bidirChildEntity, bidir2.getId());
  377. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  378. assertEquals(1L, bidirChildEntity.getProperty("bidirChildren_INTEGER_IDX"));
  379. }
  380. Entity flightEntity = ds.get(KeyFactory.stringToKey(f2.getId()));
  381. assertNotNull(flightEntity);
  382. assertEquals("bos", flightEntity.getProperty("origin"));
  383. assertEquals("mia", flightEntity.getProperty("dest"));
  384. assertEquals("another name", flightEntity.getProperty("name"));
  385. assertEquals(KeyFactory.stringToKey(f2.getId()), flightEntity.getKey());
  386. assertKeyParentEquals(pojo.getId(), flightEntity, f2.getId());
  387. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  388. assertEquals(0L, flightEntity.getProperty("flights_INTEGER_IDX"));
  389. }
  390. flightEntity = ds.get(KeyFactory.stringToKey(f3.getId()));
  391. assertNotNull(flightEntity);
  392. assertEquals("bos", flightEntity.getProperty("origin"));
  393. assertEquals("mia", flightEntity.getProperty("dest"));
  394. assertEquals("yet another name", flightEntity.getProperty("name"));
  395. assertEquals(KeyFactory.stringToKey(f3.getId()), flightEntity.getKey());
  396. assertKeyParentEquals(pojo.getId(), flightEntity, f2.getId());
  397. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  398. assertEquals(1L, flightEntity.getProperty("flights_INTEGER_IDX"));
  399. }
  400. Entity hasKeyPkEntity = ds.get(hasKeyPk2.getKey());
  401. assertNotNull(hasKeyPkEntity);
  402. assertEquals("another str", hasKeyPkEntity.getProperty("str"));
  403. assertEquals(hasKeyPk2.getKey(), hasKeyPkEntity.getKey());
  404. assertKeyParentEquals(pojo.getId(), hasKeyPkEntity, hasKeyPk2.getKey());
  405. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  406. assertEquals(0L, hasKeyPkEntity.getProperty("hasKeyPks_INTEGER_IDX"));
  407. }
  408. hasKeyPkEntity = ds.get(hasKeyPk3.getKey());
  409. assertNotNull(hasKeyPkEntity);
  410. assertEquals("yet another str", hasKeyPkEntity.getProperty("str"));
  411. assertEquals(hasKeyPk3.getKey(), hasKeyPkEntity.getKey());
  412. assertKeyParentEquals(pojo.getId(), hasKeyPkEntity, hasKeyPk2.getKey());
  413. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  414. assertEquals(1L, hasKeyPkEntity.getProperty("hasKeyPks_INTEGER_IDX"));
  415. }
  416. Entity parentEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
  417. assertNotNull(parentEntity);
  418. assertEquals(4, parentEntity.getProperties().size());
  419. assertEquals("yar", parentEntity.getProperty("val"));
  420. assertEquals(Utils.newArrayList(
  421. KeyFactory.stringToKey(bidir2.getId()),
  422. KeyFactory.stringToKey(bidir3.getId())), parentEntity.getProperty("bidirChildren"));
  423. assertEquals(Utils.newArrayList(
  424. KeyFactory.stringToKey(f2.getId()),
  425. KeyFactory.stringToKey(f3.getId())), parentEntity.getProperty("flights"));
  426. assertEquals(Utils.newArrayList(
  427. hasKeyPk2.getKey(),
  428. hasKeyPk3.getKey()), parentEntity.getProperty("hasKeyPks"));
  429. assertCountsInDatastore(pojo.getClass(), bidir2.getClass(), 1, 2);
  430. }
  431. void testAddAtPosition(HasOneToManyJDO pojo,
  432. BidirectionalChildJDO bidir1,
  433. BidirectionalChildJDO bidir2, StartEnd startEnd) throws EntityNotFoundException {
  434. pojo.setVal("yar");
  435. bidir2.setChildVal("yam");
  436. Flight f = newFlight();
  437. Flight f2 = newFlight();
  438. f2.setName("another name");
  439. HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
  440. HasKeyPkJDO hasKeyPk2 = new HasKeyPkJDO();
  441. hasKeyPk2.setStr("another str");
  442. pojo.addFlight(f);
  443. pojo.addHasKeyPk(hasKeyPk);
  444. pojo.addBidirChild(bidir1);
  445. startEnd.start();
  446. pm.makePersistent(pojo);
  447. startEnd.end();
  448. assertCountsInDatastore(pojo.getClass(), bidir1.getClass(), 1, 1);
  449. startEnd.start();
  450. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  451. String bidir1Id = pojo.getBidirChildren().iterator().next().getId();
  452. String flight1Id = pojo.getFlights().iterator().next().getId();
  453. Key hasKeyPk1Key = pojo.getHasKeyPks().iterator().next().getKey();
  454. pojo.addAtPosition(0, bidir2);
  455. pojo.addAtPosition(0, f2);
  456. pojo.addAtPosition(0, hasKeyPk2);
  457. startEnd.end();
  458. startEnd.start();
  459. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  460. assertNotNull(pojo.getId());
  461. assertEquals(2, pojo.getFlights().size());
  462. assertEquals(2, pojo.getHasKeyPks().size());
  463. assertEquals(2, pojo.getBidirChildren().size());
  464. assertNotNull(bidir2.getId());
  465. assertNotNull(bidir2.getParent());
  466. assertNotNull(f2.getId());
  467. assertNotNull(hasKeyPk2.getKey());
  468. Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
  469. assertNotNull(pojoEntity);
  470. assertEquals(4, pojoEntity.getProperties().size());
  471. assertEquals(Utils.newArrayList(
  472. KeyFactory.stringToKey(bidir2.getId()),
  473. KeyFactory.stringToKey(bidir1.getId())), pojoEntity.getProperty("bidirChildren"));
  474. assertEquals(Utils.newArrayList(
  475. KeyFactory.stringToKey(f2.getId()),
  476. KeyFactory.stringToKey(f.getId())), pojoEntity.getProperty("flights"));
  477. assertEquals(Utils.newArrayList(
  478. hasKeyPk2.getKey(),
  479. hasKeyPk.getKey()), pojoEntity.getProperty("hasKeyPks"));
  480. startEnd.end();
  481. ds.get(KeyFactory.stringToKey(bidir1Id));
  482. ds.get(KeyFactory.stringToKey(flight1Id));
  483. ds.get(hasKeyPk1Key);
  484. Entity bidirChildEntity = ds.get(KeyFactory.stringToKey(bidir2.getId()));
  485. assertNotNull(bidirChildEntity);
  486. assertEquals("yam", bidirChildEntity.getProperty("childVal"));
  487. assertEquals(KeyFactory.stringToKey(bidir2.getId()), bidirChildEntity.getKey());
  488. assertKeyParentEquals(pojo.getId(), bidirChildEntity, bidir2.getId());
  489. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  490. assertEquals(0L, bidirChildEntity.getProperty("bidirChildren_INTEGER_IDX"));
  491. }
  492. Entity flightEntity = ds.get(KeyFactory.stringToKey(f2.getId()));
  493. assertNotNull(flightEntity);
  494. assertEquals("bos", flightEntity.getProperty("origin"));
  495. assertEquals("mia", flightEntity.getProperty("dest"));
  496. assertEquals("another name", flightEntity.getProperty("name"));
  497. assertEquals(KeyFactory.stringToKey(f2.getId()), flightEntity.getKey());
  498. assertKeyParentEquals(pojo.getId(), flightEntity, f2.getId());
  499. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  500. assertEquals(0L, flightEntity.getProperty("flights_INTEGER_IDX"));
  501. }
  502. Entity hasKeyPkEntity = ds.get(hasKeyPk2.getKey());
  503. assertNotNull(hasKeyPkEntity);
  504. assertEquals("another str", hasKeyPkEntity.getProperty("str"));
  505. assertEquals(hasKeyPk2.getKey(), hasKeyPkEntity.getKey());
  506. assertKeyParentEquals(pojo.getId(), hasKeyPkEntity, hasKeyPk2.getKey());
  507. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  508. assertEquals(0L, hasKeyPkEntity.getProperty("hasKeyPks_INTEGER_IDX"));
  509. }
  510. Entity parentEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
  511. assertNotNull(parentEntity);
  512. assertEquals(4, parentEntity.getProperties().size());
  513. assertEquals("yar", parentEntity.getProperty("val"));
  514. assertEquals(Utils.newArrayList(
  515. KeyFactory.stringToKey(bidir2.getId()),
  516. KeyFactory.stringToKey(bidir1.getId())), parentEntity.getProperty("bidirChildren"));
  517. assertEquals(Utils.newArrayList(
  518. KeyFactory.stringToKey(f2.getId()),
  519. KeyFactory.stringToKey(f.getId())), parentEntity.getProperty("flights"));
  520. assertEquals(Utils.newArrayList(
  521. hasKeyPk2.getKey(),
  522. hasKeyPk.getKey()), parentEntity.getProperty("hasKeyPks"));
  523. assertCountsInDatastore(pojo.getClass(), bidir2.getClass(), 1, 2);
  524. }
  525. void testUpdate_UpdateChildWithMerge(HasOneToManyJDO pojo,
  526. BidirectionalChildJDO bidir, StartEnd startEnd) throws EntityNotFoundException {
  527. Flight f = newFlight();
  528. HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
  529. pojo.addFlight(f);
  530. pojo.addHasKeyPk(hasKeyPk);
  531. pojo.addBidirChild(bidir);
  532. bidir.setParent(pojo);
  533. startEnd.start();
  534. pm.makePersistent(pojo);
  535. startEnd.end();
  536. assertNotNull(f.getId());
  537. assertNotNull(hasKeyPk.getKey());
  538. assertNotNull(bidir.getId());
  539. assertNotNull(pojo.getId());
  540. startEnd.start();
  541. f.setOrigin("yam");
  542. hasKeyPk.setStr("yar");
  543. bidir.setChildVal("yap");
  544. pm.makePersistent(pojo);
  545. startEnd.end();
  546. Entity flightEntity = ds.get(KeyFactory.stringToKey(f.getId()));
  547. assertNotNull(flightEntity);
  548. assertEquals("yam", flightEntity.getProperty("origin"));
  549. assertKeyParentEquals(pojo.getId(), flightEntity, f.getId());
  550. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  551. assertEquals(0L, flightEntity.getProperty("flights_INTEGER_IDX"));
  552. }
  553. Entity hasKeyPkEntity = ds.get(hasKeyPk.getKey());
  554. assertNotNull(hasKeyPkEntity);
  555. assertEquals("yar", hasKeyPkEntity.getProperty("str"));
  556. assertKeyParentEquals(pojo.getId(), hasKeyPkEntity, hasKeyPk.getKey());
  557. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  558. assertEquals(0L, hasKeyPkEntity.getProperty("hasKeyPks_INTEGER_IDX"));
  559. }
  560. Entity bidirEntity = ds.get(KeyFactory.stringToKey(bidir.getId()));
  561. assertNotNull(bidirEntity);
  562. assertEquals("yap", bidirEntity.getProperty("childVal"));
  563. assertKeyParentEquals(pojo.getId(), bidirEntity, bidir.getId());
  564. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  565. assertEquals(0L, bidirEntity.getProperty("bidirChildren_INTEGER_IDX"));
  566. }
  567. assertCountsInDatastore(pojo.getClass(), bidir.getClass(), 1, 1);
  568. }
  569. void testUpdate_UpdateChild(HasOneToManyJDO pojo,
  570. BidirectionalChildJDO bidir, StartEnd startEnd) throws EntityNotFoundException {
  571. Flight f = newFlight();
  572. HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
  573. pojo.addFlight(f);
  574. pojo.addHasKeyPk(hasKeyPk);
  575. pojo.addBidirChild(bidir);
  576. bidir.setParent(pojo);
  577. startEnd.start();
  578. pm.makePersistent(pojo);
  579. startEnd.end();
  580. assertNotNull(f.getId());
  581. assertNotNull(hasKeyPk.getKey());
  582. assertNotNull(bidir.getId());
  583. assertNotNull(pojo.getId());
  584. startEnd.start();
  585. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  586. pojo.getFlights().iterator().next().setOrigin("yam");
  587. pojo.getHasKeyPks().iterator().next().setStr("yar");
  588. pojo.getBidirChildren().iterator().next().setChildVal("yap");
  589. startEnd.end();
  590. Entity flightEntity = ds.get(KeyFactory.stringToKey(f.getId()));
  591. assertNotNull(flightEntity);
  592. assertEquals("yam", flightEntity.getProperty("origin"));
  593. assertKeyParentEquals(pojo.getId(), flightEntity, f.getId());
  594. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  595. assertEquals(0L, flightEntity.getProperty("flights_INTEGER_IDX"));
  596. }
  597. Entity hasKeyPkEntity = ds.get(hasKeyPk.getKey());
  598. assertNotNull(hasKeyPkEntity);
  599. assertEquals("yar", hasKeyPkEntity.getProperty("str"));
  600. assertKeyParentEquals(pojo.getId(), hasKeyPkEntity, hasKeyPk.getKey());
  601. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  602. assertEquals(0L, hasKeyPkEntity.getProperty("hasKeyPks_INTEGER_IDX"));
  603. }
  604. Entity bidirEntity = ds.get(KeyFactory.stringToKey(bidir.getId()));
  605. assertNotNull(bidirEntity);
  606. assertEquals("yap", bidirEntity.getProperty("childVal"));
  607. assertKeyParentEquals(pojo.getId(), bidirEntity, bidir.getId());
  608. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  609. assertEquals(0L, bidirEntity.getProperty("bidirChildren_INTEGER_IDX"));
  610. }
  611. assertCountsInDatastore(pojo.getClass(), bidir.getClass(), 1, 1);
  612. }
  613. void testUpdate_NullOutChildren(HasOneToManyJDO pojo,
  614. BidirectionalChildJDO bidir, StartEnd startEnd) throws EntityNotFoundException {
  615. Flight f = newFlight();
  616. HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
  617. pojo.addFlight(f);
  618. pojo.addHasKeyPk(hasKeyPk);
  619. pojo.addBidirChild(bidir);
  620. bidir.setParent(pojo);
  621. startEnd.start();
  622. pm.makePersistent(pojo);
  623. startEnd.end();
  624. assertCountsInDatastore(pojo.getClass(), bidir.getClass(), 1, 1);
  625. startEnd.start();
  626. String flightId = f.getId();
  627. Key hasKeyPkKey = hasKeyPk.getKey();
  628. String bidirChildId = bidir.getId();
  629. pojo.nullFlights();
  630. pojo.nullHasKeyPks();
  631. pojo.nullBidirChildren();
  632. pm.makePersistent(pojo);
  633. startEnd.end();
  634. try {
  635. ds.get(KeyFactory.stringToKey(flightId));
  636. fail("expected enfe");
  637. } catch (EntityNotFoundException enfe) {
  638. // good
  639. }
  640. try {
  641. ds.get(hasKeyPkKey);
  642. fail("expected enfe");
  643. } catch (EntityNotFoundException enfe) {
  644. // good
  645. }
  646. try {
  647. ds.get(KeyFactory.stringToKey(bidirChildId));
  648. fail("expected enfe");
  649. } catch (EntityNotFoundException enfe) {
  650. // good
  651. }
  652. Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
  653. assertEquals(4, pojoEntity.getProperties().size());
  654. assertTrue(pojoEntity.hasProperty("bidirChildren"));
  655. assertNull(pojoEntity.getProperty("bidirChildren"));
  656. assertTrue(pojoEntity.hasProperty("flights"));
  657. assertNull(pojoEntity.getProperty("flights"));
  658. assertTrue(pojoEntity.hasProperty("hasKeyPks"));
  659. assertNull(pojoEntity.getProperty("hasKeyPks"));
  660. assertCountsInDatastore(pojo.getClass(), bidir.getClass(), 1, 0);
  661. }
  662. void testUpdate_ClearOutChildren(HasOneToManyJDO pojo,
  663. BidirectionalChildJDO bidir, StartEnd startEnd) throws EntityNotFoundException {
  664. Flight f = newFlight();
  665. HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
  666. pojo.addFlight(f);
  667. pojo.addHasKeyPk(hasKeyPk);
  668. pojo.addBidirChild(bidir);
  669. bidir.setParent(pojo);
  670. startEnd.start();
  671. pm.makePersistent(pojo);
  672. startEnd.end();
  673. String flightId = f.getId();
  674. Key hasKeyPkId = hasKeyPk.getKey();
  675. String bidirChildId = bidir.getId();
  676. assertCountsInDatastore(pojo.getClass(), bidir.getClass(), 1, 1);
  677. startEnd.start();
  678. pojo = pm.makePersistent(pojo);
  679. pojo.clearFlights();
  680. pojo.clearHasKeyPks();
  681. pojo.clearBidirChildren();
  682. startEnd.end();
  683. try {
  684. ds.get(KeyFactory.stringToKey(flightId));
  685. fail("expected enfe");
  686. } catch (EntityNotFoundException enfe) {
  687. // good
  688. }
  689. try {
  690. ds.get(hasKeyPkId);
  691. fail("expected enfe");
  692. } catch (EntityNotFoundException enfe) {
  693. // good
  694. }
  695. try {
  696. ds.get(KeyFactory.stringToKey(bidirChildId));
  697. fail("expected enfe");
  698. } catch (EntityNotFoundException enfe) {
  699. // good
  700. }
  701. Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
  702. assertEquals(4, pojoEntity.getProperties().size());
  703. assertTrue(pojoEntity.hasProperty("bidirChildren"));
  704. assertNull(pojoEntity.getProperty("bidirChildren"));
  705. assertTrue(pojoEntity.hasProperty("flights"));
  706. assertNull(pojoEntity.getProperty("flights"));
  707. assertTrue(pojoEntity.hasProperty("hasKeyPks"));
  708. assertNull(pojoEntity.getProperty("hasKeyPks"));
  709. assertCountsInDatastore(pojo.getClass(), bidir.getClass(), 1, 0);
  710. }
  711. void testFindWithOrderBy(Class<? extends HasOneToManyWithOrderByJDO> pojoClass, StartEnd startEnd)
  712. throws EntityNotFoundException {
  713. getExecutionContext().getNucleusContext().getPersistenceConfiguration().setProperty(
  714. "datanucleus.appengine.allowMultipleRelationsOfSameType", true);
  715. Entity pojoEntity = new Entity(pojoClass.getSimpleName());
  716. ds.put(pojoEntity);
  717. Entity flightEntity1 = newFlightEntity(pojoEntity.getKey(), "bos1", "mia2", "name 1");
  718. flightEntity1.setProperty("flightsByOrigAndDest_INTEGER_IDX", 0);
  719. flightEntity1.setProperty("flightsByIdAndOrig_INTEGER_IDX", 0);
  720. flightEntity1.setProperty("flightsByOrigAndId_INTEGER_IDX", 0);
  721. ds.put(flightEntity1);
  722. Entity flightEntity2 = newFlightEntity(pojoEntity.getKey(), "bos2", "mia2", "name 2");
  723. flightEntity2.setProperty("flightsByOrigAndDest_INTEGER_IDX", 1);
  724. flightEntity2.setProperty("flightsByIdAndOrig_INTEGER_IDX", 1);
  725. flightEntity2.setProperty("flightsByOrigAndId_INTEGER_IDX", 1);
  726. ds.put(flightEntity2);
  727. Entity flightEntity3 = newFlightEntity(pojoEntity.getKey(), "bos1", "mia1", "name 0");
  728. flightEntity3.setProperty("flightsByOrigAndDest_INTEGER_IDX", 2);
  729. flightEntity3.setProperty("flightsByIdAndOrig_INTEGER_IDX", 2);
  730. flightEntity3.setProperty("flightsByOrigAndId_INTEGER_IDX", 2);
  731. ds.put(flightEntity3);
  732. Entity explicitIndexEntity1 =
  733. new Entity(HasExplicitIndexColumnJDO.class.getSimpleName(), pojoEntity.getKey());
  734. explicitIndexEntity1.setProperty("index", 3);
  735. ds.put(explicitIndexEntity1);
  736. Entity explicitIndexEntity2 =
  737. new Entity(HasExplicitIndexColumnJDO.class.getSimpleName(), pojoEntity.getKey());
  738. explicitIndexEntity2.setProperty("index", 2);
  739. ds.put(explicitIndexEntity2);
  740. Entity explicitIndexEntity3 =
  741. new Entity(HasExplicitIndexColumnJDO.class.getSimpleName(), pojoEntity.getKey());
  742. explicitIndexEntity3.setProperty("index", 1);
  743. ds.put(explicitIndexEntity3);
  744. pojoEntity.setProperty("flightsByOrigAndDest", Utils.newArrayList(flightEntity2.getKey(), flightEntity3.getKey(), flightEntity1.getKey()));
  745. pojoEntity.setProperty("flightsByIdAndOrig", Utils.newArrayList(flightEntity3.getKey(), flightEntity2.getKey(), flightEntity1.getKey()));
  746. pojoEntity.setProperty("flightsByOrigAndId", Utils.newArrayList(flightEntity2.getKey(), flightEntity1.getKey(), flightEntity3.getKey()));
  747. pojoEntity.setProperty("hasIndexColumn", Utils.newArrayList(explicitIndexEntity3.getKey(), explicitIndexEntity2.getKey(), explicitIndexEntity1.getKey()));
  748. ds.put(pojoEntity);
  749. startEnd.start();
  750. HasOneToManyWithOrderByJDO pojo = pm.getObjectById(
  751. pojoClass, KeyFactory.keyToString(pojoEntity.getKey()));
  752. assertNotNull(pojo);
  753. assertNotNull(pojo.getFlightsByOrigAndDest());
  754. assertEquals(3, pojo.getFlightsByOrigAndDest().size());
  755. assertEquals("name 2", pojo.getFlightsByOrigAndDest().get(0).getName());
  756. assertEquals("name 0", pojo.getFlightsByOrigAndDest().get(1).getName());
  757. assertEquals("name 1", pojo.getFlightsByOrigAndDest().get(2).getName());
  758. assertNotNull(pojo.getFlightsByIdAndOrig());
  759. assertEquals(3, pojo.getFlightsByIdAndOrig().size());
  760. assertEquals("name 0", pojo.getFlightsByIdAndOrig().get(0).getName());
  761. assertEquals("name 2", pojo.getFlightsByIdAndOrig().get(1).getName());
  762. assertEquals("name 1", pojo.getFlightsByIdAndOrig().get(2).getName());
  763. assertNotNull(pojo.getFlightsByOrigAndId());
  764. assertEquals(3, pojo.getFlightsByOrigAndId().size());
  765. assertEquals("name 2", pojo.getFlightsByOrigAndId().get(0).getName());
  766. assertEquals("name 1", pojo.getFlightsByOrigAndId().get(1).getName());
  767. assertEquals("name 0", pojo.getFlightsByOrigAndId().get(2).getName());
  768. assertNotNull(pojo.getHasIndexColumn());
  769. assertEquals(3, pojo.getHasIndexColumn().size());
  770. assertEquals(explicitIndexEntity3.getKey(), pojo.getHasIndexColumn().get(0).getId());
  771. assertEquals(explicitIndexEntity2.getKey(), pojo.getHasIndexColumn().get(1).getId());
  772. assertEquals(explicitIndexEntity1.getKey(), pojo.getHasIndexColumn().get(2).getId());
  773. startEnd.end();
  774. }
  775. void testFind(Class<? extends HasOneToManyJDO> pojoClass,
  776. Class<? extends BidirectionalChildJDO> bidirClass, StartEnd startEnd) throws EntityNotFoundException {
  777. Entity pojoEntity = new Entity(pojoClass.getSimpleName());
  778. ds.put(pojoEntity);
  779. Entity flightEntity = newFlightEntity(pojoEntity.getKey(), "bos1", "mia2", "name 1");
  780. ds.put(flightEntity);
  781. Entity hasKeyPkEntity = new Entity(HasKeyPkJDO.class.getSimpleName(), pojoEntity.getKey());
  782. hasKeyPkEntity.setProperty("str", "yar");
  783. hasKeyPkEntity.setProperty("hasKeyPks_INTEGER_IDX", 1);
  784. ds.put(hasKeyPkEntity);
  785. Entity bidirEntity = new Entity(bidirClass.getSimpleName(), pojoEntity.getKey());
  786. bidirEntity.setProperty("childVal", "yap");
  787. bidirEntity.setProperty("bidirChildren_INTEGER_IDX", 1);
  788. ds.put(bidirEntity);
  789. pojoEntity.setProperty("bidirChildren", Utils.newArrayList(bidirEntity.getKey()));
  790. pojoEntity.setProperty("hasKeyPks", Utils.newArrayList(hasKeyPkEntity.getKey()));
  791. pojoEntity.setProperty("flights", Utils.newArrayList(flightEntity.getKey()));
  792. ds.put(pojoEntity);
  793. startEnd.start();
  794. HasOneToManyJDO pojo =
  795. pm.getObjectById(pojoClass, KeyFactory.keyToString(pojoEntity.getKey()));
  796. assertNotNull(pojo);
  797. assertNotNull(pojo.getFlights());
  798. assertEquals(1, pojo.getFlights().size());
  799. assertEquals("bos1", pojo.getFlights().iterator().next().getOrigin());
  800. assertNotNull(pojo.getHasKeyPks());
  801. assertEquals(1, pojo.getHasKeyPks().size());
  802. assertEquals("yar", pojo.getHasKeyPks().iterator().next().getStr());
  803. assertNotNull(pojo.getBidirChildren());
  804. assertEquals(1, pojo.getBidirChildren().size());
  805. assertEquals("yap", pojo.getBidirChildren().iterator().next().getChildVal());
  806. assertEquals(pojo, pojo.getBidirChildren().iterator().next().getParent());
  807. startEnd.end();
  808. }
  809. void testQuery(Class<? extends HasOneToManyJDO> pojoClass,
  810. Class<? extends BidirectionalChildJDO> bidirClass, StartEnd startEnd) throws EntityNotFoundException {
  811. Entity pojoEntity = new Entity(pojoClass.getSimpleName());
  812. ds.put(pojoEntity);
  813. Entity flightEntity = newFlightEntity(pojoEntity.getKey(), "bos", "mia2", "name");
  814. ds.put(flightEntity);
  815. Entity hasKeyPkEntity = new Entity(HasKeyPkJDO.class.getSimpleName(), pojoEntity.getKey());
  816. hasKeyPkEntity.setProperty("str", "yar");
  817. hasKeyPkEntity.setProperty("hasKeyPks_INTEGER_IDX", 1);
  818. ds.put(hasKeyPkEntity);
  819. Entity bidirEntity = new Entity(bidirClass.getSimpleName(), pojoEntity.getKey());
  820. bidirEntity.setProperty("childVal", "yap");
  821. bidirEntity.setProperty("bidirChildren_INTEGER_IDX", 1);
  822. ds.put(bidirEntity);
  823. pojoEntity.setProperty("bidirChildren", Utils.newArrayList(bidirEntity.getKey()));
  824. pojoEntity.setProperty("hasKeyPks", Utils.newArrayList(hasKeyPkEntity.getKey()));
  825. pojoEntity.setProperty("flights", Utils.newArrayList(flightEntity.getKey()));
  826. ds.put(pojoEntity);
  827. javax.jdo.Query q = pm.newQuery(
  828. "select from " + pojoClass.getName() + " where id == key parameters String key");
  829. startEnd.start();
  830. @SuppressWarnings("unchecked")
  831. List<HasOneToManyListJDO> result =
  832. (List<HasOneToManyListJDO>) q.execute(KeyFactory.keyToString(pojoEntity.getKey()));
  833. assertEquals(1, result.size());
  834. HasOneToManyJDO pojo = result.get(0);
  835. assertNotNull(pojo.getFlights());
  836. assertEquals(1, pojo.getFlights().size());
  837. assertEquals("bos", pojo.getFlights().iterator().next().getOrigin());
  838. assertEquals(1, pojo.getFlights().size());
  839. assertNotNull(pojo.getHasKeyPks());
  840. assertEquals(1, pojo.getHasKeyPks().size());
  841. assertEquals("yar", pojo.getHasKeyPks().iterator().next().getStr());
  842. assertNotNull(pojo.getBidirChildren());
  843. assertEquals(1, pojo.getBidirChildren().size());
  844. assertEquals("yap", pojo.getBidirChildren().iterator().next().getChildVal());
  845. assertEquals(pojo, pojo.getBidirChildren().iterator().next().getParent());
  846. startEnd.end();
  847. }
  848. void testChildFetchedLazily(Class<? extends HasOneToManyJDO> pojoClass,
  849. Class<? extends BidirectionalChildJDO> bidirClass) throws Exception {
  850. DatastoreServiceConfig config = getStoreManager().getDefaultDatastoreServiceConfigForReads();
  851. tearDown();
  852. DatastoreService mockDatastore = EasyMock.createMock(DatastoreService.class);
  853. DatastoreService original = DatastoreServiceFactoryInternal.getDatastoreService(config);
  854. DatastoreServiceFactoryInternal.setDatastoreService(mockDatastore);
  855. try {
  856. setUp();
  857. Entity pojoEntity = new Entity(pojoClass.getSimpleName());
  858. ds.put(pojoEntity);
  859. Entity FlightEntity = newFlightEntity(pojoEntity.getKey(), "bos", "mia", "name");
  860. ds.put(FlightEntity);
  861. Entity hasKeyPkEntity = new Entity(HasKeyPkJDO.class.getSimpleName(), pojoEntity.getKey());
  862. hasKeyPkEntity.setProperty("str", "yar");
  863. ds.put(hasKeyPkEntity);
  864. Entity bidirEntity = new Entity(bidirClass.getSimpleName(), pojoEntity.getKey());
  865. bidirEntity.setProperty("childVal", "yap");
  866. ds.put(bidirEntity);
  867. Transaction txn = EasyMock.createMock(Transaction.class);
  868. EasyMock.expect(txn.getId()).andReturn("1").times(2);
  869. txn.commit();
  870. EasyMock.expectLastCall();
  871. EasyMock.replay(txn);
  872. EasyMock.expect(mockDatastore.beginTransaction(EasyMock.isA(TransactionOptions.class))).andReturn(txn);
  873. // the only get we're going to perform is for the pojo
  874. EasyMock.expect(mockDatastore.get(txn, pojoEntity.getKey())).andReturn(pojoEntity);
  875. EasyMock.replay(mockDatastore);
  876. beginTxn();
  877. HasOneToManyJDO pojo =
  878. pm.getObjectById(pojoClass, KeyFactory.keyToString(pojoEntity.getKey()));
  879. assertNotNull(pojo);
  880. pojo.getId();
  881. commitTxn();
  882. } finally {
  883. DatastoreServiceFactoryInternal.setDatastoreService(original);
  884. }
  885. EasyMock.verify(mockDatastore);
  886. }
  887. void testDeleteParentDeletesChild(Class<? extends HasOneToManyJDO> pojoClass,
  888. Class<? extends BidirectionalChildJDO> bidirClass, StartEnd startEnd) throws Exception {
  889. Entity pojoEntity = new Entity(pojoClass.getSimpleName());
  890. ds.put(pojoEntity);
  891. Entity flightEntity = newFlightEntity(pojoEntity.getKey(), "bos", "mia", "name");
  892. flightEntity.setProperty("flights_INTEGER_IDX", 1);
  893. ds.put(flightEntity);
  894. Entity hasKeyPkEntity = new Entity(HasKeyPkJDO.class.getSimpleName(), pojoEntity.getKey());
  895. hasKeyPkEntity.setProperty("str", "yar");
  896. hasKeyPkEntity.setProperty("hasKeyPks_INTEGER_IDX", 1);
  897. ds.put(hasKeyPkEntity);
  898. Entity bidirEntity = new Entity(bidirClass.getSimpleName(), pojoEntity.getKey());
  899. bidirEntity.setProperty("childVal", "yap");
  900. bidirEntity.setProperty("bidirChildren_INTEGER_IDX", 1);
  901. ds.put(bidirEntity);
  902. pojoEntity.setProperty("bidirChildren", Utils.newArrayList(bidirEntity.getKey()));
  903. pojoEntity.setProperty("hasKeyPks", Utils.newArrayList(hasKeyPkEntity.getKey()));
  904. pojoEntity.setProperty("flights", Utils.newArrayList(flightEntity.getKey()));
  905. ds.put(pojoEntity);
  906. startEnd.start();
  907. HasOneToManyJDO pojo = pm.getObjectById(pojoClass, KeyFactory.keyToString(pojoEntity.getKey()));
  908. pm.deletePersistent(pojo);
  909. startEnd.end();
  910. assertCountsInDatastore(pojoClass, bidirClass, 0, 0);
  911. }
  912. void testRemoveAll(HasOneToManyJDO pojo, BidirectionalChildJDO bidir1,
  913. BidirectionalChildJDO bidir2, BidirectionalChildJDO bidir3, StartEnd startEnd)
  914. throws EntityNotFoundException {
  915. Flight f1 = new Flight();
  916. Flight f2 = new Flight();
  917. Flight f3 = new Flight();
  918. pojo.addFlight(f1);
  919. pojo.addFlight(f2);
  920. pojo.addFlight(f3);
  921. pojo.addBidirChild(bidir1);
  922. pojo.addBidirChild(bidir2);
  923. pojo.addBidirChild(bidir3);
  924. startEnd.start();
  925. pm.makePersistent(pojo);
  926. startEnd.end();
  927. startEnd.start();
  928. pojo = pm.makePersistent(pojo);
  929. String f2Id = f2.getId();
  930. String bidir2Id = bidir2.getId();
  931. pojo.removeFlights(Collections.singleton(f2));
  932. pojo.removeBidirChildren(Collections.singleton(bidir2));
  933. startEnd.end();
  934. startEnd.start();
  935. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  936. assertEquals(2, pojo.getFlights().size());
  937. Set<String> flightIds = Utils.newHashSet(f1.getId(), f2.getId(), f3.getId());
  938. for (Flight f : pojo.getFlights()) {
  939. flightIds.remove(f.getId());
  940. }
  941. assertEquals(1, flightIds.size());
  942. assertEquals(f2.getId(), flightIds.iterator().next());
  943. assertEquals(2, pojo.getBidirChildren().size());
  944. Set<String> bidirIds = Utils.newHashSet(bidir1.getId(), bidir2.getId(), bidir3.getId());
  945. for (BidirectionalChildJDO b : pojo.getBidirChildren()) {
  946. bidirIds.remove(b.getId());
  947. }
  948. assertEquals(1, bidirIds.size());
  949. assertEquals(bidir2.getId(), bidirIds.iterator().next());
  950. startEnd.end();
  951. Entity flightEntity1 = ds.get(KeyFactory.stringToKey(f1.getId()));
  952. Entity flightEntity3 = ds.get(KeyFactory.stringToKey(f3.getId()));
  953. Entity bidirEntity1 = ds.get(KeyFactory.stringToKey(bidir1.getId()));
  954. Entity bidirEntity3 = ds.get(KeyFactory.stringToKey(bidir3.getId()));
  955. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  956. assertEquals(0L, flightEntity1.getProperty("flights_INTEGER_IDX"));
  957. assertEquals(1L, flightEntity3.getProperty("flights_INTEGER_IDX"));
  958. assertEquals(0L, bidirEntity1.getProperty("bidirChildren_INTEGER_IDX"));
  959. assertEquals(1L, bidirEntity3.getProperty("bidirChildren_INTEGER_IDX"));
  960. }
  961. try {
  962. ds.get(KeyFactory.stringToKey(f2Id));
  963. fail("expected enfe");
  964. } catch (EntityNotFoundException enfe) {
  965. // good
  966. }
  967. try {
  968. ds.get(KeyFactory.stringToKey(bidir2Id));
  969. fail("expected enfe");
  970. } catch (EntityNotFoundException enfe) {
  971. // good
  972. }
  973. }
  974. void testRemoveAll_LongPkOnParent(HasOneToManyLongPkJDO pojo, BidirectionalChildLongPkJDO bidir1,
  975. BidirectionalChildLongPkJDO bidir2, BidirectionalChildLongPkJDO bidir3, StartEnd startEnd)
  976. throws EntityNotFoundException {
  977. Flight f1 = new Flight();
  978. Flight f2 = new Flight();
  979. Flight f3 = new Flight();
  980. pojo.addFlight(f1);
  981. pojo.addFlight(f2);
  982. pojo.addFlight(f3);
  983. pojo.addBidirChild(bidir1);
  984. pojo.addBidirChild(bidir2);
  985. pojo.addBidirChild(bidir3);
  986. startEnd.start();
  987. pm.makePersistent(pojo);
  988. startEnd.end();
  989. startEnd.start();
  990. pojo = pm.makePersistent(pojo);
  991. String f2Id = f2.getId();
  992. String bidir2Id = bidir2.getId();
  993. pojo.removeFlights(Collections.singleton(f2));
  994. pojo.removeBidirChildren(Collections.singleton(bidir2));
  995. startEnd.end();
  996. startEnd.start();
  997. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  998. assertEquals(2, pojo.getFlights().size());
  999. Set<String> flightIds = Utils.newHashSet(f1.getId(), f2.getId(), f3.getId());
  1000. for (Flight f : pojo.getFlights()) {
  1001. flightIds.remove(f.getId());
  1002. }
  1003. assertEquals(1, flightIds.size());
  1004. assertEquals(f2.getId(), flightIds.iterator().next());
  1005. assertEquals(2, pojo.getBidirChildren().size());
  1006. Set<String> bidirIds = Utils.newHashSet(bidir1.getId(), bidir2.getId(), bidir3.getId());
  1007. for (BidirectionalChildLongPkJDO b : pojo.getBidirChildren()) {
  1008. bidirIds.remove(b.getId());
  1009. }
  1010. assertEquals(1, bidirIds.size());
  1011. assertEquals(bidir2.getId(), bidirIds.iterator().next());
  1012. startEnd.end();
  1013. Entity flightEntity1 = ds.get(KeyFactory.stringToKey(f1.getId()));
  1014. Entity flightEntity3 = ds.get(KeyFactory.stringToKey(f3.getId()));
  1015. Entity bidirEntity1 = ds.get(KeyFactory.stringToKey(bidir1.getId()));
  1016. Entity bidirEntity3 = ds.get(KeyFactory.stringToKey(bidir3.getId()));
  1017. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  1018. assertEquals(0L, flightEntity1.getProperty("flights_INTEGER_IDX_longpk"));
  1019. assertEquals(1L, flightEntity3.getProperty("flights_INTEGER_IDX_longpk"));
  1020. assertEquals(0L, bidirEntity1.getProperty("bidirChildren_INTEGER_IDX"));
  1021. assertEquals(1L, bidirEntity3.getProperty("bidirChildren_INTEGER_IDX"));
  1022. }
  1023. try {
  1024. ds.get(KeyFactory.stringToKey(f2Id));
  1025. fail("expected enfe");
  1026. } catch (EntityNotFoundException enfe) {
  1027. // good
  1028. }
  1029. try {
  1030. ds.get(KeyFactory.stringToKey(bidir2Id));
  1031. fail("expected enfe");
  1032. } catch (EntityNotFoundException enfe) {
  1033. // good
  1034. }
  1035. }
  1036. void testRemoveAll_UnencodedStringPkOnParent(HasOneToManyUnencodedStringPkJDO pojo, BidirectionalChildUnencodedStringPkJDO bidir1,
  1037. BidirectionalChildUnencodedStringPkJDO bidir2,
  1038. BidirectionalChildUnencodedStringPkJDO bidir3, StartEnd startEnd)
  1039. throws EntityNotFoundException {
  1040. Flight f1 = new Flight();
  1041. Flight f2 = new Flight();
  1042. Flight f3 = new Flight();
  1043. pojo.addFlight(f1);
  1044. pojo.addFlight(f2);
  1045. pojo.addFlight(f3);
  1046. pojo.addBidirChild(bidir1);
  1047. pojo.addBidirChild(bidir2);
  1048. pojo.addBidirChild(bidir3);
  1049. startEnd.start();
  1050. pm.makePersistent(pojo);
  1051. startEnd.end();
  1052. startEnd.start();
  1053. pojo = pm.makePersistent(pojo);
  1054. String f2Id = f2.getId();
  1055. String bidir2Id = bidir2.getId();
  1056. pojo.removeFlights(Collections.singleton(f2));
  1057. pojo.removeBidirChildren(Collections.singleton(bidir2));
  1058. startEnd.end();
  1059. startEnd.start();
  1060. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  1061. assertEquals(2, pojo.getFlights().size());
  1062. Set<String> flightIds = Utils.newHashSet(f1.getId(), f2.getId(), f3.getId());
  1063. for (Flight f : pojo.getFlights()) {
  1064. flightIds.remove(f.getId());
  1065. }
  1066. assertEquals(1, flightIds.size());
  1067. assertEquals(f2.getId(), flightIds.iterator().next());
  1068. assertEquals(2, pojo.getBidirChildren().size());
  1069. Set<String> bidirIds = Utils.newHashSet(bidir1.getId(), bidir2.getId(), bidir3.getId());
  1070. for (BidirectionalChildUnencodedStringPkJDO b : pojo.getBidirChildren()) {
  1071. bidirIds.remove(b.getId());
  1072. }
  1073. assertEquals(1, bidirIds.size());
  1074. assertEquals(bidir2.getId(), bidirIds.iterator().next());
  1075. startEnd.end();
  1076. Entity flightEntity1 = ds.get(KeyFactory.stringToKey(f1.getId()));
  1077. Entity flightEntity3 = ds.get(KeyFactory.stringToKey(f3.getId()));
  1078. Entity bidirEntity1 = ds.get(KeyFactory.stringToKey(bidir1.getId()));
  1079. Entity bidirEntity3 = ds.get(KeyFactory.stringToKey(bidir3.getId()));
  1080. if (isIndexed() && getStorageVersion(pm) == StorageVersion.PARENTS_DO_NOT_REFER_TO_CHILDREN) {
  1081. assertEquals(0L, flightEntity1.getProperty("flights_INTEGER_IDX_unencodedstringpk"));
  1082. assertEquals(1L, flightEntity3.getProperty("flights_INTEGER_IDX_unencodedstringpk"));
  1083. assertEquals(0L, bidirEntity1.getProperty("bidirChildren_INTEGER_IDX"));
  1084. assertEquals(1L, bidirEntity3.getProperty("bidirChildren_INTEGER_IDX"));
  1085. }
  1086. try {
  1087. ds.get(KeyFactory.stringToKey(f2Id));
  1088. fail("expected enfe");
  1089. } catch (EntityNotFoundException enfe) {
  1090. // good
  1091. }
  1092. try {
  1093. ds.get(KeyFactory.stringToKey(bidir2Id));
  1094. fail("expected enfe");
  1095. } catch (EntityNotFoundException enfe) {
  1096. // good
  1097. }
  1098. }
  1099. void testChangeParent(HasOneToManyJDO pojo, HasOneToManyJDO pojo2, StartEnd startEnd) {
  1100. switchDatasource(PersistenceManagerFactoryName.nontransactional);
  1101. Flight f1 = new Flight();
  1102. pojo.addFlight(f1);
  1103. startEnd.start();
  1104. pm.makePersistent(pojo);
  1105. startEnd.end();
  1106. startEnd.start();
  1107. pojo2.addFlight(f1);
  1108. try {
  1109. pm.makePersistent(pojo2);
  1110. fail("expected exception");
  1111. } catch (JDOFatalUserException e) {
  1112. if (pm.currentTransaction().isActive()) {
  1113. rollbackTxn();
  1114. }
  1115. }
  1116. }
  1117. void testNewParentNewChild_NamedKeyOnChild(HasOneToManyJDO pojo, StartEnd startEnd) throws EntityNotFoundException {
  1118. Flight f1 = new Flight();
  1119. pojo.addFlight(f1);
  1120. f1.setId(KeyFactory.keyToString(
  1121. KeyFactory.createKey(Flight.class.getSimpleName(), "named key")));
  1122. startEnd.start();
  1123. pm.makePersistent(pojo);
  1124. startEnd.end();
  1125. Entity flightEntity = ds.get(KeyFactory.stringToKey(f1.getId()));
  1126. assertEquals("named key", flightEntity.getKey().getName());
  1127. }
  1128. void testAddAlreadyPersistedChildToParent_NoTxnDifferentPm(HasOneToManyJDO pojo) {
  1129. switchDatasource(PersistenceManagerFactoryName.nontransactional);
  1130. Flight f1 = new Flight();
  1131. pm.makePersistent(f1);
  1132. f1 = pm.detachCopy(f1);
  1133. pm.close();
  1134. pm = pmf.getPersistenceManager();
  1135. f1 = pm.makePersistent(f1);
  1136. pojo.addFlight(f1);
  1137. try {
  1138. pm.makePersistent(pojo);
  1139. fail("expected exception");
  1140. } catch (JDOFatalUserException e) {
  1141. // good
  1142. }
  1143. pm.close();
  1144. assertEquals(0, countForClass(pojo.getClass()));
  1145. assertEquals(1, countForClass(Flight.class));
  1146. }
  1147. void testAddAlreadyPersistedChildToParent_NoTxnSamePm(HasOneToManyJDO pojo) {
  1148. switchDatasource(PersistenceManagerFactoryName.nontransactional);
  1149. Flight f1 = new Flight();
  1150. pm.makePersistent(f1);
  1151. pojo.addFlight(f1);
  1152. try {
  1153. pm.makePersistent(pojo);
  1154. fail("expected exception");
  1155. } catch (JDOFatalUserException e) {
  1156. // good
  1157. }
  1158. pm.close();
  1159. assertEquals(0, countForClass(pojo.getClass()));
  1160. assertEquals(1, countForClass(Flight.class));
  1161. }
  1162. void testFetchOfOneToManyParentWithKeyPk(HasOneToManyKeyPkJDO pojo, StartEnd startEnd) {
  1163. startEnd.start();
  1164. pm.makePersistent(pojo);
  1165. startEnd.end();
  1166. startEnd.start();
  1167. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  1168. assertEquals(0, pojo.getFlights().size());
  1169. startEnd.end();
  1170. }
  1171. void testFetchOfOneToManyParentWithLongPk(HasOneToManyLongPkJDO pojo, StartEnd startEnd) {
  1172. startEnd.start();
  1173. pm.makePersistent(pojo);
  1174. startEnd.end();
  1175. startEnd.start();
  1176. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  1177. assertEquals(0, pojo.getFlights().size());
  1178. startEnd.end();
  1179. }
  1180. void testFetchOfOneToManyParentWithUnencodedStringPk(HasOneToManyUnencodedStringPkJDO pojo, StartEnd startEnd) {
  1181. pojo.setId("yar");
  1182. startEnd.start();
  1183. pm.makePersistent(pojo);
  1184. startEnd.end();
  1185. startEnd.start();
  1186. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  1187. assertEquals(0, pojo.getFlights().size());
  1188. startEnd.end();
  1189. }
  1190. void testAddChildToOneToManyParentWithLongPk(
  1191. HasOneToManyLongPkJDO pojo, BidirectionalChildLongPkJDO bidirChild, StartEnd startEnd)
  1192. throws EntityNotFoundException {
  1193. startEnd.start();
  1194. pm.makePersistent(pojo);
  1195. startEnd.end();
  1196. startEnd.start();
  1197. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  1198. Flight f = new Flight();
  1199. pojo.addFlight(f);
  1200. pojo.addBidirChild(bidirChild);
  1201. startEnd.end();
  1202. Entity flightEntity = ds.get(KeyFactory.stringToKey(f.getId()));
  1203. Entity bidirEntity = ds.get(KeyFactory.stringToKey(bidirChild.getId()));
  1204. Entity pojoEntity = ds.get(KeyFactory.createKey(pojo.getClass().getSimpleName(), pojo.getId()));
  1205. assertEquals(pojoEntity.getKey(), flightEntity.getParent());
  1206. assertEquals(pojoEntity.getKey(), bidirEntity.getParent());
  1207. }
  1208. void testAddChildToOneToManyParentWithUnencodedStringPk(
  1209. HasOneToManyUnencodedStringPkJDO pojo, BidirectionalChildUnencodedStringPkJDO bidirChild,
  1210. StartEnd startEnd)
  1211. throws EntityNotFoundException {
  1212. pojo.setId("yar");
  1213. startEnd.start();
  1214. pm.makePersistent(pojo);
  1215. startEnd.end();
  1216. startEnd.start();
  1217. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  1218. Flight f = new Flight();
  1219. pojo.addFlight(f);
  1220. pojo.addBidirChild(bidirChild);
  1221. startEnd.end();
  1222. Entity flightEntity = ds.get(KeyFactory.stringToKey(f.getId()));
  1223. Entity bidirEntity = ds.get(KeyFactory.stringToKey(bidirChild.getId()));
  1224. Entity pojoEntity = ds.get(KeyFactory.createKey(pojo.getClass().getSimpleName(), pojo.getId()));
  1225. assertEquals(pojoEntity.getKey(), flightEntity.getParent());
  1226. assertEquals(pojoEntity.getKey(), bidirEntity.getParent());
  1227. }
  1228. void testAddQueriedParentToBidirChild(HasOneToManyJDO pojo, BidirectionalChildJDO bidir, StartEnd startEnd)
  1229. throws EntityNotFoundException {
  1230. startEnd.start();
  1231. pm.makePersistent(pojo);
  1232. startEnd.end();
  1233. startEnd.start();
  1234. pojo = (HasOneToManyJDO) ((List<?>)pm.newQuery(pojo.getClass()).execute()).get(0);
  1235. bidir.setParent(pojo);
  1236. pojo.addBidirChild(bidir);
  1237. pm.makePersistent(bidir);
  1238. startEnd.end();
  1239. assertEquals(1, countForClass(bidir.getClass()));
  1240. Entity e = ds.prepare(new Query(bidir.getClass().getSimpleName())).asSingleEntity();
  1241. assertNotNull(e.getParent());
  1242. startEnd.start();
  1243. pojo = (HasOneToManyJDO) ((List<?>)pm.newQuery(pojo.getClass()).execute()).get(0);
  1244. assertEquals(1, pojo.getBidirChildren().size());
  1245. startEnd.end();
  1246. Entity bidirEntity = ds.get(KeyFactory.stringToKey(bidir.getId()));
  1247. Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
  1248. assertEquals(pojoEntity.getKey(), bidirEntity.getParent());
  1249. }
  1250. void testAddFetchedParentToBidirChild(HasOneToManyJDO pojo, BidirectionalChildJDO bidir, StartEnd startEnd)
  1251. throws EntityNotFoundException {
  1252. startEnd.start();
  1253. pm.makePersistent(pojo);
  1254. startEnd.end();
  1255. startEnd.start();
  1256. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  1257. bidir.setParent(pojo);
  1258. pojo.addBidirChild(bidir);
  1259. pm.makePersistent(bidir);
  1260. startEnd.end();
  1261. assertEquals(1, countForClass(bidir.getClass()));
  1262. Entity e = ds.prepare(new Query(bidir.getClass().getSimpleName())).asSingleEntity();
  1263. assertNotNull(e.getParent());
  1264. startEnd.start();
  1265. pojo = (HasOneToManyJDO) ((List<?>)pm.newQuery(pojo.getClass()).execute()).get(0);
  1266. assertEquals(1, pojo.getBidirChildren().size());
  1267. startEnd.end();
  1268. Entity bidirEntity = ds.get(KeyFactory.stringToKey(bidir.getId()));
  1269. Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
  1270. assertEquals(pojoEntity.getKey(), bidirEntity.getParent());
  1271. }
  1272. void testReplaceBidirColl(HasOneToManyJDO parent,
  1273. BidirectionalChildJDO bidir1,
  1274. Collection<BidirectionalChildJDO> newColl, StartEnd startEnd) {
  1275. bidir1.setParent(parent);
  1276. parent.addBidirChild(bidir1);
  1277. startEnd.start();
  1278. pm.makePersistent(parent);
  1279. startEnd.end();
  1280. String childKey = bidir1.getId();
  1281. startEnd.start();
  1282. parent = pm.getObjectById(parent.getClass(), KeyFactory.stringToKey(parent.getId()));
  1283. parent.setBidirChildren(newColl);
  1284. startEnd.end();
  1285. startEnd.start();
  1286. parent = pm.getObjectById(parent.getClass(), KeyFactory.stringToKey(parent.getId()));
  1287. assertEquals(2, parent.getBidirChildren().size());
  1288. Iterator<BidirectionalChildJDO> childIter = parent.getBidirChildren().iterator();
  1289. assertFalse(childKey.equals(childIter.next().getId()));
  1290. assertFalse(childKey.equals(childIter.next().getId()));
  1291. startEnd.end();
  1292. assertEquals(2, countForClass(newColl.iterator().next().getClass()));
  1293. }
  1294. private static final class PutPolicy implements DatastoreServiceInterceptor.Policy {
  1295. private final List<Object[]> putParamList = Utils.newArrayList();
  1296. public void intercept(Object o, Method method, Object[] params) {
  1297. if (method.getName().equals("put")) {
  1298. putParamList.add(params);
  1299. }
  1300. }
  1301. }
  1302. PutPolicy setupPutPolicy(HasOneToManyJDO pojo, BidirectionalChildJDO bidir, StartEnd startEnd)
  1303. throws Throwable {
  1304. PutPolicy policy = new PutPolicy();
  1305. DatastoreServiceInterceptor.install(getStoreManager(), policy);
  1306. try {
  1307. pmf.close();
  1308. switchDatasource(startEnd.getPmfName());
  1309. Flight flight = new Flight();
  1310. pojo.addFlight(flight);
  1311. pojo.addBidirChild(bidir);
  1312. HasKeyPkJDO hasKeyPk = new HasKeyPkJDO();
  1313. pojo.addHasKeyPk(hasKeyPk);
  1314. startEnd.start();
  1315. pm.makePersistent(pojo);
  1316. startEnd.end();
  1317. // 1 put for the parent, 3 puts for the children, 1 more put
  1318. // to add the child keys back on the parent
  1319. assertEquals(5, policy.putParamList.size());
  1320. policy.putParamList.clear();
  1321. return policy;
  1322. } catch (Throwable t) {
  1323. DatastoreServiceInterceptor.uninstall();
  1324. throw t;
  1325. }
  1326. }
  1327. void testOnlyOnePutOnChildUpdate(HasOneToManyJDO pojo, BidirectionalChildJDO bidir, StartEnd startEnd)
  1328. throws Throwable {
  1329. PutPolicy policy = setupPutPolicy(pojo, bidir, startEnd);
  1330. try {
  1331. startEnd.start();
  1332. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  1333. pojo.getFlights().iterator().next().setMe(88);
  1334. pojo.getBidirChildren().iterator().next().setChildVal("blarg");
  1335. pojo.getHasKeyPks().iterator().next().setStr("double blarg");
  1336. startEnd.end();
  1337. } finally {
  1338. DatastoreServiceInterceptor.uninstall();
  1339. }
  1340. // 1 put for each child update
  1341. assertEquals(3, policy.putParamList.size());
  1342. }
  1343. void testOnlyOneParentPutOnParentAndChildUpdate(HasOneToManyJDO pojo, BidirectionalChildJDO bidir, StartEnd startEnd)
  1344. throws Throwable {
  1345. PutPolicy policy = setupPutPolicy(pojo, bidir, startEnd);
  1346. try {
  1347. startEnd.start();
  1348. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  1349. pojo.setVal("another val");
  1350. pojo.getFlights().iterator().next().setMe(88);
  1351. pojo.getBidirChildren().iterator().next().setChildVal("blarg");
  1352. pojo.getHasKeyPks().iterator().next().setStr("double blarg");
  1353. startEnd.end();
  1354. } finally {
  1355. DatastoreServiceInterceptor.uninstall();
  1356. }
  1357. // 1 put for the parent update, 1 put for each child update
  1358. assertEquals(4, policy.putParamList.size());
  1359. }
  1360. void testOnlyOneParentPutOnChildDelete(HasOneToManyJDO pojo, BidirectionalChildJDO bidir, StartEnd startEnd)
  1361. throws Throwable {
  1362. PutPolicy policy = setupPutPolicy(pojo, bidir, startEnd);
  1363. try {
  1364. startEnd.start();
  1365. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  1366. pojo.setVal("another val");
  1367. pojo.nullFlights();
  1368. pojo.nullBidirChildren();
  1369. pojo.nullHasKeyPks();
  1370. startEnd.end();
  1371. } finally {
  1372. DatastoreServiceInterceptor.uninstall();
  1373. }
  1374. if (startEnd == TXN_START_END) {
  1375. // transactional, so 1 put to do all
  1376. assertEquals(1, policy.putParamList.size());
  1377. } else {
  1378. // non-tx so 1 for each
  1379. assertEquals(4, policy.putParamList.size());
  1380. }
  1381. }
  1382. void testNonTxnAddOfChildToParentFailsPartwayThrough(HasOneToManyJDO pojo)
  1383. throws Throwable {
  1384. Flight flight1 = new Flight();
  1385. pojo.addFlight(flight1);
  1386. beginTxn();
  1387. pm.makePersistent(pojo);
  1388. commitTxn();
  1389. final String kind = kindForObject(pojo);
  1390. DatastoreServiceInterceptor.Policy policy = new DatastoreServiceInterceptor.Policy() {
  1391. public void intercept(Object o, Method method, Object[] params) {
  1392. if (method.getName().equals("put") && ((Entity) params[0]).getKind().equals(kind)) {
  1393. throw new ConcurrentModificationException("kaboom");
  1394. }
  1395. }
  1396. };
  1397. DatastoreServiceInterceptor.install(getStoreManager(), policy);
  1398. Flight flight2 = new Flight();
  1399. try {
  1400. pmf.close();
  1401. switchDatasource(PersistenceManagerFactoryName.nontransactional);
  1402. pojo = pm.getObjectById(pojo.getClass(), pojo.getId());
  1403. pojo.addFlight(flight2);
  1404. pm.close();
  1405. fail("expected exception");
  1406. } catch (ConcurrentModificationException cme) {
  1407. // good
  1408. } finally {
  1409. DatastoreServiceInterceptor.uninstall();
  1410. }
  1411. // prove that the book entity exists
  1412. ds.get(KeyFactory.stringToKey(flight2.getId()));
  1413. Entity pojoEntity = ds.get(KeyFactory.stringToKey(pojo.getId()));
  1414. // the parent has a reference to the first book that was already there
  1415. // but no reference to the second book
  1416. assertEquals(
  1417. Collections.singletonList(KeyFactory.stringToKey(flight1.getId())),
  1418. pojoEntity.getProperty("flights"));
  1419. }
  1420. void testSaveWithOrderBy(HasOneToManyListWithOrderByJDO pojo, StartEnd startEnd)
  1421. throws EntityNotFoundException {
  1422. getExecutionContext().getNucleusContext().getPersistenceConfiguration().setProperty(
  1423. "datanucleus.appengine.allowMultipleRelationsOfSameType", true);
  1424. startEnd.start();
  1425. pm.makePersistent(pojo);
  1426. startEnd.end();
  1427. }
  1428. // void testIndexOf(HasOneToManyJDO pojo, BidirectionalChildJDO bidir1, BidirectionalChildJDO bidir2,
  1429. // BidirectionalChildJDO bidir3) {
  1430. //
  1431. // Flight f1 = new Flight();
  1432. // Flight f2 = new Flight();
  1433. // Flight f3 = new Flight();
  1434. // pojo.addFlight(f1);
  1435. // pojo.addFlight(f2);
  1436. // pojo.addFlight(f3);
  1437. //
  1438. // pojo.addBidirChild(bidir1);
  1439. // pojo.addBidirChild(bidir2);
  1440. // pojo.addBidirChild(bidir3);
  1441. //
  1442. // startEnd.start();
  1443. // pm.makePersistent(pojo);
  1444. // startEnd.end();
  1445. // startEnd.start();
  1446. // assertEquals(0, pojo.indexOf(f1));
  1447. // assertEquals(1, pojo.indexOf(f2));
  1448. // assertEquals(2, pojo.indexOf(f3));
  1449. // assertEquals(0, pojo.indexOf(bidir1));
  1450. // assertEquals(1, pojo.indexOf(bidir2));
  1451. // assertEquals(2, pojo.indexOf(bidir3));
  1452. // startEnd.end();
  1453. //
  1454. // startEnd.start();
  1455. // pojo = pm.getObjectById(pojo.getClass(), pojo.getKey());
  1456. // assertEquals(0, pojo.indexOf(f1));
  1457. // assertEquals(1, pojo.indexOf(f2));
  1458. // assertEquals(2, pojo.indexOf(f3));
  1459. // assertEquals(0, pojo.indexOf(bidir1));
  1460. // assertEquals(1, pojo.indexOf(bidir2));
  1461. // assertEquals(2, pojo.indexOf(bidir3));
  1462. // startEnd.end();
  1463. // }
  1464. void assertCountsInDatastore(Class<? extends HasOneToManyJDO> parentClass,
  1465. Class<? extends BidirectionalChildJDO> bidirClass,
  1466. int expectedParent, int expectedChildren) {
  1467. assertEquals(parentClass.getName(), expectedParent, countForClass(parentClass));
  1468. assertEquals(bidirClass.getName(), expectedChildren, countForClass(bidirClass));
  1469. assertEquals(
  1470. Flight.class.getName(), expectedChildren, countForClass(Flight.class));
  1471. assertEquals(
  1472. HasKeyPkJDO.class.getName(), expectedChildren, countForClass(HasKeyPkJDO.class));
  1473. }
  1474. Flight newFlight() {
  1475. Flight f = new Flight();
  1476. f.setOrigin("bos");
  1477. f.setDest("mia");
  1478. f.setName("jimmy");
  1479. f.setMe(22);
  1480. f.setYou(26);
  1481. f.setFlightNumber(99);
  1482. return f;
  1483. }
  1484. Entity newFlightEntity(
  1485. Key parentKey, String orig, String dest, String name) {
  1486. Entity entity = new Entity(Flight.class.getSimpleName(), parentKey);
  1487. entity.setProperty("origin", orig);
  1488. entity.setProperty("dest", dest);
  1489. entity.setProperty("name", name);
  1490. entity.setProperty("you", 44);
  1491. entity.setProperty("me", 45);
  1492. entity.setProperty("flight_number", 99);
  1493. entity.setProperty("flights_INTEGER_IDX", 1);
  1494. return entity;
  1495. }
  1496. abstract boolean isIndexed();
  1497. }