PageRenderTime 57ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

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