PageRenderTime 69ms CodeModel.GetById 9ms app.highlight 53ms RepoModel.GetById 1ms app.codeStats 0ms

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

http://datanucleus-appengine.googlecode.com/
Java | 760 lines | 609 code | 114 blank | 37 comment | 7 complexity | 491f4b46bd64ef834d6df6312de4724e MD5 | raw file
  1/**********************************************************************
  2Copyright (c) 2011 Google Inc.
  3
  4Licensed under the Apache License, Version 2.0 (the "License");
  5you may not use this file except in compliance with the License.
  6You may obtain a copy of the License at
  7
  8http://www.apache.org/licenses/LICENSE-2.0
  9
 10Unless required by applicable law or agreed to in writing, software
 11distributed under the License is distributed on an "AS IS" BASIS,
 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13See the License for the specific language governing permissions and
 14limitations under the License.
 15**********************************************************************/
 16package com.google.appengine.datanucleus.jdo;
 17
 18import com.google.appengine.api.datastore.Entity;
 19import com.google.appengine.api.datastore.Key;
 20import com.google.appengine.api.datastore.KeyFactory;
 21import com.google.appengine.api.datastore.Text;
 22import com.google.appengine.datanucleus.DatastoreManager;
 23import com.google.appengine.datanucleus.test.jdo.SuperclassTableInheritanceJDO.*;
 24
 25import junit.framework.Assert;
 26
 27import javax.jdo.Extent;
 28import javax.jdo.JDOFatalUserException;
 29import javax.jdo.Query;
 30
 31import java.util.*;
 32
 33public class JDOSuperclassTableInheritanceTest extends JDOTestCase {
 34  private final static String PARENT_KIND = "SuperclassTableInheritanceJDO$Parent";
 35  private final static String PARENTINT_KIND = "SuperclassTableInheritanceJDO$ParentIntDiscriminator";
 36
 37  public void testCreateAndFindParentAndChildren() throws Exception {
 38    testCreateAndFindParentAndChildren(TXN_START_END);
 39  }
 40  public void testCreateAndFindParentAndChildren_NoTxn() throws Exception {
 41    switchDatasource(PersistenceManagerFactoryName.nontransactional);
 42    testCreateAndFindParentAndChildren(NEW_PM_START_END);
 43  }
 44  @SuppressWarnings("unchecked")
 45  private void testCreateAndFindParentAndChildren(StartEnd startEnd) throws Exception {
 46    
 47    //	create Parent
 48    Parent p = newParent(startEnd, "Parent");
 49    Long pId = p.getId();
 50    Key pKey = KeyFactory.createKey(PARENT_KIND, pId);
 51    
 52    //	verify Parent entity
 53    Entity pe = ds.get(pKey);
 54    Assert.assertEquals(pKey, pe.getKey());
 55    Assert.assertEquals("P", pe.getProperty("DISCRIMINATOR"));
 56    Assert.assertEquals("Parent", pe.getProperty("parentStr"));
 57    Assert.assertEquals(2, pe.getProperties().size());
 58    
 59    //	verify Parent object
 60    startEnd.start();
 61    p = pm.getObjectById(Parent.class, pId);
 62    Assert.assertEquals(pId, p.getId());
 63    Assert.assertEquals("Parent", p.getParentStr());
 64    startEnd.end();
 65
 66    //	create Child11
 67    Child11 c11 = newChild11(startEnd, "Child11", 11);
 68    Long c11Id = c11.getId();
 69    Key c11Key = KeyFactory.createKey(PARENT_KIND, c11Id);
 70    
 71    //	verify Child11 entity
 72    Entity c11e = ds.get(c11Key);
 73    Assert.assertEquals(c11Key, c11e.getKey());
 74    Assert.assertEquals("C11", c11e.getProperty("DISCRIMINATOR"));
 75    Assert.assertEquals("Child11", c11e.getProperty("parentStr"));
 76    Assert.assertEquals(11, ((Long) c11e.getProperty("child11Integer")).intValue());
 77    Assert.assertTrue(c11e.hasProperty("child11Manys"));
 78    Assert.assertNull(c11e.getProperty("child11Manys"));
 79    Assert.assertEquals(4, c11e.getProperties().size());
 80    
 81    //	verify Child11 object
 82    startEnd.start();
 83    c11 = pm.getObjectById(Child11.class, c11Id);
 84    Assert.assertEquals(c11Id, c11.getId());
 85    Assert.assertEquals("Child11", c11.getParentStr());
 86    Assert.assertEquals(new Integer(11), c11.getChild11Integer());
 87    Assert.assertTrue(c11.getChild11Manys().isEmpty());
 88    startEnd.end();
 89
 90    //	create Child12
 91    Child11Many c12m = new Child11Many("Child11ManyStr");
 92    Child12 c12 = newChild12(startEnd, "Child12", null, 112, null, new Embedded1("Child12Embedded1"), c12m);
 93    Long c12Id = c12.getId();
 94    String c12mId = c12m.getId();
 95    Key c12Key = KeyFactory.createKey(PARENT_KIND, c12Id);
 96    
 97    //	verify Child12 entity
 98    Entity c12e = ds.get(c12Key);
 99    Assert.assertEquals(c12Key, c12e.getKey());
100    Assert.assertEquals("C12", c12e.getProperty("DISCRIMINATOR"));
101    Assert.assertEquals("Child12", c12e.getProperty("parentStr"));
102    Assert.assertTrue(c12e.hasProperty("child11Integer"));
103    Assert.assertNull(c12e.getProperty("child11Integer"));
104    Assert.assertEquals(112, ((Long) c12e.getProperty("child12Int")).intValue());
105    Assert.assertTrue(c12e.hasProperty("value"));
106    Assert.assertEquals(0d, c12e.getProperty("value"));
107    Assert.assertEquals("Child12Embedded1", c12e.getProperty("string"));
108    Assert.assertTrue(c12e.hasProperty("child11Manys"));
109    Assert.assertEquals(1, ((List<Key>)c12e.getProperty("child11Manys")).size());
110    Assert.assertEquals(KeyFactory.stringToKey(c12mId), ((List<Key>)c12e.getProperty("child11Manys")).get(0));
111    Assert.assertEquals(7, c12e.getProperties().size());
112    
113    //	verify Child12 object
114    startEnd.start();
115    c12 = pm.getObjectById(Child12.class, c12Id);
116    Assert.assertEquals(c12Id, c12.getId());
117    Assert.assertEquals("Child12", c12.getParentStr());
118    Assert.assertNull(c12.getChild11Integer());
119    Assert.assertEquals(112, c12.getChild12Int());
120    Assert.assertNotNull(c12.getEmbedded1());
121    Assert.assertEquals("Child12Embedded1", c12.getEmbedded1().getStr());
122    Assert.assertNotNull(c12.getChild11Manys());
123    Assert.assertEquals(1, c12.getChild11Manys().size());
124    Assert.assertEquals("Child11ManyStr", c12.getChild11Manys().get(0).getStr());
125    startEnd.end();
126    
127    //	create Child21
128    Child21 c21 = newChild21(startEnd, null, 21L);    
129    Long c21Id = c21.getId();
130    Key c21Key = KeyFactory.createKey(PARENT_KIND, c21Id);
131    
132    //	verify Child21 entity
133    Entity c21e = ds.get(c21Key);
134    Assert.assertEquals(c21Key, c21e.getKey());
135    Assert.assertEquals("C21", c21e.getProperty("DISCRIMINATOR"));
136    Assert.assertTrue(c21e.hasProperty("parentStr"));
137    Assert.assertNull(c21e.getProperty("parentStr"));
138    Assert.assertEquals(21L, c21e.getProperty("child21Long"));
139    Assert.assertTrue(c21e.hasProperty("str"));
140    Assert.assertNull(c21e.getProperty("str"));
141    Assert.assertTrue(c21e.hasProperty("dbl"));
142    Assert.assertNull(c21e.getProperty("dbl"));
143    Assert.assertEquals(5, c21e.getProperties().size());
144
145    //	verify Child21 object
146    startEnd.start();
147    c21 = pm.getObjectById(Child21.class, c21Id);
148    Assert.assertEquals(c21Id, c21.getId());
149    Assert.assertEquals(21L, c21.getChild21Long());
150    Assert.assertNull(c21.getParentStr());
151    startEnd.end();
152
153    //	create Child22
154    Child22 c22 = newChild22(startEnd, "ParentChild22", "Child22", Boolean.TRUE, new Embedded2("Embedded2Child22", -7d));
155    Long c22Id = c22.getId();
156    Key c22Key = KeyFactory.createKey(PARENT_KIND, c22Id);
157
158    //	verify Child22 entity
159    Entity c22e = ds.get(c22Key);
160    Assert.assertEquals(c22Key, c22e.getKey());    
161    Assert.assertEquals("C22", c22e.getProperty("DISCRIMINATOR"));
162    Assert.assertEquals("ParentChild22", c22e.getProperty("parentStr"));
163    Assert.assertEquals("Child22", c22e.getProperty("child22Str"));
164    Assert.assertEquals(0L, c22e.getProperty("child21Long"));
165    Assert.assertEquals(Boolean.TRUE, c22e.getProperty("value_0"));
166    Assert.assertEquals(new Text("Embedded2Child22"), c22e.getProperty("str"));
167    Assert.assertEquals(-7d, c22e.getProperty("dbl"));
168    Assert.assertEquals(7, c22e.getProperties().size());
169
170    //	verify Child22 object
171    startEnd.start();
172    c22 = pm.getObjectById(Child22.class, c22Id);
173    Assert.assertEquals(c22Id, c22.getId());
174    Assert.assertEquals("ParentChild22", c22.getParentStr());
175    Assert.assertEquals(0L, c22.getChild21Long());
176    Assert.assertEquals("Child22", c22.getChild22Str());
177    startEnd.end();
178    
179    Assert.assertEquals(5, countForKind(PARENT_KIND));
180  }
181  
182  public void testQueryParent() {
183    Map<String, String> props = new HashMap<String, String>();
184    props.put("datanucleus.appengine.getExtentCanReturnSubclasses", Boolean.TRUE.toString());
185    switchDatasource(PersistenceManagerFactoryName.transactional, props);
186    testQueryParent(TXN_START_END);
187  }
188  public void testQueryParent_NoTxn() {
189    Map<String, String> props = new HashMap<String, String>();
190    props.put("datanucleus.appengine.getExtentCanReturnSubclasses", Boolean.TRUE.toString());
191    switchDatasource(PersistenceManagerFactoryName.nontransactional, props);
192    testQueryParent(NEW_PM_START_END);
193  }
194  @SuppressWarnings("unchecked")
195  private void testQueryParent(StartEnd startEnd) {
196    Parent p = newParent(startEnd, "Parent");
197    Long pId = p.getId();
198
199    newChild21(startEnd, null, 21L);
200    
201    startEnd.start();
202    Query q = pm.newQuery("select from " + Parent.class.getName() + " where id == :id");
203    List<Parent> r = (List<Parent>)q.execute(pId);
204    Assert.assertEquals(1, r.size());
205    p = r.get(0);
206    Assert.assertEquals(pId, p.getId());
207    Assert.assertEquals("Parent", p.getParentStr());
208    startEnd.end();
209    
210    startEnd.start();
211    Extent<Parent> e = pm.getExtent(Parent.class, true);
212    q = pm.newQuery(e);
213    r = (List<Parent>)q.execute();
214    Assert.assertEquals(2, r.size());
215    startEnd.end();
216
217  }
218  public void testUpdateDependent() throws Exception {
219    testUpdateDependent(TXN_START_END);
220  }
221  public void testUpdateDependent_NoTxn() throws Exception {
222    switchDatasource(PersistenceManagerFactoryName.nontransactional);
223    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
224    testUpdateDependent(NEW_PM_START_END);
225  }
226  @SuppressWarnings("unchecked")
227  private void testUpdateDependent(StartEnd startEnd) throws Exception {
228    //	create Child12
229    Child12 c12_0 = newChild12(startEnd, null, null, 12, null, new Embedded1("Child12Embedded1(1)"));
230    Long c12_0Id = c12_0.getId();
231    Key c12_0key = KeyFactory.createKey(PARENT_KIND, c12_0Id);
232    
233    //	add a Child11Many to Child12
234    startEnd.start();
235    c12_0 = pm.getObjectById(Child12.class, c12_0Id);
236    Assert.assertTrue(c12_0.getChild11Manys().isEmpty());
237    Child11Many c12m_0 = new Child11Many("Child12Embedded1(1)/Child11ManyStr(1)");
238    c12_0.getChild11Manys().add(c12m_0);
239    startEnd.end();
240    String c12m_0Id = c12m_0.getId();
241    
242    // more objects to prove we update and delete the correct one
243    Child12 c12_1 = newChild12(startEnd, null, null, 121, null, new Embedded1("Child12Embedded1(2)"));
244    Long c12_1Id = c12_1.getId();
245    startEnd.start();
246    c12_1 = pm.getObjectById(Child12.class, c12_1Id);
247    c12_1.getChild11Manys().add(new Child11Many("Child12Embedded1(2)/Child11ManyStr(1)"));
248    startEnd.end();
249    
250    Assert.assertEquals(2, countForKind(PARENT_KIND));
251    Assert.assertEquals(2, countForClass(Child11Many.class));
252    
253    //	check the key of  Child11Many in the Entity
254    Entity c12e = ds.get(c12_0key);
255    Assert.assertEquals(KeyFactory.stringToKey(c12m_0Id), ((List<Key>)c12e.getProperty("child11Manys")).get(0));
256    
257    startEnd.start();
258    Query q = pm.newQuery();
259    q.setIgnoreCache(true);
260    q.setClass(Child12.class);
261    q.setRange(0, 1);
262    List<Child11> r = (List<Child11>)q.execute();
263    Assert.assertEquals(1, r.size());
264    Child11Many c12m_1 = new Child11Many("Child12Embedded1(1)/Child11ManyStr(2)");
265    r.get(0).getChild11Manys().add(c12m_1);
266    startEnd.end();
267    String c12m_1Id = c12m_1.getId();
268    
269    Assert.assertEquals(2, countForKind(PARENT_KIND));
270    Assert.assertEquals(3, countForClass(Child11Many.class));
271
272    c12e = ds.get(c12_0key);
273    Assert.assertEquals(KeyFactory.stringToKey(c12m_0Id), ((List<Key>)c12e.getProperty("child11Manys")).get(0));
274    Assert.assertEquals(KeyFactory.stringToKey(c12m_1Id), ((List<Key>)c12e.getProperty("child11Manys")).get(1));
275    
276    startEnd.start();
277    c12_0 = (Child12)pm.getObjectById(Child12.class, c12_0Id);
278    c12_0.getChild11Manys().remove(0);
279    startEnd.end();
280
281    c12e = ds.get(c12_0key);
282    Assert.assertEquals(1, ((List<Key>)c12e.getProperty("child11Manys")).size());
283    Assert.assertEquals(KeyFactory.stringToKey(c12m_1Id), ((List<Key>)c12e.getProperty("child11Manys")).get(0));
284    
285    Assert.assertEquals(2, countForKind(PARENT_KIND));
286    Assert.assertEquals(2, countForClass(Child11Many.class));
287    
288    startEnd.start();
289    pm.deletePersistent(pm.getObjectById(Child12.class, c12_0Id));
290    startEnd.end();
291
292    Assert.assertEquals(1, countForClass(Child11Many.class));
293    Assert.assertEquals(1, countForKind(PARENT_KIND));
294  }
295  
296  public void testQueryChildren() {
297    testQueryChildren(TXN_START_END);
298  }
299  public void testQueryChildren_NoTxn() {
300    switchDatasource(PersistenceManagerFactoryName.nontransactional);
301    testQueryChildren(NEW_PM_START_END);
302  }
303  @SuppressWarnings("unchecked")
304  private void testQueryChildren(StartEnd startEnd) {
305    Child11 c11_0 = newChild11(startEnd, "Child11", 11);
306    Long c11Id = c11_0.getId();
307    
308    Child12 c12_0 = newChild12(startEnd, "Child12", 111, 112, null, new Embedded1("Child12Embedded1"));
309    Long c12_0Id = c12_0.getId();
310
311    newChild12(startEnd, "Child12", 111, 112, null, null);
312
313    startEnd.start();
314    Query q = pm.newQuery("select from " + Parent.class.getName() + " where id == :id");
315    List<Child11> r11 = (List<Child11>)q.execute(c11Id);
316    Assert.assertEquals(1, r11.size());
317    c11_0 = r11.get(0);
318    Assert.assertEquals(c11Id, c11_0.getId());
319    Assert.assertEquals("Child11", c11_0.getParentStr());
320    Assert.assertEquals(new Integer(11), c11_0.getChild11Integer());
321    startEnd.end();
322    
323    startEnd.start();
324    q = pm.newQuery("select from " + Child11.class.getName() + " where child12Int > 0");
325    q.addExtension(DatastoreManager.QUERYEXT_INMEMORY_WHEN_UNSUPPORTED, "false");
326    try {
327      q.execute();
328      fail("expected JDOFatalUserException");
329    } catch (JDOFatalUserException ex) {
330      // good Child11 does not have a property child12Int
331    } finally {
332      startEnd.end();
333    }
334
335    startEnd.start();
336    q = pm.newQuery("select from " + Child12.class.getName() + " where embedded1.str == :str");
337    List<Child12> r12 = (List<Child12>)q.execute("Child12Embedded1");
338    Assert.assertEquals(1, r12.size());
339    c12_0 = r12.get(0);
340    Assert.assertEquals(c12_0Id, c12_0.getId());
341    Assert.assertEquals("Child12Embedded1", c12_0.getEmbedded1().getStr());
342    startEnd.end();
343    
344    startEnd.start();
345    q = pm.newQuery("select from " + Child11.class.getName() + " where parentStr == :str");
346    r11 = (List<Child11>)q.execute("Child12");
347    Assert.assertEquals(2, r11.size());
348    startEnd.end();
349    
350    startEnd.start();
351    q = pm.newQuery("select from " + Child12.class.getName() + " where parentStr == :parentStr && embedded1.str == :str");
352    r12 = (List<Child12>)q.execute("Child12", "Child12Embedded1");
353    Assert.assertEquals(1, r12.size());
354    startEnd.end();
355  }
356  
357  public void testQueryParentAndChildren() {
358    testQueryParentAndChildren(TXN_START_END);
359  }
360  public void testQueryParentAndChildren_NoTxn() {
361    switchDatasource(PersistenceManagerFactoryName.nontransactional);
362    testQueryParentAndChildren(NEW_PM_START_END);
363  }
364  @SuppressWarnings("unchecked")
365  private void testQueryParentAndChildren(StartEnd startEnd) {
366    Child11 c11 = newChild11(startEnd, "A", 111);
367    Long c11Id = c11.getId();
368
369    Child12 c12 = newChild12(startEnd, "B", 112, 211, 8.15f, null);
370    Long c12Id = c12.getId();
371    
372    Parent p = newParent(startEnd, "C");
373    Long pId = p.getId();
374
375    Child21 c21 = newChild21(startEnd, "D", 121L);
376    Long c21Id = c21.getId();
377
378    Child22 c22 = newChild22(startEnd, "E", "Child22", Boolean.TRUE, null);
379    Long c22Id = c22.getId();
380    
381    Assert.assertEquals(5, countForKind(PARENT_KIND));
382    
383    startEnd.start();
384    Query q = pm.newQuery("select from " + Parent.class.getName() + " order by parentStr desc");
385    q.setIgnoreCache(true);
386    List<Parent> r = (List<Parent>)q.execute();
387    Assert.assertEquals(5, r.size());
388
389    c22 = (Child22)r.get(0);
390    Assert.assertEquals(c22Id, c22.getId());
391    Assert.assertEquals("E", c22.getParentStr());
392    Assert.assertEquals("Child22", c22.getChild22Str());
393    Assert.assertEquals(Boolean.TRUE, c22.getValue());
394
395    c21 = (Child21)r.get(1);
396    Assert.assertEquals(c21Id, c21.getId());
397    Assert.assertEquals("D", c21.getParentStr());
398    Assert.assertEquals(121L, c21.getChild21Long());
399
400    p = r.get(2);
401    Assert.assertEquals(pId, p.getId());
402    Assert.assertEquals("C", p.getParentStr());
403    
404    c12 = (Child12)r.get(3);
405    Assert.assertEquals(c12Id, c12.getId());
406    Assert.assertEquals("B", c12.getParentStr());
407    Assert.assertEquals(new Integer(112), c12.getChild11Integer());
408    Assert.assertEquals(211, c12.getChild12Int());
409    Assert.assertEquals(8.15f, c12.getValue());
410
411    c11 = (Child11)r.get(4);
412    Assert.assertEquals(c11Id, c11.getId());
413    Assert.assertEquals("A", c11.getParentStr());
414    Assert.assertEquals(new Integer(111), c11.getChild11Integer());
415    startEnd.end();
416    
417    startEnd.start();
418    q = pm.newQuery("select from " + Child11.class.getName() + " where child11Integer >= 111");
419    r = (List<Parent>)q.execute();
420    Assert.assertEquals(2, r.size());
421    startEnd.end();
422    
423    startEnd.start();
424    q = pm.newQuery("select from " + Child12.class.getName() + " where value >= 8.0");
425    r = (List<Parent>)q.execute();
426    Assert.assertEquals(1, r.size());
427    Assert.assertEquals(c12Id, r.get(0).getId());
428    startEnd.end();
429    
430    startEnd.start();
431    q = pm.newQuery("select from " + Child22.class.getName() + " where value == true");
432    r = (List<Parent>)q.execute();
433    Assert.assertEquals(1, r.size());
434    Assert.assertEquals(c22Id, r.get(0).getId());
435    startEnd.end();
436  }
437
438  public void testQueryHierarchy()throws Exception {
439    testQueryHierarchy(TXN_START_END);
440  }
441  public void testQueryHierarchy_NoTxn() throws Exception{
442    switchDatasource(PersistenceManagerFactoryName.nontransactional);
443    testQueryHierarchy(NEW_PM_START_END);
444  }
445  @SuppressWarnings("unchecked")
446  private void testQueryHierarchy(StartEnd startEnd) throws Exception {
447    
448    Child11 c11 = newChild11(startEnd, "A", 111);
449    Long c11Id = c11.getId();
450
451    Child12 c12 = newChild12(startEnd, "A", 211, 112, 8.15f, null);
452    Long c12Id = c12.getId();
453
454    Parent p = newParent(startEnd, "A");
455    Long pId = p.getId();
456
457    c12 = newChild12(startEnd, "B", 2211, 2112, 47.11f, null);
458
459    switchDatasource(PersistenceManagerFactoryName.nontransactional);
460    
461    Query q = pm.newQuery("select from " + Parent.class.getName() + " where parentStr == 'A'");
462    q.setIgnoreCache(true);
463    List<Parent> r = (List<Parent>)q.execute();
464    Assert.assertEquals(3, r.size());
465    Set<Long> ids = new HashSet<Long>(Arrays.asList(new Long[] {c11Id, c12Id, pId}));
466    for(Parent rp : r) {
467      Assert.assertTrue(ids.remove(rp.getId()));
468    }
469    
470    q = pm.newQuery("select from " + Child11.class.getName() + " where parentStr == 'A' && child11Integer > 110");
471    r = (List<Parent>)q.execute();
472    Assert.assertEquals(2, r.size());
473    ids = new HashSet<Long>(Arrays.asList(new Long[] {c11Id, c12Id}));
474    for(Parent rp : r) {
475      Assert.assertTrue(ids.remove(rp.getId()));
476    }
477
478    q = pm.newQuery("select from " + Child12.class.getName() + " where parentStr == 'A'");
479    r = (List<Parent>)q.execute();
480    Assert.assertEquals(1, r.size());
481    Assert.assertEquals(c12Id, r.get(0).getId());
482  }
483
484  public void testUpdateAndDeleteParentAndChilds() throws Exception {
485    testUpdateAndDeleteParentAndChilds(TXN_START_END);
486  }
487  public void testUpdateAndDeleteParentAndChilds_NoTxn() throws Exception {
488    switchDatasource(PersistenceManagerFactoryName.nontransactional);
489    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
490    testUpdateAndDeleteParentAndChilds(NEW_PM_START_END);
491  }
492  private void testUpdateAndDeleteParentAndChilds(StartEnd startEnd) throws Exception {
493    Child11 c11 = newChild11(startEnd, "Parent", 211);
494    Long c11Id = c11.getId();
495    Key c11Key = KeyFactory.createKey(PARENT_KIND, c11.getId());
496    
497    startEnd.start();
498    c11 = (Child11) pm.getObjectById(Child11.class, c11Id);
499    Assert.assertEquals(c11Id, c11.getId());
500    Assert.assertEquals("Parent", c11.getParentStr());
501    c11.setParentStr("Child22");
502    startEnd.end();
503    
504    verifyDiscriminator(c11Id, "C11");
505    Entity c11e = ds.get(c11Key);
506    Assert.assertEquals("Child22", c11e.getProperty("parentStr"));
507    
508    startEnd.start();
509    c11 = (Child11) pm.getObjectById(Child11.class, c11Id);
510    Assert.assertEquals("Child22", c11.getParentStr());
511    Assert.assertEquals(new Integer(211), c11.getChild11Integer());
512    startEnd.end();
513
514    Child12 c12 = newChild12(startEnd, null, null, 0, null, null);
515    Long c12Id = c12.getId();
516
517    Assert.assertEquals(2, countForKind(PARENT_KIND));
518
519    startEnd.start();
520    pm.deletePersistent(pm.getObjectById(Child11.class, c11Id));
521    startEnd.end();
522    
523    Assert.assertEquals(1, countForKind(PARENT_KIND));
524    
525    startEnd.start();
526    c12 = (Child12) pm.getObjectById(Child12.class, c12Id);
527    Assert.assertEquals(c12Id, c12.getId());
528    
529    startEnd.end();
530  }
531  
532  public void testCreateIntDiscriminator() throws Exception {
533    testCreateIntDiscriminator(TXN_START_END);
534  }
535  public void testCreateIntDiscriminator_NoTxn() throws Exception {
536    switchDatasource(PersistenceManagerFactoryName.nontransactional);
537    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
538    testCreateIntDiscriminator(NEW_PM_START_END);
539  }
540  private void testCreateIntDiscriminator(StartEnd startEnd) throws Exception {
541    ParentIntDiscriminator p = new ParentIntDiscriminator();
542    p.setParentStr("ParentInt");
543    makePersistentInTxn(p, startEnd);
544    
545    String pId = p.getId();
546    Key pKey = KeyFactory.stringToKey(pId);
547    Entity pe = ds.get(pKey);
548    
549    Assert.assertEquals(pKey, pe.getKey());
550    Assert.assertEquals(1L, pe.getProperty("type"));  
551    Assert.assertEquals("ParentInt", pe.getProperty("parentStr"));
552    Assert.assertEquals(2, pe.getProperties().size());
553    
554    long now = System.currentTimeMillis();
555    ChildDateIntDiscriminator cd = new ChildDateIntDiscriminator();
556    cd.setParentStr("ChildDateInt");
557    cd.setValue(new Date(now));
558    makePersistentInTxn(cd, startEnd);
559    
560    String cdId = cd.getId();
561    Key cdKey = KeyFactory.stringToKey(cdId);
562    Entity cde = ds.get(cdKey);
563    
564    Assert.assertEquals(cdKey, cde.getKey());
565    Assert.assertEquals(2L, cde.getProperty("type"));  
566    Assert.assertEquals("ChildDateInt", cde.getProperty("parentStr"));
567    Assert.assertEquals(now, ((Date)cde.getProperty("date")).getTime());  
568    Assert.assertEquals(3, cde.getProperties().size());
569    
570    ChildBoolIntDiscriminator cb = new ChildBoolIntDiscriminator();
571    cb.setParentStr("ChildBoolInt");
572    cb.setValue(Boolean.TRUE);
573    makePersistentInTxn(cb, startEnd);
574    
575    String cbId = cb.getId();
576    Key cbKey = KeyFactory.stringToKey(cbId);
577    Entity cbe = ds.get(cbKey);
578    
579    Assert.assertEquals(cbKey, cbe.getKey());
580    Assert.assertEquals(3L, cbe.getProperty("type"));  
581    Assert.assertEquals("ChildBoolInt", cbe.getProperty("parentStr"));
582    Assert.assertEquals(Boolean.TRUE, cbe.getProperty("bool"));  
583    Assert.assertEquals(3, cbe.getProperties().size());
584    
585    Assert.assertEquals(3, countForKind(PARENTINT_KIND));
586  }
587  
588  public void testQueryIntDiscriminator() throws Exception {
589    testQueryIntDiscriminator(TXN_START_END);
590  }
591  public void testQueryIntDiscriminator_NoTxn() throws Exception {
592    switchDatasource(PersistenceManagerFactoryName.nontransactional);
593    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
594    testQueryIntDiscriminator(NEW_PM_START_END);
595  }
596  @SuppressWarnings("unchecked")
597  private void testQueryIntDiscriminator(StartEnd startEnd) throws Exception {
598    ChildDateIntDiscriminator cd = new ChildDateIntDiscriminator();
599    cd.setParentStr("A");
600    cd.setValue(new Date());
601    makePersistentInTxn(cd, startEnd);
602    String cdId = cd.getId();
603
604    ChildBoolIntDiscriminator cb = new ChildBoolIntDiscriminator();
605    cb.setParentStr("C");
606    cb.setValue(Boolean.TRUE);
607    makePersistentInTxn(cb, startEnd);
608    String cbId = cb.getId();
609    
610    ParentIntDiscriminator p = new ParentIntDiscriminator();
611    p.setParentStr("B");
612    makePersistentInTxn(p, startEnd);
613    String pId = p.getId();
614
615    startEnd.start();
616    Query q = pm.newQuery("select from " + ParentIntDiscriminator.class.getName() + " order by parentStr");
617    List<ParentIntDiscriminator> r = (List<ParentIntDiscriminator>)q.execute();
618    Assert.assertEquals(3, r.size());
619    
620    Assert.assertEquals(cdId, r.get(0).getId());
621    Assert.assertTrue(r.get(0) instanceof ChildDateIntDiscriminator);
622    Assert.assertEquals(pId, r.get(1).getId());
623    Assert.assertTrue(r.get(1) instanceof ParentIntDiscriminator);
624    Assert.assertEquals(cbId, r.get(2).getId());
625    Assert.assertTrue(r.get(2) instanceof ChildBoolIntDiscriminator);
626    startEnd.end();
627  }
628  
629  public void testUpdateIntDiscriminator() throws Exception {
630    testUpdateIntDiscriminator(TXN_START_END);
631  }
632  public void testUpdateIntDiscriminator_NoTxn() throws Exception {
633    switchDatasource(PersistenceManagerFactoryName.nontransactional);
634    getExecutionContext().setProperty(PROP_DETACH_ON_CLOSE, true);
635    testUpdateIntDiscriminator(NEW_PM_START_END);
636  }
637  public void testUpdateIntDiscriminator(StartEnd startEnd) throws Exception {
638    ParentIntDiscriminator p = new ParentIntDiscriminator();
639    p.setParentStr("ParentInt");
640    makePersistentInTxn(p, startEnd);
641    
642    String pId = p.getId();
643    Key pKey = KeyFactory.stringToKey(pId);
644    Assert.assertEquals(PARENTINT_KIND, pKey.getKind());
645    
646    Entity pe = ds.get(pKey);
647    Assert.assertEquals(pKey, pe.getKey());
648    Assert.assertEquals(1L, pe.getProperty("type"));  
649    Assert.assertEquals("ParentInt", pe.getProperty("parentStr"));
650    Assert.assertEquals(2, pe.getProperties().size());
651
652    startEnd.start();
653    p = pm.getObjectById(ParentIntDiscriminator.class, pId);
654    p.setParentStr("ParentInt(2)");
655    startEnd.end();
656    
657    pe = ds.get(pKey);
658    Assert.assertEquals(pKey, pe.getKey());
659    Assert.assertEquals(1L, pe.getProperty("type"));  
660    Assert.assertEquals("ParentInt(2)", pe.getProperty("parentStr"));
661    Assert.assertEquals(2, pe.getProperties().size());
662    
663    startEnd.start();
664    p = pm.getObjectById(ParentIntDiscriminator.class, pId);
665    Assert.assertEquals("ParentInt(2)", p.getParentStr());
666    startEnd.end();
667    
668    Assert.assertEquals(1, countForKind(PARENTINT_KIND));
669    
670    startEnd.start();
671    pm.deletePersistent(pm.getObjectById(ParentIntDiscriminator.class, pId));
672    startEnd.end();
673
674    Assert.assertEquals(0, countForKind(PARENTINT_KIND));
675  }
676  
677  public void testMissingDiscriminator() {
678    beginTxn();
679    try {
680      pm.makePersistent(new ChildToParentWithoutDiscriminator());
681      commitTxn();
682      fail("expected exeception");
683    } catch (Exception e) {
684      // good
685    }
686  }
687
688  public void testMissingDiscriminator_NoTxn() {
689    switchDatasource(PersistenceManagerFactoryName.nontransactional);
690    try {
691      pm.makePersistent(new ChildToParentWithoutDiscriminator());
692      pm.close();
693      fail("expected exeception");
694    } catch (Exception e) {
695      // good
696    }
697  }
698
699  private Parent newParent(StartEnd startEnd, String parentStr) {
700    Parent p = new Parent();
701    p.setParentStr(parentStr);
702    makePersistentInTxn(p, startEnd);
703    return p;
704  }
705  
706  private Child11 newChild11(StartEnd startEnd, String parentStr, int child11Int) {
707    Child11 c11 = new Child11();
708    c11.setParentStr(parentStr);
709    c11.setChild11Integer(child11Int);
710    makePersistentInTxn(c11, startEnd);
711    return c11;
712  }
713  
714  private Child12 newChild12(StartEnd startEnd, String parentStr, Integer child11Integer, int child12Int, Float value, Embedded1 embedded1, Child11Many... child11Many) {
715    Child12 c12 = new Child12();
716    c12.setParentStr(parentStr);
717    c12.setChild11Integer(child11Integer);
718    c12.setChild12Int(child12Int);
719    c12.setEmbedded1(embedded1);
720    if (value != null) {
721      c12.setValue(value);
722    }
723    if (child11Many != null) {
724      for (Child11Many c : child11Many) {
725        c12.getChild11Manys().add(c);
726      }
727    }
728    makePersistentInTxn(c12, startEnd);
729    return c12;
730  }
731  
732  private Child21 newChild21(StartEnd startEnd, String parentStr, Long child21Long) {
733    Child21 c21 = new Child21();
734    c21.setParentStr(parentStr);
735    c21.setChild21Long(child21Long);
736    makePersistentInTxn(c21, startEnd);
737    return c21;
738  }
739  
740  private Child22 newChild22(StartEnd startEnd, String parentStr, String child22Str, Boolean value, Embedded2 embedded2) {
741    Child22 c22 = new Child22();
742    c22.setParentStr(parentStr);
743    c22.setChild22Str("Child22");
744    c22.setEmbedded2(embedded2);
745    c22.setValue(value);
746    makePersistentInTxn(c22, startEnd);
747    return c22;
748  }
749  
750  private void verifyDiscriminator(Long id, String expectedDiscriminator) throws Exception {
751    Entity entity = ds.get(KeyFactory.createKey(PARENT_KIND, id));
752    Assert.assertEquals(expectedDiscriminator, entity.getProperty("DISCRIMINATOR"));
753  }
754
755  @SuppressWarnings("deprecation")
756  private int countForKind(String kind) {
757    return ds.prepare(
758        new com.google.appengine.api.datastore.Query(kind)).countEntities();
759  }
760}