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

http://datanucleus-appengine.googlecode.com/ · Java · 692 lines · 574 code · 84 blank · 34 comment · 0 complexity · 7e3234e78f133835485bc5c0c435b8f1 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.Entity;
  15. import com.google.appengine.api.datastore.EntityNotFoundException;
  16. import com.google.appengine.api.datastore.Key;
  17. import com.google.appengine.api.datastore.KeyFactory;
  18. import com.google.appengine.datanucleus.DatastoreManager;
  19. import com.google.appengine.datanucleus.test.jdo.SubclassesJDO;
  20. import com.google.appengine.datanucleus.test.jdo.SubclassesJDO.CompleteTableParentNoChildStrategy;
  21. import com.google.appengine.datanucleus.test.jdo.SubclassesJDO.CompleteTableParentWithCompleteTableChild;
  22. import com.google.appengine.datanucleus.test.jdo.SubclassesJDO.CompleteTableParentWithEmbedded;
  23. import com.google.appengine.datanucleus.test.jdo.SubclassesJDO.CompleteTableParentWithNewTableChild;
  24. import com.google.appengine.datanucleus.test.jdo.SubclassesJDO.CompleteTableParentWithSubclassTableChild;
  25. import com.google.appengine.datanucleus.test.jdo.SubclassesJDO.DurableChild;
  26. import com.google.appengine.datanucleus.test.jdo.SubclassesJDO.Grandchild;
  27. import com.google.appengine.datanucleus.test.jdo.SubclassesJDO.NewTableParentWithCompleteTableChild;
  28. import com.google.appengine.datanucleus.test.jdo.SubclassesJDO.NewTableParentWithNewTableChild;
  29. import com.google.appengine.datanucleus.test.jdo.SubclassesJDO.NewTableParentWithSubclassTableChild;
  30. import com.google.appengine.datanucleus.test.jdo.SubclassesJDO.OverrideParent;
  31. import com.google.appengine.datanucleus.test.jdo.SubclassesJDO.Parent;
  32. import com.google.appengine.datanucleus.test.jdo.SubclassesJDO.SubclassTableParentWithCompleteTableChild;
  33. import com.google.appengine.datanucleus.test.jdo.SubclassesJDO.SubclassTableParentWithNewTableChild;
  34. import com.google.appengine.datanucleus.test.jdo.SubclassesJDO.SubclassTableParentWithSubclassTableChild;
  35. import org.datanucleus.api.jdo.exceptions.NoPersistenceInformationException;
  36. import java.util.List;
  37. import javax.jdo.JDOFatalUserException;
  38. import javax.jdo.Query;
  39. /**
  40. * There's something flaky here that will probably show up as a real bug at
  41. * some point. If the Parent class gets used first, the subclass
  42. * tests fail. To get around this I'm just running the subclass tests
  43. * first. There's definitely something funny going on though.
  44. *
  45. * @author Max Ross <maxr@google.com>
  46. */
  47. // TODO(maxr): non-transactional tests
  48. public class JDOSubclassTest extends JDOTestCase {
  49. public void testGrandchildren() throws Exception {
  50. testGrandchild(new CompleteTableParentWithCompleteTableChild.Child.Grandchild());
  51. testGrandchild(new CompleteTableParentNoChildStrategy.Child.Grandchild());
  52. testGrandchild(new SubclassTableParentWithCompleteTableChild.Child.Grandchild());
  53. }
  54. public void testChildren() throws Exception {
  55. testChild(new CompleteTableParentWithCompleteTableChild.Child());
  56. testChild(new CompleteTableParentNoChildStrategy.Child());
  57. testChild(new SubclassTableParentWithCompleteTableChild.Child());
  58. testChild(new SubclassTableParentWithNewTableChild.Child());
  59. testChild(new NewTableParentWithCompleteTableChild.Child());
  60. }
  61. public void testUnsupportedStrategies_GAE() {
  62. assertUnsupportedByGAE(new NewTableParentWithNewTableChild.Child());
  63. assertUnsupportedByGAE(new CompleteTableParentWithNewTableChild.Child());
  64. assertUnsupportedByGAE(new SubclassTableParentWithNewTableChild.Child.Grandchild());
  65. }
  66. public void testUnsupportedStrategies_DataNuc() throws Exception {
  67. assertUnsupportedByDataNuc(new SubclassTableParentWithSubclassTableChild.Child());
  68. assertUnsupportedByDataNuc(new SubclassTableParentWithCompleteTableChild());
  69. }
  70. public void testParents() throws Exception {
  71. testParent(new CompleteTableParentWithCompleteTableChild());
  72. testParent(new CompleteTableParentWithNewTableChild());
  73. testParent(new CompleteTableParentWithSubclassTableChild());
  74. testParent(new CompleteTableParentNoChildStrategy());
  75. testParent(new NewTableParentWithCompleteTableChild());
  76. testParent(new NewTableParentWithSubclassTableChild());
  77. testParent(new NewTableParentWithNewTableChild());
  78. }
  79. public void testOverride() throws Exception {
  80. OverrideParent.Child child = new OverrideParent.Child();
  81. child.setOverriddenString("blarg");
  82. beginTxn();
  83. pm.makePersistent(child);
  84. commitTxn();
  85. Entity e = ds.get(KeyFactory.createKey(kindForClass(child.getClass()), child.getId()));
  86. assertEquals("blarg", e.getProperty("overridden_string"));
  87. assertFalse(e.hasProperty("overriddenProperty"));
  88. }
  89. public void testEmbedded_Child() throws Exception {
  90. CompleteTableParentWithEmbedded.Child child = new CompleteTableParentWithEmbedded.Child();
  91. child.setAString("aString");
  92. child.setBString("bString");
  93. SubclassesJDO.IsEmbeddedOnly embedded = new SubclassesJDO.IsEmbeddedOnly();
  94. embedded.setVal0("embedded val 0");
  95. embedded.setVal1("embedded val 1");
  96. child.setEmbedded(embedded);
  97. SubclassesJDO.IsEmbeddedOnlyBase embeddedBase = new SubclassesJDO.IsEmbeddedOnlyBase();
  98. embeddedBase.setVal0("embedded base val 0");
  99. child.setEmbeddedBase(embeddedBase);
  100. SubclassesJDO.IsEmbeddedOnly2 embedded2 = new SubclassesJDO.IsEmbeddedOnly2();
  101. embedded2.setVal2("embedded val 2");
  102. embedded2.setVal3("embedded val 3");
  103. child.setEmbedded2(embedded2);
  104. SubclassesJDO.IsEmbeddedOnlyBase2 embeddedBase2 = new SubclassesJDO.IsEmbeddedOnlyBase2();
  105. embeddedBase2.setVal2("embedded base val 2");
  106. child.setEmbeddedBase2(embeddedBase2);
  107. beginTxn();
  108. pm.makePersistent(child);
  109. commitTxn();
  110. Key key = KeyFactory.createKey(kindForClass(child.getClass()), child.getId());
  111. Entity e = ds.get(key);
  112. assertEquals("aString", e.getProperty("aString"));
  113. assertEquals("bString", e.getProperty("bString"));
  114. assertEquals("embedded val 0", e.getProperty("val0"));
  115. assertEquals("embedded val 1", e.getProperty("val1"));
  116. assertEquals("embedded base val 0", e.getProperty("VAL0"));
  117. assertEquals("embedded val 2", e.getProperty("val2"));
  118. assertEquals("embedded val 3", e.getProperty("val3"));
  119. assertEquals("embedded base val 2", e.getProperty("VAL2"));
  120. pm.close();
  121. pm = pmf.getPersistenceManager();
  122. beginTxn();
  123. child = pm.getObjectById(child.getClass(), child.getId());
  124. assertEmbeddedChildContents(child);
  125. commitTxn();
  126. pm.close();
  127. pm = pmf.getPersistenceManager();
  128. beginTxn();
  129. Query q = pm.newQuery("select from " + child.getClass().getName() + " where embedded.val1 == :p "
  130. + "order by embedded.val1 desc, embedded.val0 desc, embeddedBase.val0 desc, "
  131. + "embedded2.val2 desc, embedded2.val3 desc, embeddedBase2.val2");
  132. q.setUnique(true);
  133. child = (CompleteTableParentWithEmbedded.Child) q.execute("embedded val 1");
  134. assertEmbeddedChildContents(child);
  135. q = pm.newQuery("select from " + child.getClass().getName() + " where embedded.val0 == :p "
  136. + "order by embedded.val1 desc, embedded.val0 desc, embeddedBase.val0 desc, "
  137. + "embedded2.val2 desc, embedded2.val3 desc, embeddedBase2.val2");
  138. q.setUnique(true);
  139. child = (CompleteTableParentWithEmbedded.Child) q.execute("embedded val 0");
  140. assertEmbeddedChildContents(child);
  141. q = pm.newQuery("select from " + child.getClass().getName() + " where embeddedBase.val0 == :p "
  142. + "order by embedded.val1 desc, embedded.val0 desc, embeddedBase.val0 desc, "
  143. + "embedded2.val2 desc, embedded2.val3 desc, embeddedBase2.val2");
  144. q.setUnique(true);
  145. child = (CompleteTableParentWithEmbedded.Child) q.execute("embedded base val 0");
  146. assertEmbeddedChildContents(child);
  147. q = pm.newQuery("select from " + child.getClass().getName() + " where embedded2.val2 == :p "
  148. + "order by embedded.val1 desc, embedded.val0 desc, embeddedBase.val0 desc, "
  149. + "embedded2.val2 desc, embedded2.val3 desc, embeddedBase2.val2");
  150. q.setUnique(true);
  151. child = (CompleteTableParentWithEmbedded.Child) q.execute("embedded val 2");
  152. assertEmbeddedChildContents(child);
  153. q = pm.newQuery("select from " + child.getClass().getName() + " where embedded2.val3 == :p "
  154. + "order by embedded.val1 desc, embedded.val0 desc, embeddedBase.val0 desc, "
  155. + "embedded2.val2 desc, embedded2.val3 desc, embeddedBase2.val2");
  156. q.setUnique(true);
  157. child = (CompleteTableParentWithEmbedded.Child) q.execute("embedded val 3");
  158. assertEmbeddedChildContents(child);
  159. q = pm.newQuery("select from " + child.getClass().getName() + " where embeddedBase2.val2 == :p "
  160. + "order by embedded.val1 desc, embedded.val0 desc, embeddedBase.val0 desc, "
  161. + "embedded2.val2 desc, embedded2.val3 desc, embeddedBase2.val2");
  162. q.setUnique(true);
  163. child = (CompleteTableParentWithEmbedded.Child) q.execute("embedded base val 2");
  164. assertEmbeddedChildContents(child);
  165. q = pm.newQuery("select embedded.val1, embedded.val0, embeddedBase.val0, embedded2.val2, embedded2.val3, embeddedBase2.val2 from " +
  166. child.getClass().getName() + " where embeddedBase2.val2 == :p");
  167. q.setUnique(true);
  168. Object[] result = (Object[]) q.execute("embedded base val 2");
  169. assertEquals("embedded val 1", result[0]);
  170. assertEquals("embedded val 0", result[1]);
  171. assertEquals("embedded base val 0", result[2]);
  172. assertEquals("embedded val 2", result[3]);
  173. assertEquals("embedded val 3", result[4]);
  174. assertEquals("embedded base val 2", result[5]);
  175. pm.deletePersistent(child);
  176. commitTxn();
  177. try {
  178. ds.get(key);
  179. fail("expected enfe");
  180. } catch (EntityNotFoundException enfe) {
  181. // good
  182. }
  183. }
  184. public void testEmbedded_Parent() throws Exception {
  185. CompleteTableParentWithEmbedded parent = new CompleteTableParentWithEmbedded();
  186. parent.setAString("aString");
  187. SubclassesJDO.IsEmbeddedOnly embedded = new SubclassesJDO.IsEmbeddedOnly();
  188. embedded.setVal0("embedded val 0");
  189. embedded.setVal1("embedded val 1");
  190. parent.setEmbedded(embedded);
  191. SubclassesJDO.IsEmbeddedOnlyBase embeddedBase = new SubclassesJDO.IsEmbeddedOnlyBase();
  192. embeddedBase.setVal0("embedded base val 0");
  193. parent.setEmbeddedBase(embeddedBase);
  194. beginTxn();
  195. pm.makePersistent(parent);
  196. commitTxn();
  197. Key key = KeyFactory.createKey(kindForClass(parent.getClass()), parent.getId());
  198. Entity e = ds.get(key);
  199. assertEquals("aString", e.getProperty("aString"));
  200. assertEquals("embedded val 0", e.getProperty("val0"));
  201. assertEquals("embedded val 1", e.getProperty("val1"));
  202. assertEquals("embedded base val 0", e.getProperty("VAL0"));
  203. pm.close();
  204. pm = pmf.getPersistenceManager();
  205. beginTxn();
  206. parent = pm.getObjectById(parent.getClass(), parent.getId());
  207. assertEmbeddedParentContents(parent);
  208. commitTxn();
  209. pm.close();
  210. pm = pmf.getPersistenceManager();
  211. beginTxn();
  212. Query q = pm.newQuery(
  213. "select from " + parent.getClass().getName() + " where embedded.val1 == :p "
  214. + "order by embedded.val1 desc, embedded.val0 asc, embeddedBase.val0 desc");
  215. q.setUnique(true);
  216. parent = (CompleteTableParentWithEmbedded) q.execute("embedded val 1");
  217. assertEmbeddedParentContents(parent);
  218. q = pm.newQuery(
  219. "select from " + parent.getClass().getName() + " where embedded.val0 == :p "
  220. + "order by embedded.val1 desc, embedded.val0 asc, embeddedBase.val0 desc");
  221. q.setUnique(true);
  222. parent = (CompleteTableParentWithEmbedded) q.execute("embedded val 0");
  223. assertEmbeddedParentContents(parent);
  224. q = pm.newQuery(
  225. "select from " + parent.getClass().getName() + " where embeddedBase.val0 == :p "
  226. + "order by embedded.val1 desc, embedded.val0 asc, embeddedBase.val0 desc");
  227. q.setUnique(true);
  228. parent = (CompleteTableParentWithEmbedded) q.execute("embedded base val 0");
  229. assertEmbeddedParentContents(parent);
  230. q = pm.newQuery("select embedded.val1, embedded.val0, embeddedBase.val0 from " +
  231. parent.getClass().getName() + " where embeddedBase.val0 == :p "
  232. + "order by embedded.val1 desc, embedded.val0 asc, embeddedBase.val0 desc");
  233. q.setUnique(true);
  234. Object[] result = (Object[]) q.execute("embedded base val 0");
  235. assertEquals("embedded val 1", result[0]);
  236. assertEquals("embedded val 0", result[1]);
  237. assertEquals("embedded base val 0", result[2]);
  238. pm.deletePersistent(parent);
  239. commitTxn();
  240. try {
  241. ds.get(key);
  242. fail("expected enfe");
  243. } catch (EntityNotFoundException enfe) {
  244. // good
  245. }
  246. }
  247. public void testNondurableParent() {
  248. DurableChild dc = new DurableChild();
  249. dc.setStr("yar");
  250. beginTxn();
  251. pm.makePersistent(dc);
  252. commitTxn();
  253. beginTxn();
  254. dc = pm.getObjectById(DurableChild.class, dc.getId());
  255. assertEquals("yar", dc.getStr());
  256. }
  257. // This is absurd, but if the signature of this method and the one below
  258. // refers to the actual type we want the runtime enhancer gets totally
  259. // confused.
  260. private void assertEmbeddedChildContents(Object obj) {
  261. CompleteTableParentWithEmbedded.Child child = (CompleteTableParentWithEmbedded.Child) obj;
  262. assertEquals("bString", child.getBString());
  263. assertEquals("embedded val 2", child.getEmbedded2().getVal2());
  264. assertEquals("embedded val 3", child.getEmbedded2().getVal3());
  265. assertEquals("embedded base val 2", child.getEmbeddedBase2().getVal2());
  266. assertEmbeddedParentContents(child);
  267. }
  268. private void assertEmbeddedParentContents(Object obj) {
  269. CompleteTableParentWithEmbedded parentWithEmbedded = (CompleteTableParentWithEmbedded) obj;
  270. assertEquals("aString", parentWithEmbedded.getAString());
  271. assertEquals("embedded val 0", parentWithEmbedded.getEmbedded().getVal0());
  272. assertEquals("embedded val 1", parentWithEmbedded.getEmbedded().getVal1());
  273. assertEquals("embedded base val 0", parentWithEmbedded.getEmbeddedBase().getVal0());
  274. }
  275. private void assertUnsupportedByDataNuc(Object obj) {
  276. switchDatasource(PersistenceManagerFactoryName.transactional);
  277. beginTxn();
  278. try {
  279. pm.makePersistent(obj);
  280. fail("expected exception");
  281. } catch (NoPersistenceInformationException e) {
  282. // good
  283. }
  284. rollbackTxn();
  285. }
  286. private void assertUnsupportedByGAE(Object obj) {
  287. switchDatasource(PersistenceManagerFactoryName.transactional);
  288. beginTxn();
  289. try {
  290. pm.makePersistent(obj);
  291. fail("expected exception");
  292. } catch (JDOFatalUserException e) {
  293. // good
  294. assertTrue(e.getCause().getClass().getName(),
  295. DatastoreManager.UnsupportedInheritanceStrategyException.class.isAssignableFrom(e.getCause().getClass()));
  296. }
  297. rollbackTxn();
  298. }
  299. private void testInsertParent(Parent parent) throws Exception {
  300. parent.setAString("a");
  301. beginTxn();
  302. pm.makePersistent(parent);
  303. commitTxn();
  304. Entity e = ds.get(KeyFactory.createKey(kindForClass(parent.getClass()), parent.getId()));
  305. assertEquals("a", e.getProperty("aString"));
  306. }
  307. private void testInsertChild(SubclassesJDO.Child child) throws Exception {
  308. child.setAString("a");
  309. child.setBString("b");
  310. beginTxn();
  311. pm.makePersistent(child);
  312. commitTxn();
  313. Entity e = ds.get(KeyFactory.createKey(kindForClass(child.getClass()), child.getId()));
  314. assertEquals("a", e.getProperty("aString"));
  315. assertEquals("b", e.getProperty("bString"));
  316. }
  317. private void testInsertGrandchild(com.google.appengine.datanucleus.test.jdo.SubclassesJDO.Grandchild grandchild) throws Exception {
  318. grandchild.setAString("a");
  319. grandchild.setBString("b");
  320. grandchild.setCString("c");
  321. beginTxn();
  322. pm.makePersistent(grandchild);
  323. commitTxn();
  324. Entity e = ds.get(KeyFactory.createKey(kindForClass(grandchild.getClass()), grandchild.getId()));
  325. assertEquals("a", e.getProperty("aString"));
  326. assertEquals("b", e.getProperty("bString"));
  327. assertEquals("c", e.getProperty("cString"));
  328. }
  329. private void testFetchParent(Class<? extends Parent> parentClass) {
  330. Entity e = new Entity(kindForClass(parentClass));
  331. e.setProperty("aString", "a");
  332. ds.put(e);
  333. beginTxn();
  334. Parent parent = pm.getObjectById(parentClass, e.getKey());
  335. assertEquals(parentClass, parent.getClass());
  336. assertEquals("a", parent.getAString());
  337. commitTxn();
  338. }
  339. private void testFetchChild(Class<? extends SubclassesJDO.Child> childClass) {
  340. Entity e = new Entity(kindForClass(childClass));
  341. e.setProperty("aString", "a");
  342. e.setProperty("bString", "b");
  343. ds.put(e);
  344. beginTxn();
  345. SubclassesJDO.Child child = pm.getObjectById(childClass, e.getKey());
  346. assertEquals(childClass, child.getClass());
  347. assertEquals("a", child.getAString());
  348. assertEquals("b", child.getBString());
  349. commitTxn();
  350. }
  351. private void testFetchGrandchild(Class<? extends com.google.appengine.datanucleus.test.jdo.SubclassesJDO.Grandchild> grandchildClass) {
  352. Entity e = new Entity(kindForClass(grandchildClass));
  353. e.setProperty("aString", "a");
  354. e.setProperty("bString", "b");
  355. e.setProperty("cString", "c");
  356. ds.put(e);
  357. beginTxn();
  358. com.google.appengine.datanucleus.test.jdo.SubclassesJDO.Grandchild
  359. grandchild = pm.getObjectById(grandchildClass, e.getKey());
  360. assertEquals(grandchildClass, grandchild.getClass());
  361. assertEquals("a", grandchild.getAString());
  362. assertEquals("b", grandchild.getBString());
  363. assertEquals("c", grandchild.getCString());
  364. commitTxn();
  365. }
  366. private void testQueryParent(Class<? extends Parent> parentClass) {
  367. Entity e = new Entity(kindForClass(parentClass));
  368. e.setProperty("aString", "z8");
  369. ds.put(e);
  370. e = new Entity(kindForClass(parentClass));
  371. e.setProperty("aString", "z9");
  372. ds.put(e);
  373. beginTxn();
  374. Parent parent = ((List<Parent>) pm.newQuery(
  375. "select from " + parentClass.getName() + " where aString == 'z8'").execute()).get(0);
  376. assertEquals(parentClass, parent.getClass());
  377. assertEquals("z8", parent.getAString());
  378. commitTxn();
  379. beginTxn();
  380. List<Parent> parents = ((List<Parent>) pm.newQuery(
  381. "select from " + parentClass.getName() + " where aString >= 'z8' order by aString desc").execute());
  382. assertEquals(2, parents.size());
  383. assertEquals("z9", parents.get(0).getAString());
  384. assertEquals("z8", parents.get(1).getAString());
  385. commitTxn();
  386. beginTxn();
  387. String aString = ((List<String>) pm.newQuery(
  388. "select aString from " + parentClass.getName() + " where aString == 'z8'").execute()).get(0);
  389. assertEquals("z8", aString);
  390. commitTxn();
  391. }
  392. private void testQueryChild(Class<? extends SubclassesJDO.Child> childClass) {
  393. Entity e1 = new Entity(kindForClass(childClass));
  394. e1.setProperty("aString", "a2");
  395. e1.setProperty("bString", "b2");
  396. ds.put(e1);
  397. Entity e2 = new Entity(kindForClass(childClass));
  398. e2.setProperty("aString", "a2");
  399. e2.setProperty("bString", "b3");
  400. ds.put(e2);
  401. Entity e3 = new Entity(kindForClass(childClass));
  402. e3.setProperty("aString", "a2");
  403. e3.setProperty("bString", "b3");
  404. ds.put(e3);
  405. beginTxn();
  406. SubclassesJDO.Child child = ((List<SubclassesJDO.Child>) pm.newQuery(
  407. "select from " + childClass.getName() + " where aString == 'a2'").execute()).get(0);
  408. assertEquals(childClass, child.getClass());
  409. assertEquals("a2", child.getAString());
  410. assertEquals("b2", child.getBString());
  411. child = ((List<SubclassesJDO.Child>) pm.newQuery(
  412. "select from " + childClass.getName() + " where bString == 'b2'").execute()).get(0);
  413. assertEquals(childClass, child.getClass());
  414. assertEquals("a2", child.getAString());
  415. assertEquals("b2", child.getBString());
  416. List<SubclassesJDO.Child> kids = ((List<SubclassesJDO.Child>) pm.newQuery(
  417. "select from " + childClass.getName() + " where aString == 'a2' order by bString desc").execute());
  418. assertEquals(3, kids.size());
  419. assertEquals(e2.getKey().getId(), kids.get(0).getId().longValue());
  420. assertEquals(e3.getKey().getId(), kids.get(1).getId().longValue());
  421. assertEquals(e1.getKey().getId(), kids.get(2).getId().longValue());
  422. kids = ((List<SubclassesJDO.Child>) pm.newQuery("select from " + childClass.getName() + " where aString == 'a2' order by aString desc").execute());
  423. assertEquals(3, kids.size());
  424. assertEquals(e1.getKey().getId(), kids.get(0).getId().longValue());
  425. assertEquals(e2.getKey().getId(), kids.get(1).getId().longValue());
  426. assertEquals(e3.getKey().getId(), kids.get(2).getId().longValue());
  427. Object[] result = ((List<Object[]>) pm.newQuery("select bString, aString from " + childClass.getName() + " where bString == 'b2'").execute()).get(0);
  428. assertEquals(2, result.length);
  429. assertEquals("b2", result[0]);
  430. assertEquals("a2", result[1]);
  431. commitTxn();
  432. }
  433. private void testQueryGrandchild(Class<? extends com.google.appengine.datanucleus.test.jdo.SubclassesJDO.Grandchild> grandchildClass) {
  434. Entity e1 = new Entity(kindForClass(grandchildClass));
  435. e1.setProperty("aString", "a2");
  436. e1.setProperty("bString", "b1");
  437. e1.setProperty("cString", "c2");
  438. ds.put(e1);
  439. Entity e2 = new Entity(kindForClass(grandchildClass));
  440. e2.setProperty("aString", "a2");
  441. e2.setProperty("bString", "b3");
  442. e2.setProperty("cString", "c3");
  443. ds.put(e2);
  444. Entity e3 = new Entity(kindForClass(grandchildClass));
  445. e3.setProperty("aString", "a2");
  446. e3.setProperty("bString", "b2");
  447. e3.setProperty("cString", "c3");
  448. ds.put(e3);
  449. beginTxn();
  450. Grandchild grandchild = ((List<Grandchild>) pm.newQuery(
  451. "select from " + grandchildClass.getName() + " where aString == 'a2'").execute()).get(0);
  452. assertEquals(grandchildClass, grandchild.getClass());
  453. assertEquals("a2", grandchild.getAString());
  454. assertEquals("b1", grandchild.getBString());
  455. assertEquals("c2", grandchild.getCString());
  456. grandchild = ((List<Grandchild>) pm.newQuery(
  457. "select from " + grandchildClass.getName() + " where bString == 'b2'").execute()).get(0);
  458. assertEquals(grandchildClass, grandchild.getClass());
  459. assertEquals("a2", grandchild.getAString());
  460. assertEquals("b2", grandchild.getBString());
  461. assertEquals("c3", grandchild.getCString());
  462. grandchild = ((List<Grandchild>) pm.newQuery(
  463. "select from " + grandchildClass.getName() + " where cString == 'c2'").execute()).get(0);
  464. assertEquals(grandchildClass, grandchild.getClass());
  465. assertEquals("a2", grandchild.getAString());
  466. assertEquals("b1", grandchild.getBString());
  467. assertEquals("c2", grandchild.getCString());
  468. List<Grandchild> grandkids = ((List<Grandchild>) pm.newQuery(
  469. "select from " + grandchildClass.getName() + " where aString == 'a2' order by bString desc").execute());
  470. assertEquals(3, grandkids.size());
  471. assertEquals(e2.getKey().getId(), grandkids.get(0).getId().longValue());
  472. assertEquals(e3.getKey().getId(), grandkids.get(1).getId().longValue());
  473. assertEquals(e1.getKey().getId(), grandkids.get(2).getId().longValue());
  474. grandkids = ((List<Grandchild>) pm.newQuery(
  475. "select from " + grandchildClass.getName() + " where aString == 'a2' order by aString desc").execute());
  476. assertEquals(3, grandkids.size());
  477. assertEquals(e1.getKey().getId(), grandkids.get(0).getId().longValue());
  478. assertEquals(e2.getKey().getId(), grandkids.get(1).getId().longValue());
  479. assertEquals(e3.getKey().getId(), grandkids.get(2).getId().longValue());
  480. grandkids = ((List<Grandchild>) pm.newQuery(
  481. "select from " + grandchildClass.getName() + " where aString == 'a2' order by cString desc").execute());
  482. assertEquals(3, grandkids.size());
  483. assertEquals(e2.getKey().getId(), grandkids.get(0).getId().longValue());
  484. assertEquals(e3.getKey().getId(), grandkids.get(1).getId().longValue());
  485. assertEquals(e1.getKey().getId(), grandkids.get(2).getId().longValue());
  486. Object[] result = ((List<Object[]>) pm.newQuery(
  487. "select bString, aString, cString from " + grandchildClass.getName() + " where cString == 'c2'").execute()).get(0);
  488. assertEquals(3, result.length);
  489. assertEquals("b1", result[0]);
  490. assertEquals("a2", result[1]);
  491. assertEquals("c2", result[2]);
  492. commitTxn();
  493. }
  494. private void testDeleteParent(Class<? extends Parent> parentClass) {
  495. Entity e = new Entity(kindForClass(parentClass));
  496. e.setProperty("aString", "a");
  497. ds.put(e);
  498. beginTxn();
  499. Parent parent = pm.getObjectById(parentClass, e.getKey());
  500. pm.deletePersistent(parent);
  501. commitTxn();
  502. try {
  503. ds.get(e.getKey());
  504. fail("expected exception");
  505. } catch (EntityNotFoundException e1) {
  506. // good
  507. }
  508. }
  509. private void testDeleteChild(Class<? extends SubclassesJDO.Child> childClass) {
  510. Entity e = new Entity(kindForClass(childClass));
  511. e.setProperty("aString", "a");
  512. e.setProperty("bString", "b");
  513. ds.put(e);
  514. beginTxn();
  515. SubclassesJDO.Child child = pm.getObjectById(childClass, e.getKey());
  516. pm.deletePersistent(child);
  517. commitTxn();
  518. try {
  519. ds.get(e.getKey());
  520. fail("expected exception");
  521. } catch (EntityNotFoundException e1) {
  522. // good
  523. }
  524. }
  525. private void testDeleteGrandchild(Class<? extends com.google.appengine.datanucleus.test.jdo.SubclassesJDO.Grandchild> grandchildClass) {
  526. Entity e = new Entity(kindForClass(grandchildClass));
  527. e.setProperty("aString", "a");
  528. e.setProperty("bString", "b");
  529. e.setProperty("cString", "c");
  530. ds.put(e);
  531. beginTxn();
  532. SubclassesJDO.Child child = pm.getObjectById(grandchildClass, e.getKey());
  533. pm.deletePersistent(child);
  534. commitTxn();
  535. try {
  536. ds.get(e.getKey());
  537. fail("expected exception");
  538. } catch (EntityNotFoundException e1) {
  539. // good
  540. }
  541. }
  542. private void testUpdateParent(Class<? extends Parent> parentClass) throws Exception {
  543. Entity e = new Entity(kindForClass(parentClass));
  544. e.setProperty("aString", "a");
  545. ds.put(e);
  546. beginTxn();
  547. Parent parent = pm.getObjectById(parentClass, e.getKey());
  548. parent.setAString("not a");
  549. commitTxn();
  550. e = ds.get(e.getKey());
  551. assertEquals("not a", e.getProperty("aString"));
  552. }
  553. private void testUpdateChild(Class<? extends SubclassesJDO.Child> childClass) throws Exception {
  554. Entity e = new Entity(kindForClass(childClass));
  555. e.setProperty("aString", "a");
  556. e.setProperty("bString", "b");
  557. ds.put(e);
  558. beginTxn();
  559. SubclassesJDO.Child child = pm.getObjectById(childClass, e.getKey());
  560. child.setAString("not a");
  561. child.setBString("not b");
  562. commitTxn();
  563. e = ds.get(e.getKey());
  564. assertEquals("not a", e.getProperty("aString"));
  565. assertEquals("not b", e.getProperty("bString"));
  566. }
  567. private void testUpdateGrandchild(Class<? extends com.google.appengine.datanucleus.test.jdo.SubclassesJDO.Grandchild> grandchildClass) throws Exception {
  568. Entity e = new Entity(kindForClass(grandchildClass));
  569. e.setProperty("aString", "a");
  570. e.setProperty("bString", "b");
  571. ds.put(e);
  572. beginTxn();
  573. com.google.appengine.datanucleus.test.jdo.SubclassesJDO.Grandchild
  574. grandchild = pm.getObjectById(grandchildClass, e.getKey());
  575. grandchild.setAString("not a");
  576. grandchild.setBString("not b");
  577. grandchild.setCString("not c");
  578. commitTxn();
  579. e = ds.get(e.getKey());
  580. assertEquals("not a", e.getProperty("aString"));
  581. assertEquals("not b", e.getProperty("bString"));
  582. assertEquals("not c", e.getProperty("cString"));
  583. }
  584. private void testGrandchild(com.google.appengine.datanucleus.test.jdo.SubclassesJDO.Grandchild grandchild) throws Exception {
  585. testInsertGrandchild(grandchild);
  586. testUpdateGrandchild(grandchild.getClass());
  587. testDeleteGrandchild(grandchild.getClass());
  588. testFetchGrandchild(grandchild.getClass());
  589. testQueryGrandchild(grandchild.getClass());
  590. }
  591. private void testChild(SubclassesJDO.Child child) throws Exception {
  592. testInsertChild(child);
  593. testUpdateChild(child.getClass());
  594. testDeleteChild(child.getClass());
  595. testFetchChild(child.getClass());
  596. testQueryChild(child.getClass());
  597. }
  598. private void testParent(Parent parent) throws Exception {
  599. testInsertParent(parent);
  600. testUpdateParent(parent.getClass());
  601. testDeleteParent(parent.getClass());
  602. testFetchParent(parent.getClass());
  603. testQueryParent(parent.getClass());
  604. }
  605. }