1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2000, 2013 Oracle and/or its affiliates.  All rights reserved.
5  *
6  */
7 package com.sleepycat.persist.test;
8 
9 import static com.sleepycat.persist.model.Relationship.MANY_TO_ONE;
10 import static com.sleepycat.persist.model.Relationship.ONE_TO_ONE;
11 
12 import java.math.BigInteger;
13 import java.util.ArrayList;
14 import java.util.Collections;
15 import java.util.HashMap;
16 import java.util.Map;
17 import java.util.StringTokenizer;
18 
19 import junit.framework.TestCase;
20 
21 import com.sleepycat.db.DatabaseException;
22 import com.sleepycat.db.Environment;
23 import com.sleepycat.persist.EntityStore;
24 import com.sleepycat.persist.PrimaryIndex;
25 import com.sleepycat.persist.SecondaryIndex;
26 import com.sleepycat.persist.StoreConfig;
27 import com.sleepycat.persist.evolve.Conversion;
28 import com.sleepycat.persist.evolve.Converter;
29 import com.sleepycat.persist.evolve.Deleter;
30 import com.sleepycat.persist.evolve.EntityConverter;
31 import com.sleepycat.persist.evolve.Mutations;
32 import com.sleepycat.persist.evolve.Renamer;
33 import com.sleepycat.persist.model.Entity;
34 import com.sleepycat.persist.model.EntityModel;
35 import com.sleepycat.persist.model.KeyField;
36 import com.sleepycat.persist.model.Persistent;
37 import com.sleepycat.persist.model.PersistentProxy;
38 import com.sleepycat.persist.model.PrimaryKey;
39 import com.sleepycat.persist.model.SecondaryKey;
40 import com.sleepycat.persist.raw.RawObject;
41 import com.sleepycat.persist.raw.RawStore;
42 import com.sleepycat.persist.raw.RawType;
43 
44 /**
45  * Nested classes are modified versions of classes of the same name in
46  * EvolveClasses.java.original.  See EvolveTestBase.java for the steps that are
47  * taken to add a new class (test case).
48  *
49  * @author Mark Hayes
50  */
51 class EvolveClasses {
52 
53     private static final String PREFIX = EvolveClasses.class.getName() + '$';
54     private static final String CASECLS = EvolveCase.class.getName();
55 
readRaw(RawStore store, Object key, Object... classVersionPairs)56     private static RawObject readRaw(RawStore store,
57                                      Object key,
58                                      Object... classVersionPairs)
59         throws DatabaseException {
60 
61         return readRaw(store, null, key, classVersionPairs);
62     }
63 
64     /**
65      * Reads a raw object and checks its superclass names and versions.
66      */
readRaw(RawStore store, String entityClsName, Object key, Object... classVersionPairs)67     private static RawObject readRaw(RawStore store,
68                                      String entityClsName,
69                                      Object key,
70                                      Object... classVersionPairs)
71         throws DatabaseException {
72 
73         TestCase.assertNotNull(store);
74         TestCase.assertNotNull(key);
75 
76         if (entityClsName == null) {
77             entityClsName = (String) classVersionPairs[0];
78         }
79         PrimaryIndex<Object, RawObject> index =
80             store.getPrimaryIndex(entityClsName);
81         TestCase.assertNotNull(index);
82 
83         RawObject obj = index.get(key);
84         TestCase.assertNotNull(obj);
85 
86         checkRawType(obj.getType(), classVersionPairs);
87 
88         RawObject superObj = obj.getSuper();
89         for (int i = 2; i < classVersionPairs.length; i += 2) {
90             Object[] a = new Object[classVersionPairs.length - i];
91             System.arraycopy(classVersionPairs, i, a, 0, a.length);
92             TestCase.assertNotNull(superObj);
93             checkRawType(superObj.getType(), a);
94             superObj = superObj.getSuper();
95         }
96 
97         return obj;
98     }
99 
100     /**
101      * Reads a raw object and checks its superclass names and versions.
102      */
checkRawType(RawType type, Object... classVersionPairs)103     private static void checkRawType(RawType type,
104                                      Object... classVersionPairs) {
105         TestCase.assertNotNull(type);
106         TestCase.assertNotNull(classVersionPairs);
107         TestCase.assertTrue(classVersionPairs.length % 2 == 0);
108 
109         for (int i = 0; i < classVersionPairs.length; i += 2) {
110             String clsName = (String) classVersionPairs[i];
111             int clsVersion = (Integer) classVersionPairs[i + 1];
112             TestCase.assertEquals(clsName, type.getClassName());
113             TestCase.assertEquals(clsVersion, type.getVersion());
114             type = type.getSuperType();
115         }
116         TestCase.assertNull(type);
117     }
118 
119     /**
120      * Checks that a raw object contains the specified field values.  Does not
121      * check superclass fields.
122      */
checkRawFields(RawObject obj, Object... nameValuePairs)123     private static void checkRawFields(RawObject obj,
124                                        Object... nameValuePairs) {
125         TestCase.assertNotNull(obj);
126         TestCase.assertNotNull(obj.getValues());
127         TestCase.assertNotNull(nameValuePairs);
128         TestCase.assertTrue(nameValuePairs.length % 2 == 0);
129 
130         Map<String, Object> values = obj.getValues();
131         TestCase.assertEquals(nameValuePairs.length / 2, values.size());
132 
133         for (int i = 0; i < nameValuePairs.length; i += 2) {
134             String name = (String) nameValuePairs[i];
135             Object value = nameValuePairs[i + 1];
136             TestCase.assertEquals(name, value, values.get(name));
137         }
138     }
139 
makeValues(Object... nameValuePairs)140     private static Map<String, Object> makeValues(Object... nameValuePairs) {
141         TestCase.assertTrue(nameValuePairs.length % 2 == 0);
142         Map<String, Object> values = new HashMap<String, Object>();
143         for (int i = 0; i < nameValuePairs.length; i += 2) {
144             values.put((String) nameValuePairs[i], nameValuePairs[i + 1]);
145         }
146         return values;
147     }
148 
149     /**
150      * Disallow removing an entity class when no Deleter mutation is specified.
151      */
152     static class DeletedEntity1_ClassRemoved_NoMutation extends EvolveCase {
153 
154         private static final String NAME =
155             PREFIX + "DeletedEntity1_ClassRemoved";
156 
157         @Override
getStoreOpenException()158         public String getStoreOpenException() {
159             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DeletedEntity1_ClassRemoved version: 0 Error: java.lang.ClassNotFoundException: com.sleepycat.persist.test.EvolveClasses$DeletedEntity1_ClassRemoved";
160         }
161 
162         @Override
checkUnevolvedModel(EntityModel model, Environment env)163         void checkUnevolvedModel(EntityModel model, Environment env) {
164             checkEntity(true, model, env, NAME, 0, "skey");
165             checkVersions(model, NAME, 0);
166         }
167 
168         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)169         void readRawObjects(RawStore store,
170                             boolean expectEvolved,
171                             boolean expectUpdated)
172             throws DatabaseException {
173 
174             if (expectEvolved) {
175                 TestCase.fail();
176             }
177             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
178             checkRawFields(obj, "key", 99, "skey", 88);
179         }
180     }
181 
182     /**
183      * Allow removing an entity class when a Deleter mutation is specified.
184      */
185     static class DeletedEntity2_ClassRemoved_WithDeleter extends EvolveCase {
186 
187         private static final String NAME =
188             PREFIX + "DeletedEntity2_ClassRemoved";
189 
190         @Override
getNRecordsExpected()191         int getNRecordsExpected() {
192             return 0;
193         }
194 
195         @Override
getMutations()196         Mutations getMutations() {
197             Mutations m = new Mutations();
198             m.addDeleter(new Deleter(NAME, 0));
199             return m;
200         }
201 
202         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)203         void checkEvolvedModel(EntityModel model,
204                                Environment env,
205                                boolean oldTypesExist) {
206             checkEntity(false, model, env, NAME, 0, "skey");
207             if (oldTypesExist) {
208                 checkVersions(model, NAME, 0);
209             }
210         }
211 
212         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)213         void readRawObjects(RawStore store,
214                             boolean expectEvolved,
215                             boolean expectUpdated)
216             throws DatabaseException {
217 
218             if (expectEvolved) {
219                 return;
220             }
221             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
222             checkRawFields(obj, "key", 99, "skey", 88);
223         }
224     }
225 
226     /**
227      * Disallow removing the Entity annotation when no Deleter mutation is
228      * specified.
229      */
230     static class DeletedEntity3_AnnotRemoved_NoMutation extends EvolveCase {
231 
232         private static final String NAME =
233             DeletedEntity3_AnnotRemoved_NoMutation.class.getName();
234 
235         @Override
getStoreOpenException()236         public String getStoreOpenException() {
237             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DeletedEntity3_AnnotRemoved_NoMutation version: 0 Error: java.lang.IllegalArgumentException: Class could not be loaded or is not persistent: com.sleepycat.persist.test.EvolveClasses$DeletedEntity3_AnnotRemoved_NoMutation";
238         }
239 
240         @Override
checkUnevolvedModel(EntityModel model, Environment env)241         void checkUnevolvedModel(EntityModel model, Environment env) {
242             checkEntity(true, model, env, NAME, 0, "skey");
243             checkVersions(model, NAME, 0);
244         }
245 
246         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)247         void readRawObjects(RawStore store,
248                             boolean expectEvolved,
249                             boolean expectUpdated)
250             throws DatabaseException {
251 
252             if (expectEvolved) {
253                 TestCase.fail();
254             }
255             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
256             checkRawFields(obj, "key", 99, "skey", 88);
257         }
258     }
259 
260     /**
261      * Allow removing the Entity annotation when a Deleter mutation is
262      * specified.
263      */
264     static class DeletedEntity4_AnnotRemoved_WithDeleter extends EvolveCase {
265 
266         private static final String NAME =
267             DeletedEntity4_AnnotRemoved_WithDeleter.class.getName();
268 
269         @Override
getNRecordsExpected()270         int getNRecordsExpected() {
271             return 0;
272         }
273 
274         @Override
getMutations()275         Mutations getMutations() {
276             Mutations m = new Mutations();
277             m.addDeleter(new Deleter(NAME, 0));
278             return m;
279         }
280 
281         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)282         void checkEvolvedModel(EntityModel model,
283                                Environment env,
284                                boolean oldTypesExist) {
285             checkEntity(false, model, env, NAME, 0, "skey");
286             if (oldTypesExist) {
287                 checkVersions(model, NAME, 0);
288             }
289         }
290 
291         @Override
readObjects(EntityStore store, boolean doUpdate)292         void readObjects(EntityStore store, boolean doUpdate) {
293             try {
294                 store.getPrimaryIndex
295                     (Integer.class,
296                      DeletedEntity4_AnnotRemoved_WithDeleter.class);
297                 TestCase.fail();
298             } catch (Exception e) {
299                 checkEquals
300                     ("java.lang.IllegalArgumentException: Class could not be loaded or is not an entity class: com.sleepycat.persist.test.EvolveClasses$DeletedEntity4_AnnotRemoved_WithDeleter",
301                      e.toString());
302             }
303         }
304 
305         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)306         void readRawObjects(RawStore store,
307                             boolean expectEvolved,
308                             boolean expectUpdated)
309             throws DatabaseException {
310 
311             if (expectEvolved) {
312                 return;
313             }
314             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
315             checkRawFields(obj, "key", 99, "skey", 88);
316         }
317     }
318 
319     /**
320      * Disallow changing the Entity annotation to Persistent when no Deleter
321      * mutation is specified.
322      */
323     @Persistent(version=1)
324     static class DeletedEntity5_EntityToPersist_NoMutation extends EvolveCase {
325 
326         private static final String NAME =
327             DeletedEntity5_EntityToPersist_NoMutation.class.getName();
328 
329         @Override
getStoreOpenException()330         public String getStoreOpenException() {
331             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DeletedEntity5_EntityToPersist_NoMutation version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DeletedEntity5_EntityToPersist_NoMutation version: 1 Error: @Entity switched to/from @Persistent";
332         }
333 
334         @Override
checkUnevolvedModel(EntityModel model, Environment env)335         void checkUnevolvedModel(EntityModel model, Environment env) {
336             checkEntity(true, model, env, NAME, 0, "skey");
337             checkVersions(model, NAME, 0);
338         }
339 
340         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)341         void readRawObjects(RawStore store,
342                             boolean expectEvolved,
343                             boolean expectUpdated)
344             throws DatabaseException {
345 
346             if (expectEvolved) {
347                 TestCase.fail();
348             }
349             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
350             checkRawFields(obj, "key", 99, "skey", 88);
351         }
352     }
353 
354     /**
355      * Allow changing the Entity annotation to Persistent when a Deleter
356      * mutation is specified.
357      */
358     @Persistent(version=1)
359     static class DeletedEntity6_EntityToPersist_WithDeleter extends EvolveCase {
360 
361         private static final String NAME =
362             DeletedEntity6_EntityToPersist_WithDeleter.class.getName();
363         private static final String NAME2 =
364             Embed_DeletedEntity6_EntityToPersist_WithDeleter.class.getName();
365 
366         @Override
getNRecordsExpected()367         int getNRecordsExpected() {
368             return 0;
369         }
370 
371         @Override
getMutations()372         Mutations getMutations() {
373             Mutations m = new Mutations();
374             m.addDeleter(new Deleter(NAME, 0));
375             return m;
376         }
377 
378         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)379         void checkEvolvedModel(EntityModel model,
380                                Environment env,
381                                boolean oldTypesExist) {
382             checkNonEntity(true, model, env, NAME, 1);
383             if (oldTypesExist) {
384                 checkVersions(model, NAME, 1, NAME, 0);
385             } else {
386                 checkVersions(model, NAME, 1);
387             }
388         }
389 
390         @Override
readObjects(EntityStore store, boolean doUpdate)391         void readObjects(EntityStore store, boolean doUpdate)
392             throws DatabaseException {
393 
394             /* Cannot get the primary index for the former entity class. */
395             try {
396                 store.getPrimaryIndex
397                     (Integer.class,
398                      DeletedEntity6_EntityToPersist_WithDeleter.class);
399                 TestCase.fail();
400             } catch (Exception e) {
401                 checkEquals
402                     ("java.lang.IllegalArgumentException: Class could not be loaded or is not an entity class: com.sleepycat.persist.test.EvolveClasses$DeletedEntity6_EntityToPersist_WithDeleter",
403                      e.toString());
404             }
405 
406             if (newMetadataWritten) {
407                 /* Can embed the new persistent class in another entity. */
408                 PrimaryIndex<Long,
409                              Embed_DeletedEntity6_EntityToPersist_WithDeleter>
410                     index = store.getPrimaryIndex
411                     (Long.class,
412                      Embed_DeletedEntity6_EntityToPersist_WithDeleter.class);
413 
414                 if (doUpdate) {
415                     Embed_DeletedEntity6_EntityToPersist_WithDeleter embed =
416                         new Embed_DeletedEntity6_EntityToPersist_WithDeleter();
417                     index.put(embed);
418                     embed = index.get(embed.key);
419                     /* This new type should exist only after update. */
420                     Environment env = store.getEnvironment();
421                     EntityModel model = store.getModel();
422                     checkEntity(true, model, env, NAME2, 0, null);
423                     checkVersions(model, NAME2, 0);
424                 }
425             }
426         }
427 
428         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)429         void readRawObjects(RawStore store,
430                             boolean expectEvolved,
431                             boolean expectUpdated)
432             throws DatabaseException {
433 
434             if (expectEvolved) {
435                 return;
436             }
437             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
438             checkRawFields(obj, "key", 99, "skey", 88);
439         }
440     }
441 
442     @Entity
443     static class Embed_DeletedEntity6_EntityToPersist_WithDeleter {
444 
445         @PrimaryKey
446         long key = 99;
447 
448         DeletedEntity6_EntityToPersist_WithDeleter embedded =
449             new DeletedEntity6_EntityToPersist_WithDeleter();
450     }
451 
452     /**
453      * Disallow removing a Persistent class when no Deleter mutation is
454      * specified, even when the Entity class that embedded the Persistent class
455      * is deleted properly (by removing the Entity annotation in this case).
456      */
457     static class DeletedPersist1_ClassRemoved_NoMutation extends EvolveCase {
458 
459         private static final String NAME =
460             PREFIX + "DeletedPersist1_ClassRemoved";
461 
462         private static final String NAME2 =
463             DeletedPersist1_ClassRemoved_NoMutation.class.getName();
464 
465         @Override
getMutations()466         Mutations getMutations() {
467             Mutations m = new Mutations();
468             m.addDeleter(new Deleter(NAME2, 0));
469             return m;
470         }
471 
472         @Override
getStoreOpenException()473         public String getStoreOpenException() {
474             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DeletedPersist1_ClassRemoved version: 0 Error: java.lang.ClassNotFoundException: com.sleepycat.persist.test.EvolveClasses$DeletedPersist1_ClassRemoved";
475         }
476 
477         @Override
checkUnevolvedModel(EntityModel model, Environment env)478         void checkUnevolvedModel(EntityModel model, Environment env) {
479             checkNonEntity(true, model, env, NAME, 0);
480             checkEntity(true, model, env, NAME2, 0, null);
481             checkVersions(model, NAME, 0);
482             checkVersions(model, NAME2, 0);
483         }
484 
485         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)486         void readRawObjects(RawStore store,
487                             boolean expectEvolved,
488                             boolean expectUpdated)
489             throws DatabaseException {
490 
491             if (expectEvolved) {
492                 TestCase.fail();
493             }
494 
495             RawType embedType = store.getModel().getRawType(NAME);
496             checkRawType(embedType, NAME, 0);
497 
498             RawObject embed =
499                 new RawObject(embedType, makeValues("f", 123), null);
500 
501             RawObject obj = readRaw(store, 99, NAME2, 0, CASECLS, 0);
502             checkRawFields(obj, "key", 99, "embed", embed);
503         }
504     }
505 
506     /**
507      * Allow removing a Persistent class when a Deleter mutation is
508      * specified, and the Entity class that embedded the Persistent class
509      * is also deleted properly (by removing the Entity annotation in this
510      * case).
511      */
512     static class DeletedPersist2_ClassRemoved_WithDeleter extends EvolveCase {
513 
514         private static final String NAME =
515             PREFIX + "DeletedPersist2_ClassRemoved";
516         private static final String NAME2 =
517             DeletedPersist2_ClassRemoved_WithDeleter.class.getName();
518 
519         @Override
getNRecordsExpected()520         int getNRecordsExpected() {
521             return 0;
522         }
523 
524         @Override
getMutations()525         Mutations getMutations() {
526             Mutations m = new Mutations();
527             m.addDeleter(new Deleter(NAME, 0));
528             m.addDeleter(new Deleter(NAME2, 0));
529             return m;
530         }
531 
532         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)533         void checkEvolvedModel(EntityModel model,
534                                Environment env,
535                                boolean oldTypesExist) {
536             checkNonEntity(false, model, env, NAME, 0);
537             checkEntity(false, model, env, NAME2, 0, null);
538             if (oldTypesExist) {
539                 checkVersions(model, NAME, 0);
540                 checkVersions(model, NAME2, 0);
541             }
542         }
543 
544         @Override
readObjects(EntityStore store, boolean doUpdate)545         void readObjects(EntityStore store, boolean doUpdate) {
546             try {
547                 store.getPrimaryIndex
548                     (Integer.class,
549                      DeletedPersist2_ClassRemoved_WithDeleter.class);
550                 TestCase.fail();
551             } catch (Exception e) {
552                 checkEquals
553                     ("java.lang.IllegalArgumentException: Class could not be loaded or is not an entity class: com.sleepycat.persist.test.EvolveClasses$DeletedPersist2_ClassRemoved_WithDeleter",
554                      e.toString());
555             }
556         }
557 
558         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)559         void readRawObjects(RawStore store,
560                             boolean expectEvolved,
561                             boolean expectUpdated)
562             throws DatabaseException {
563 
564             if (expectEvolved) {
565                 return;
566             }
567 
568             RawType embedType = store.getModel().getRawType(NAME);
569             checkRawType(embedType, NAME, 0);
570 
571             RawObject embed =
572                 new RawObject(embedType, makeValues("f", 123), null);
573 
574             RawObject obj = readRaw(store, 99, NAME2, 0, CASECLS, 0);
575             checkRawFields(obj, "key", 99, "embed", embed);
576         }
577     }
578 
579     static class DeletedPersist3_AnnotRemoved {
580 
581         int f = 123;
582     }
583 
584     /**
585      * Disallow removing the Persistent annotation when no Deleter mutation is
586      * specified, even when the Entity class that embedded the Persistent class
587      * is deleted properly (by removing the Entity annotation in this case).
588      */
589     static class DeletedPersist3_AnnotRemoved_NoMutation extends EvolveCase {
590 
591         private static final String NAME =
592             DeletedPersist3_AnnotRemoved.class.getName();
593         private static final String NAME2 =
594             DeletedPersist3_AnnotRemoved_NoMutation.class.getName();
595 
596         @Override
getMutations()597         Mutations getMutations() {
598             Mutations m = new Mutations();
599             m.addDeleter(new Deleter(NAME2, 0));
600             return m;
601         }
602 
603         @Override
getStoreOpenException()604         public String getStoreOpenException() {
605             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DeletedPersist3_AnnotRemoved version: 0 Error: java.lang.IllegalArgumentException: Class could not be loaded or is not persistent: com.sleepycat.persist.test.EvolveClasses$DeletedPersist3_AnnotRemoved";
606         }
607 
608         @Override
checkUnevolvedModel(EntityModel model, Environment env)609         void checkUnevolvedModel(EntityModel model, Environment env) {
610             checkNonEntity(true, model, env, NAME, 0);
611             checkEntity(true, model, env, NAME2, 0, null);
612             checkVersions(model, NAME, 0);
613             checkVersions(model, NAME2, 0);
614         }
615 
616         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)617         void readRawObjects(RawStore store,
618                             boolean expectEvolved,
619                             boolean expectUpdated)
620             throws DatabaseException {
621 
622             if (expectEvolved) {
623                 TestCase.fail();
624             }
625 
626             RawType embedType = store.getModel().getRawType(NAME);
627             checkRawType(embedType, NAME, 0);
628 
629             RawObject embed =
630                 new RawObject(embedType, makeValues("f", 123), null);
631 
632             RawObject obj = readRaw(store, 99, NAME2, 0, CASECLS, 0);
633             checkRawFields(obj, "key", 99, "embed", embed);
634         }
635     }
636 
637     static class DeletedPersist4_AnnotRemoved {
638 
639         int f = 123;
640     }
641 
642     /**
643      * Allow removing the Persistent annotation when a Deleter mutation is
644      * specified, and the Entity class that embedded the Persistent class
645      * is also deleted properly (by removing the Entity annotation in this
646      * case).
647      */
648     static class DeletedPersist4_AnnotRemoved_WithDeleter extends EvolveCase {
649 
650         private static final String NAME =
651             DeletedPersist4_AnnotRemoved.class.getName();
652         private static final String NAME2 =
653             DeletedPersist4_AnnotRemoved_WithDeleter.class.getName();
654 
655         @Override
getNRecordsExpected()656         int getNRecordsExpected() {
657             return 0;
658         }
659 
660         @Override
getMutations()661         Mutations getMutations() {
662             Mutations m = new Mutations();
663             m.addDeleter(new Deleter(NAME, 0));
664             m.addDeleter(new Deleter(NAME2, 0));
665             return m;
666         }
667 
668         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)669         void checkEvolvedModel(EntityModel model,
670                                Environment env,
671                                boolean oldTypesExist) {
672             checkNonEntity(false, model, env, NAME, 0);
673             checkEntity(false, model, env, NAME2, 0, null);
674             if (oldTypesExist) {
675                 checkVersions(model, NAME, 0);
676                 checkVersions(model, NAME2, 0);
677             }
678         }
679 
680         @Override
readObjects(EntityStore store, boolean doUpdate)681         void readObjects(EntityStore store, boolean doUpdate) {
682             try {
683                 store.getPrimaryIndex
684                     (Integer.class,
685                      DeletedPersist4_AnnotRemoved_WithDeleter.class);
686                 TestCase.fail();
687             } catch (Exception e) {
688                 checkEquals
689                     ("java.lang.IllegalArgumentException: Class could not be loaded or is not an entity class: com.sleepycat.persist.test.EvolveClasses$DeletedPersist4_AnnotRemoved_WithDeleter",
690                      e.toString());
691             }
692         }
693 
694         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)695         void readRawObjects(RawStore store,
696                             boolean expectEvolved,
697                             boolean expectUpdated)
698             throws DatabaseException {
699 
700             if (expectEvolved) {
701                 return;
702             }
703 
704             RawType embedType = store.getModel().getRawType(NAME);
705             checkRawType(embedType, NAME, 0);
706 
707             RawObject embed =
708                 new RawObject(embedType, makeValues("f", 123), null);
709 
710             RawObject obj = readRaw(store, 99, NAME2, 0, CASECLS, 0);
711             checkRawFields(obj, "key", 99, "embed", embed);
712         }
713     }
714 
715     @Entity(version=1)
716     static class DeletedPersist5_PersistToEntity {
717 
718         @PrimaryKey
719         int key = 99;
720 
721         int f = 123;
722     }
723 
724     /**
725      * Disallow changing the Entity annotation to Persistent when no Deleter
726      * mutation is specified, even when the Entity class that embedded the
727      * Persistent class is deleted properly (by removing the Entity annotation
728      * in this case).
729      */
730     static class DeletedPersist5_PersistToEntity_NoMutation
731         extends EvolveCase {
732 
733         private static final String NAME =
734             DeletedPersist5_PersistToEntity.class.getName();
735         private static final String NAME2 =
736             DeletedPersist5_PersistToEntity_NoMutation.class.getName();
737 
738         @Override
getMutations()739         Mutations getMutations() {
740             Mutations m = new Mutations();
741             m.addDeleter(new Deleter(NAME2, 0));
742             return m;
743         }
744 
745         @Override
getStoreOpenException()746         public String getStoreOpenException() {
747             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DeletedPersist5_PersistToEntity version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DeletedPersist5_PersistToEntity version: 1 Error: @Entity switched to/from @Persistent";
748         }
749 
750         @Override
checkUnevolvedModel(EntityModel model, Environment env)751         void checkUnevolvedModel(EntityModel model, Environment env) {
752             checkNonEntity(true, model, env, NAME, 0);
753             checkEntity(true, model, env, NAME2, 0, null);
754             checkVersions(model, NAME, 0);
755             checkVersions(model, NAME2, 0);
756         }
757 
758         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)759         void readRawObjects(RawStore store,
760                             boolean expectEvolved,
761                             boolean expectUpdated)
762             throws DatabaseException {
763 
764             if (expectEvolved) {
765                 TestCase.fail();
766             }
767 
768             RawType embedType = store.getModel().getRawType(NAME);
769             checkRawType(embedType, NAME, 0);
770 
771             RawObject embed =
772                 new RawObject(embedType, makeValues("f", 123), null);
773 
774             RawObject obj = readRaw(store, 99, NAME2, 0, CASECLS, 0);
775             checkRawFields(obj, "key", 99, "embed", embed);
776         }
777     }
778 
779     @Entity(version=1)
780     static class DeletedPersist6_PersistToEntity {
781 
782         @PrimaryKey
783         int key = 99;
784 
785         int f = 123;
786     }
787 
788     /**
789      * Allow changing the Entity annotation to Persistent when a Deleter
790      * mutation is specified, and the Entity class that embedded the Persistent
791      * class is also deleted properly (by removing the Entity annotation in
792      * this case).
793      */
794     static class DeletedPersist6_PersistToEntity_WithDeleter
795         extends EvolveCase {
796 
797         private static final String NAME =
798             DeletedPersist6_PersistToEntity.class.getName();
799         private static final String NAME2 =
800             DeletedPersist6_PersistToEntity_WithDeleter.class.getName();
801 
802         @Override
getNRecordsExpected()803         int getNRecordsExpected() {
804             return 0;
805         }
806 
807         @Override
getMutations()808         Mutations getMutations() {
809             Mutations m = new Mutations();
810             m.addDeleter(new Deleter(NAME, 0));
811             m.addDeleter(new Deleter(NAME2, 0));
812             return m;
813         }
814 
815         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)816         void checkEvolvedModel(EntityModel model,
817                                Environment env,
818                                boolean oldTypesExist) {
819             checkEntity(false, model, env, NAME2, 0, null);
820             if (oldTypesExist) {
821                 checkVersions(model, NAME, 1, NAME, 0);
822                 checkVersions(model, NAME2, 0);
823             } else {
824                 checkVersions(model, NAME, 1);
825             }
826         }
827 
828         @Override
readObjects(EntityStore store, boolean doUpdate)829         void readObjects(EntityStore store, boolean doUpdate)
830             throws DatabaseException {
831 
832             /* Cannot get the primary index for the former entity class. */
833             try {
834                 store.getPrimaryIndex
835                     (Integer.class,
836                      DeletedPersist6_PersistToEntity_WithDeleter.class);
837                 TestCase.fail();
838             } catch (Exception e) {
839                 checkEquals
840                     ("java.lang.IllegalArgumentException: Class could not be loaded or is not an entity class: com.sleepycat.persist.test.EvolveClasses$DeletedPersist6_PersistToEntity_WithDeleter",
841                      e.toString());
842             }
843 
844             if (newMetadataWritten) {
845                 /* Can use the primary index of the new entity class. */
846                 PrimaryIndex<Integer,
847                              DeletedPersist6_PersistToEntity>
848                     index = store.getPrimaryIndex
849                         (Integer.class,
850                          DeletedPersist6_PersistToEntity.class);
851 
852                 if (doUpdate) {
853                     DeletedPersist6_PersistToEntity obj =
854                         new DeletedPersist6_PersistToEntity();
855                     index.put(obj);
856                     obj = index.get(obj.key);
857                     /* This new type should exist only after update. */
858                     Environment env = store.getEnvironment();
859                     EntityModel model = store.getModel();
860                     checkEntity(true, model, env, NAME, 1, null);
861                 }
862             }
863         }
864 
865         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)866         void copyRawObjects(RawStore rawStore, EntityStore newStore)
867             throws DatabaseException {
868 
869             PrimaryIndex<Integer,
870                          DeletedPersist6_PersistToEntity>
871                 index = newStore.getPrimaryIndex
872                     (Integer.class,
873                      DeletedPersist6_PersistToEntity.class);
874             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
875             index.put((DeletedPersist6_PersistToEntity)
876                       newStore.getModel().convertRawObject(raw));
877         }
878 
879         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)880         void readRawObjects(RawStore store,
881                             boolean expectEvolved,
882                             boolean expectUpdated)
883             throws DatabaseException {
884 
885             if (expectEvolved) {
886                 return;
887             }
888 
889             RawType embedType = store.getModel().getRawType(NAME);
890             checkRawType(embedType, NAME, 0);
891 
892             RawObject embed =
893                 new RawObject(embedType, makeValues("f", 123), null);
894 
895             RawObject obj = readRaw(store, 99, NAME2, 0, CASECLS, 0);
896             checkRawFields(obj, "key", 99, "embed", embed);
897         }
898     }
899 
900     /**
901      * Disallow renaming an entity class without a Renamer mutation.
902      */
903     @Entity(version=1)
904     static class RenamedEntity1_NewEntityName_NoMutation
905         extends EvolveCase {
906 
907         private static final String NAME =
908             PREFIX + "RenamedEntity1_NewEntityName";
909         private static final String NAME2 =
910             RenamedEntity1_NewEntityName_NoMutation.class.getName();
911 
912         @PrimaryKey
913         int key = 99;
914 
915         @SecondaryKey(relate=ONE_TO_ONE)
916         int skey = 88;
917 
918         @Override
getStoreOpenException()919         public String getStoreOpenException() {
920             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$RenamedEntity1_NewEntityName version: 0 Error: java.lang.ClassNotFoundException: com.sleepycat.persist.test.EvolveClasses$RenamedEntity1_NewEntityName";
921         }
922 
923         @Override
checkUnevolvedModel(EntityModel model, Environment env)924         void checkUnevolvedModel(EntityModel model, Environment env) {
925             checkEntity(true, model, env, NAME, 0, "skey");
926             checkVersions(model, NAME, 0);
927         }
928 
929         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)930         void readRawObjects(RawStore store,
931                             boolean expectEvolved,
932                             boolean expectUpdated)
933             throws DatabaseException {
934 
935             if (expectEvolved) {
936                 TestCase.fail();
937             }
938             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
939             checkRawFields(obj, "key", 99, "skey", 88);
940         }
941     }
942 
943     /**
944      * Allow renaming an entity class with a Renamer mutation.
945      */
946     @Entity(version=1)
947     static class RenamedEntity2_NewEntityName_WithRenamer
948         extends EvolveCase {
949 
950         private static final String NAME =
951             PREFIX + "RenamedEntity2_NewEntityName";
952         private static final String NAME2 =
953             RenamedEntity2_NewEntityName_WithRenamer.class.getName();
954 
955         @PrimaryKey
956         int key = 99;
957 
958         @SecondaryKey(relate=ONE_TO_ONE)
959         int skey = 88;
960 
961         @Override
getMutations()962         Mutations getMutations() {
963             Mutations m = new Mutations();
964             m.addRenamer(new Renamer(NAME, 0, NAME2));
965             return m;
966         }
967 
968         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)969         void checkEvolvedModel(EntityModel model,
970                                Environment env,
971                                boolean oldTypesExist) {
972             checkEntity(false, model, env, NAME, 0, null);
973             checkEntity(true, model, env, NAME2, 1, null);
974             if (oldTypesExist) {
975                 checkVersions(model, NAME2, 1, NAME, 0);
976             } else {
977                 checkVersions(model, NAME2, 1);
978             }
979         }
980 
981         @Override
readObjects(EntityStore store, boolean doUpdate)982         void readObjects(EntityStore store, boolean doUpdate)
983             throws DatabaseException {
984 
985             PrimaryIndex<Integer, RenamedEntity2_NewEntityName_WithRenamer>
986                 index = store.getPrimaryIndex
987                     (Integer.class,
988                      RenamedEntity2_NewEntityName_WithRenamer.class);
989             RenamedEntity2_NewEntityName_WithRenamer obj = index.get(key);
990             TestCase.assertNotNull(obj);
991             TestCase.assertEquals(99, obj.key);
992             TestCase.assertEquals(88, obj.skey);
993 
994             SecondaryIndex<Integer, Integer,
995                            RenamedEntity2_NewEntityName_WithRenamer>
996                 sindex = store.getSecondaryIndex(index, Integer.class, "skey");
997             obj = sindex.get(88);
998             TestCase.assertNotNull(obj);
999             TestCase.assertEquals(99, obj.key);
1000             TestCase.assertEquals(88, obj.skey);
1001 
1002             if (doUpdate) {
1003                 index.put(obj);
1004             }
1005         }
1006 
1007         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)1008         void copyRawObjects(RawStore rawStore, EntityStore newStore)
1009             throws DatabaseException {
1010 
1011             PrimaryIndex<Integer, RenamedEntity2_NewEntityName_WithRenamer>
1012                 index = newStore.getPrimaryIndex
1013                     (Integer.class,
1014                      RenamedEntity2_NewEntityName_WithRenamer.class);
1015             RawObject raw = rawStore.getPrimaryIndex(NAME2).get(99);
1016             index.put((RenamedEntity2_NewEntityName_WithRenamer)
1017                       newStore.getModel().convertRawObject(raw));
1018         }
1019 
1020         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)1021         void readRawObjects(RawStore store,
1022                             boolean expectEvolved,
1023                             boolean expectUpdated)
1024             throws DatabaseException {
1025 
1026             RawObject obj;
1027             if (expectEvolved) {
1028                 obj = readRaw(store, 99, NAME2, 1, CASECLS, 0);
1029             } else {
1030                 obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1031             }
1032             checkRawFields(obj, "key", 99, "skey", 88);
1033         }
1034     }
1035 
1036     @Persistent
1037     static class DeleteSuperclass1_BaseClass
1038         extends EvolveCase {
1039 
1040         int f = 123;
1041     }
1042 
1043     /**
1044      * Disallow deleting a superclass from the hierarchy when the superclass
1045      * has persistent fields and no Deleter or Converter is specified.
1046      */
1047     @Entity
1048     static class DeleteSuperclass1_NoMutation
1049         extends EvolveCase {
1050 
1051         private static final String NAME =
1052             DeleteSuperclass1_BaseClass.class.getName();
1053         private static final String NAME2 =
1054             DeleteSuperclass1_NoMutation.class.getName();
1055 
1056         @PrimaryKey
1057         int key = 99;
1058 
1059         int ff;
1060 
1061         @Override
getStoreOpenException()1062         public String getStoreOpenException() {
1063             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DeleteSuperclass1_NoMutation version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DeleteSuperclass1_NoMutation version: 0 Error: When a superclass is removed from the class hierarchy, the superclass or all of its persistent fields must be deleted with a Deleter: com.sleepycat.persist.test.EvolveClasses$DeleteSuperclass1_BaseClass";
1064         }
1065 
1066         @Override
checkUnevolvedModel(EntityModel model, Environment env)1067         void checkUnevolvedModel(EntityModel model, Environment env) {
1068             checkNonEntity(true, model, env, NAME, 0);
1069             checkEntity(true, model, env, NAME2, 0, null);
1070             checkVersions(model, NAME, 0);
1071             checkVersions(model, NAME2, 0);
1072         }
1073 
1074         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)1075         void readRawObjects(RawStore store,
1076                             boolean expectEvolved,
1077                             boolean expectUpdated)
1078             throws DatabaseException {
1079 
1080             if (expectEvolved) {
1081                 TestCase.fail();
1082             }
1083             RawObject obj = readRaw(store, 99, NAME2, 0, NAME, 0, CASECLS, 0);
1084             checkRawFields(obj, "key", 99, "ff", 88);
1085             checkRawFields(obj.getSuper(), "f", 123);
1086             checkRawFields(obj.getSuper().getSuper());
1087         }
1088     }
1089 
1090     @Persistent
1091     static class DeleteSuperclass2_BaseClass
1092         extends EvolveCase {
1093 
1094         int f;
1095 
1096         @SecondaryKey(relate=ONE_TO_ONE)
1097         int skey;
1098     }
1099 
1100     /**
1101      * Allow deleting a superclass from the hierarchy when the superclass has
1102      * persistent fields and a class Converter is specified.  Also check that
1103      * the secondary key field in the deleted base class is handled properly.
1104      */
1105     @Entity(version=1)
1106     static class DeleteSuperclass2_WithConverter extends EvolveCase {
1107 
1108         private static final String NAME =
1109             DeleteSuperclass2_BaseClass.class.getName();
1110         private static final String NAME2 =
1111             DeleteSuperclass2_WithConverter.class.getName();
1112 
1113         @PrimaryKey
1114         int key;
1115 
1116         int ff;
1117 
1118         @SecondaryKey(relate=ONE_TO_ONE)
1119         Integer skey2;
1120 
1121         @SecondaryKey(relate=ONE_TO_ONE)
1122         int skey3;
1123 
1124         @Override
getMutations()1125         Mutations getMutations() {
1126             Mutations m = new Mutations();
1127             m.addConverter(new EntityConverter
1128                 (NAME2, 0, new MyConversion(),
1129                  Collections.singleton("skey")));
1130             return m;
1131         }
1132 
1133         @SuppressWarnings("serial")
1134         static class MyConversion implements Conversion {
1135 
1136             transient RawType newType;
1137 
initialize(EntityModel model)1138             public void initialize(EntityModel model) {
1139                 newType = model.getRawType(NAME2);
1140                 TestCase.assertNotNull(newType);
1141             }
1142 
convert(Object fromValue)1143             public Object convert(Object fromValue) {
1144                 TestCase.assertNotNull(newType);
1145                 RawObject obj = (RawObject) fromValue;
1146                 RawObject newSuper = obj.getSuper().getSuper();
1147                 return new RawObject(newType, obj.getValues(), newSuper);
1148             }
1149 
1150             @Override
equals(Object other)1151             public boolean equals(Object other) {
1152                 return other instanceof MyConversion;
1153             }
1154         }
1155 
1156         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)1157         void checkEvolvedModel(EntityModel model,
1158                                Environment env,
1159                                boolean oldTypesExist) {
1160             checkEntity(true, model, env, NAME2, 1, null);
1161             if (oldTypesExist) {
1162                 checkVersions(model, NAME2, 1, NAME2, 0);
1163                 checkNonEntity(true, model, env, NAME, 0);
1164                 checkVersions(model, NAME, 0);
1165             } else {
1166                 checkVersions(model, NAME2, 1);
1167             }
1168         }
1169 
1170         @Override
readObjects(EntityStore store, boolean doUpdate)1171         void readObjects(EntityStore store, boolean doUpdate)
1172             throws DatabaseException {
1173 
1174             PrimaryIndex<Integer, DeleteSuperclass2_WithConverter>
1175                 index = store.getPrimaryIndex
1176                     (Integer.class,
1177                      DeleteSuperclass2_WithConverter.class);
1178             DeleteSuperclass2_WithConverter obj = index.get(99);
1179             TestCase.assertNotNull(obj);
1180             TestCase.assertSame
1181                 (EvolveCase.class, obj.getClass().getSuperclass());
1182             TestCase.assertEquals(99, obj.key);
1183             TestCase.assertEquals(88, obj.ff);
1184             TestCase.assertEquals(Integer.valueOf(77), obj.skey2);
1185             TestCase.assertEquals(66, obj.skey3);
1186             if (doUpdate) {
1187                 index.put(obj);
1188             }
1189         }
1190 
1191         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)1192         void copyRawObjects(RawStore rawStore, EntityStore newStore)
1193             throws DatabaseException {
1194 
1195             PrimaryIndex<Integer, DeleteSuperclass2_WithConverter>
1196                 index = newStore.getPrimaryIndex
1197                     (Integer.class,
1198                      DeleteSuperclass2_WithConverter.class);
1199             RawObject raw = rawStore.getPrimaryIndex(NAME2).get(99);
1200             index.put((DeleteSuperclass2_WithConverter)
1201                       newStore.getModel().convertRawObject(raw));
1202         }
1203 
1204         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)1205         void readRawObjects(RawStore store,
1206                             boolean expectEvolved,
1207                             boolean expectUpdated)
1208             throws DatabaseException {
1209 
1210             RawObject obj;
1211             if (expectEvolved) {
1212                 obj = readRaw(store, 99, NAME2, 1, CASECLS, 0);
1213             } else {
1214                 obj = readRaw(store, 99, NAME2, 0, NAME, 0, CASECLS, 0);
1215             }
1216             checkRawFields
1217                 (obj, "key", 99, "ff", 88, "skey2", 77, "skey3", 66);
1218             if (expectEvolved) {
1219                 checkRawFields(obj.getSuper());
1220             } else {
1221                 checkRawFields(obj.getSuper(), "f", 123, "skey", 456);
1222                 checkRawFields(obj.getSuper().getSuper());
1223             }
1224             Environment env = store.getEnvironment();
1225             assertDbExists(!expectEvolved, env, NAME2, "skey");
1226             assertDbExists(true, env, NAME2, "skey3");
1227         }
1228     }
1229 
1230     static class DeleteSuperclass3_BaseClass
1231         extends EvolveCase {
1232 
1233         int f;
1234 
1235         @SecondaryKey(relate=ONE_TO_ONE)
1236         int skey;
1237     }
1238 
1239     /**
1240      * Allow deleting a superclass from the hierarchy when the superclass
1241      * has persistent fields and a class Deleter is specified.  Also check that
1242      * the secondary key field in the deleted base class is handled properly.
1243      */
1244     @Entity(version=1)
1245     static class DeleteSuperclass3_WithDeleter extends EvolveCase {
1246 
1247         private static final String NAME =
1248             DeleteSuperclass3_BaseClass.class.getName();
1249         private static final String NAME2 =
1250             DeleteSuperclass3_WithDeleter.class.getName();
1251 
1252         @PrimaryKey
1253         int key;
1254 
1255         int ff;
1256 
1257         @Override
getMutations()1258         Mutations getMutations() {
1259             Mutations m = new Mutations();
1260             m.addDeleter(new Deleter(NAME, 0));
1261             return m;
1262         }
1263 
1264         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)1265         void checkEvolvedModel(EntityModel model,
1266                                Environment env,
1267                                boolean oldTypesExist) {
1268             checkEntity(true, model, env, NAME2, 1, null);
1269             if (oldTypesExist) {
1270                 checkVersions(model, NAME2, 1, NAME2, 0);
1271                 checkNonEntity(false, model, env, NAME, 0);
1272                 checkVersions(model, NAME, 0);
1273             } else {
1274                 checkVersions(model, NAME2, 1);
1275             }
1276         }
1277 
1278         @Override
readObjects(EntityStore store, boolean doUpdate)1279         void readObjects(EntityStore store, boolean doUpdate)
1280             throws DatabaseException {
1281 
1282             PrimaryIndex<Integer, DeleteSuperclass3_WithDeleter>
1283                 index = store.getPrimaryIndex
1284                     (Integer.class,
1285                      DeleteSuperclass3_WithDeleter.class);
1286             DeleteSuperclass3_WithDeleter obj = index.get(99);
1287             TestCase.assertNotNull(obj);
1288             TestCase.assertSame
1289                 (EvolveCase.class, obj.getClass().getSuperclass());
1290             TestCase.assertEquals(99, obj.key);
1291             TestCase.assertEquals(88, obj.ff);
1292             if (doUpdate) {
1293                 index.put(obj);
1294             }
1295         }
1296 
1297         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)1298         void copyRawObjects(RawStore rawStore, EntityStore newStore)
1299             throws DatabaseException {
1300 
1301             PrimaryIndex<Integer, DeleteSuperclass3_WithDeleter>
1302                 index = newStore.getPrimaryIndex
1303                     (Integer.class,
1304                      DeleteSuperclass3_WithDeleter.class);
1305             RawObject raw = rawStore.getPrimaryIndex(NAME2).get(99);
1306             index.put((DeleteSuperclass3_WithDeleter)
1307                       newStore.getModel().convertRawObject(raw));
1308         }
1309 
1310         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)1311         void readRawObjects(RawStore store,
1312                             boolean expectEvolved,
1313                             boolean expectUpdated)
1314             throws DatabaseException {
1315 
1316             RawObject obj;
1317             if (expectEvolved) {
1318                 obj = readRaw(store, 99, NAME2, 1, CASECLS, 0);
1319             } else {
1320                 obj = readRaw(store, 99, NAME2, 0, NAME, 0, CASECLS, 0);
1321             }
1322             checkRawFields(obj, "key", 99, "ff", 88);
1323             if (expectEvolved) {
1324                 checkRawFields(obj.getSuper());
1325             } else {
1326                 checkRawFields(obj.getSuper(), "f", 123, "skey", 456);
1327                 checkRawFields(obj.getSuper().getSuper());
1328             }
1329             Environment env = store.getEnvironment();
1330             assertDbExists(!expectEvolved, env, NAME2, "skey");
1331         }
1332     }
1333 
1334     @Persistent
1335     static class DeleteSuperclass4_BaseClass
1336         extends EvolveCase {
1337     }
1338 
1339     /**
1340      * Allow deleting a superclass from the hierarchy when the superclass
1341      * has NO persistent fields.  No mutations are needed.
1342      */
1343     @Entity(version=1)
1344     static class DeleteSuperclass4_NoFields extends EvolveCase {
1345 
1346         private static final String NAME =
1347             DeleteSuperclass4_BaseClass.class.getName();
1348         private static final String NAME2 =
1349             DeleteSuperclass4_NoFields.class.getName();
1350 
1351         @PrimaryKey
1352         int key = 99;
1353 
1354         int ff;
1355 
1356         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)1357         void checkEvolvedModel(EntityModel model,
1358                                Environment env,
1359                                boolean oldTypesExist) {
1360             checkEntity(true, model, env, NAME2, 1, null);
1361             if (oldTypesExist) {
1362                 checkVersions(model, NAME2, 1, NAME2, 0);
1363                 checkNonEntity(true, model, env, NAME, 0);
1364                 checkVersions(model, NAME, 0);
1365             } else {
1366                 checkVersions(model, NAME2, 1);
1367             }
1368         }
1369 
1370         @Override
readObjects(EntityStore store, boolean doUpdate)1371         void readObjects(EntityStore store, boolean doUpdate)
1372             throws DatabaseException {
1373 
1374             PrimaryIndex<Integer, DeleteSuperclass4_NoFields>
1375                 index = store.getPrimaryIndex
1376                     (Integer.class,
1377                      DeleteSuperclass4_NoFields.class);
1378             DeleteSuperclass4_NoFields obj = index.get(key);
1379             TestCase.assertNotNull(obj);
1380             TestCase.assertSame
1381                 (EvolveCase.class, obj.getClass().getSuperclass());
1382             TestCase.assertEquals(99, obj.key);
1383             TestCase.assertEquals(88, obj.ff);
1384             if (doUpdate) {
1385                 index.put(obj);
1386             }
1387         }
1388 
1389         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)1390         void copyRawObjects(RawStore rawStore, EntityStore newStore)
1391             throws DatabaseException {
1392 
1393             PrimaryIndex<Integer, DeleteSuperclass4_NoFields>
1394                 index = newStore.getPrimaryIndex
1395                     (Integer.class,
1396                      DeleteSuperclass4_NoFields.class);
1397             RawObject raw = rawStore.getPrimaryIndex(NAME2).get(99);
1398             index.put((DeleteSuperclass4_NoFields)
1399                       newStore.getModel().convertRawObject(raw));
1400         }
1401 
1402         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)1403         void readRawObjects(RawStore store,
1404                             boolean expectEvolved,
1405                             boolean expectUpdated)
1406             throws DatabaseException {
1407 
1408             RawObject obj;
1409             if (expectEvolved) {
1410                 obj = readRaw(store, 99, NAME2, 1, CASECLS, 0);
1411             } else {
1412                 obj = readRaw(store, 99, NAME2, 0, NAME, 0, CASECLS, 0);
1413             }
1414             checkRawFields(obj, "key", 99, "ff", 88);
1415             checkRawFields(obj.getSuper());
1416             if (expectEvolved) {
1417                 TestCase.assertNull(obj.getSuper().getSuper());
1418             } else {
1419                 checkRawFields(obj.getSuper().getSuper());
1420             }
1421         }
1422     }
1423 
1424     @Persistent(version=1)
1425     static class DeleteSuperclass5_Embedded {
1426 
1427         int f;
1428 
1429         @Override
toString()1430         public String toString() {
1431             return "" + f;
1432         }
1433     }
1434 
1435     /**
1436      * Ensure that a superclass at the top of the hierarchy can be deleted.  A
1437      * class Deleter is used.
1438      */
1439     @Entity
1440     static class DeleteSuperclass5_Top
1441         extends EvolveCase {
1442 
1443         private static final String NAME =
1444             DeleteSuperclass5_Top.class.getName();
1445         private static final String NAME2 =
1446             DeleteSuperclass5_Embedded.class.getName();
1447         private static final String NAME3 =
1448             PREFIX + "DeleteSuperclass5_Embedded_Base";
1449 
1450         @PrimaryKey
1451         int key = 99;
1452 
1453         int ff;
1454 
1455         DeleteSuperclass5_Embedded embed =
1456             new DeleteSuperclass5_Embedded();
1457 
1458         @Override
getMutations()1459         Mutations getMutations() {
1460             Mutations m = new Mutations();
1461             m.addDeleter(new Deleter(NAME3, 0));
1462             return m;
1463         }
1464 
1465         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)1466         void checkEvolvedModel(EntityModel model,
1467                                Environment env,
1468                                boolean oldTypesExist) {
1469             checkEntity(true, model, env, NAME, 0, null);
1470             checkNonEntity(true, model, env, NAME2, 1);
1471             checkNonEntity(false, model, env, NAME3, 0);
1472             checkVersions(model, NAME, 0);
1473             if (oldTypesExist) {
1474                 checkVersions(model, NAME2, 1, NAME2, 0);
1475                 checkVersions(model, NAME3, 0);
1476             } else {
1477                 checkVersions(model, NAME2, 1);
1478             }
1479         }
1480 
1481         @Override
readObjects(EntityStore store, boolean doUpdate)1482         void readObjects(EntityStore store, boolean doUpdate)
1483             throws DatabaseException {
1484 
1485             PrimaryIndex<Integer, DeleteSuperclass5_Top>
1486                 index = store.getPrimaryIndex
1487                     (Integer.class,
1488                      DeleteSuperclass5_Top.class);
1489             DeleteSuperclass5_Top obj = index.get(key);
1490             TestCase.assertNotNull(obj);
1491             TestCase.assertNotNull(obj.embed);
1492             TestCase.assertEquals(99, obj.key);
1493             TestCase.assertEquals(88, obj.ff);
1494             TestCase.assertEquals(123, obj.embed.f);
1495             if (doUpdate) {
1496                 index.put(obj);
1497             }
1498         }
1499 
1500         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)1501         void copyRawObjects(RawStore rawStore, EntityStore newStore)
1502             throws DatabaseException {
1503 
1504             PrimaryIndex<Integer, DeleteSuperclass5_Top>
1505                 index = newStore.getPrimaryIndex
1506                     (Integer.class,
1507                      DeleteSuperclass5_Top.class);
1508             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
1509             index.put((DeleteSuperclass5_Top)
1510                       newStore.getModel().convertRawObject(raw));
1511         }
1512 
1513         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)1514         void readRawObjects(RawStore store,
1515                             boolean expectEvolved,
1516                             boolean expectUpdated)
1517             throws DatabaseException {
1518 
1519             RawType embedType = store.getModel().getRawType(NAME2);
1520             RawObject embedSuper = null;
1521             if (!expectEvolved) {
1522                 RawType embedSuperType = store.getModel().getRawType(NAME3);
1523                 embedSuper = new RawObject
1524                     (embedSuperType, makeValues("g", 456), null);
1525             }
1526             RawObject embed =
1527                 new RawObject(embedType, makeValues("f", 123), embedSuper);
1528             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1529             checkRawFields(obj, "key", 99, "ff", 88, "embed", embed);
1530         }
1531     }
1532 
1533     @Persistent
1534     static class InsertSuperclass1_BaseClass
1535         extends EvolveCase {
1536 
1537         int f = 123;
1538     }
1539 
1540     /**
1541      * Allow inserting a superclass between two existing classes in the
1542      * hierarchy.  No mutations are needed.
1543      */
1544     @Entity(version=1)
1545     static class InsertSuperclass1_Between
1546         extends InsertSuperclass1_BaseClass {
1547 
1548         private static final String NAME =
1549             InsertSuperclass1_BaseClass.class.getName();
1550         private static final String NAME2 =
1551             InsertSuperclass1_Between.class.getName();
1552 
1553         @PrimaryKey
1554         int key = 99;
1555 
1556         int ff;
1557 
1558         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)1559         void checkEvolvedModel(EntityModel model,
1560                                Environment env,
1561                                boolean oldTypesExist) {
1562             checkNonEntity(true, model, env, NAME, 0);
1563             checkEntity(true, model, env, NAME2, 1, null);
1564             checkVersions(model, NAME, 0);
1565             if (oldTypesExist) {
1566                 checkVersions(model, NAME2, 1, NAME2, 0);
1567             } else {
1568                 checkVersions(model, NAME2, 1);
1569             }
1570         }
1571 
1572         @Override
readObjects(EntityStore store, boolean doUpdate)1573         void readObjects(EntityStore store, boolean doUpdate)
1574             throws DatabaseException {
1575 
1576             PrimaryIndex<Integer, InsertSuperclass1_Between>
1577                 index = store.getPrimaryIndex
1578                     (Integer.class,
1579                      InsertSuperclass1_Between.class);
1580             InsertSuperclass1_Between obj = index.get(key);
1581             TestCase.assertNotNull(obj);
1582             TestCase.assertSame
1583                 (InsertSuperclass1_BaseClass.class,
1584                  obj.getClass().getSuperclass());
1585             TestCase.assertSame
1586                 (EvolveCase.class,
1587                  obj.getClass().getSuperclass().getSuperclass());
1588             TestCase.assertEquals(99, obj.key);
1589             TestCase.assertEquals(88, obj.ff);
1590             TestCase.assertEquals(123, obj.f);
1591             if (doUpdate) {
1592                 index.put(obj);
1593             }
1594         }
1595 
1596         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)1597         void copyRawObjects(RawStore rawStore, EntityStore newStore)
1598             throws DatabaseException {
1599 
1600             PrimaryIndex<Integer, InsertSuperclass1_Between>
1601                 index = newStore.getPrimaryIndex
1602                     (Integer.class,
1603                      InsertSuperclass1_Between.class);
1604             RawObject raw = rawStore.getPrimaryIndex(NAME2).get(99);
1605             index.put((InsertSuperclass1_Between)
1606                       newStore.getModel().convertRawObject(raw));
1607         }
1608 
1609         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)1610         void readRawObjects(RawStore store,
1611                             boolean expectEvolved,
1612                             boolean expectUpdated)
1613             throws DatabaseException {
1614 
1615             RawObject obj;
1616             if (expectEvolved) {
1617                 obj = readRaw(store, 99, NAME2, 1, NAME, 0, CASECLS, 0);
1618             } else {
1619                 obj = readRaw(store, 99, NAME2, 0, CASECLS, 0);
1620             }
1621             checkRawFields(obj, "key", 99, "ff", 88);
1622             if (expectEvolved) {
1623                 if (expectUpdated) {
1624                     checkRawFields(obj.getSuper(), "f", 123);
1625                 } else {
1626                     checkRawFields(obj.getSuper());
1627                 }
1628                 checkRawFields(obj.getSuper().getSuper());
1629                 TestCase.assertNull(obj.getSuper().getSuper().getSuper());
1630             } else {
1631                 checkRawFields(obj.getSuper());
1632                 TestCase.assertNull(obj.getSuper().getSuper());
1633             }
1634         }
1635     }
1636 
1637     @Persistent
1638     static class InsertSuperclass2_Embedded_Base {
1639 
1640         int g = 456;
1641     }
1642 
1643     @Persistent(version=1)
1644     static class InsertSuperclass2_Embedded
1645         extends InsertSuperclass2_Embedded_Base  {
1646 
1647         int f;
1648     }
1649 
1650     /**
1651      * Allow inserting a superclass at the top of the hierarchy.  No mutations
1652      * are needed.
1653      */
1654     @Entity
1655     static class InsertSuperclass2_Top
1656         extends EvolveCase {
1657 
1658         private static final String NAME =
1659             InsertSuperclass2_Top.class.getName();
1660         private static final String NAME2 =
1661             InsertSuperclass2_Embedded.class.getName();
1662         private static final String NAME3 =
1663             InsertSuperclass2_Embedded_Base.class.getName();
1664 
1665         @PrimaryKey
1666         int key = 99;
1667 
1668         int ff;
1669 
1670         InsertSuperclass2_Embedded embed =
1671             new InsertSuperclass2_Embedded();
1672 
1673         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)1674         void checkEvolvedModel(EntityModel model,
1675                                Environment env,
1676                                boolean oldTypesExist) {
1677             checkEntity(true, model, env, NAME, 0, null);
1678             checkNonEntity(true, model, env, NAME2, 1);
1679             checkNonEntity(true, model, env, NAME3, 0);
1680             checkVersions(model, NAME, 0);
1681             if (oldTypesExist) {
1682                 checkVersions(model, NAME2, 1, NAME2, 0);
1683             } else {
1684                 checkVersions(model, NAME2, 1);
1685             }
1686             checkVersions(model, NAME3, 0);
1687         }
1688 
1689         @Override
readObjects(EntityStore store, boolean doUpdate)1690         void readObjects(EntityStore store, boolean doUpdate)
1691             throws DatabaseException {
1692 
1693             PrimaryIndex<Integer, InsertSuperclass2_Top>
1694                 index = store.getPrimaryIndex
1695                     (Integer.class,
1696                      InsertSuperclass2_Top.class);
1697             InsertSuperclass2_Top obj = index.get(key);
1698             TestCase.assertNotNull(obj);
1699             TestCase.assertNotNull(obj.embed);
1700             TestCase.assertEquals(99, obj.key);
1701             TestCase.assertEquals(88, obj.ff);
1702             TestCase.assertEquals(123, obj.embed.f);
1703             TestCase.assertEquals(456, obj.embed.g);
1704             if (doUpdate) {
1705                 index.put(obj);
1706             }
1707         }
1708 
1709         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)1710         void copyRawObjects(RawStore rawStore, EntityStore newStore)
1711             throws DatabaseException {
1712 
1713             PrimaryIndex<Integer, InsertSuperclass2_Top>
1714                 index = newStore.getPrimaryIndex
1715                     (Integer.class,
1716                      InsertSuperclass2_Top.class);
1717             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
1718             index.put((InsertSuperclass2_Top)
1719                       newStore.getModel().convertRawObject(raw));
1720         }
1721 
1722         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)1723         void readRawObjects(RawStore store,
1724                             boolean expectEvolved,
1725                             boolean expectUpdated)
1726             throws DatabaseException {
1727 
1728             RawType embedType = store.getModel().getRawType(NAME2);
1729             RawObject embedSuper = null;
1730             if (expectEvolved) {
1731                 RawType embedSuperType = store.getModel().getRawType(NAME3);
1732                 Map<String, Object> values =
1733                     expectUpdated ? makeValues("g", 456) : makeValues();
1734                 embedSuper = new RawObject(embedSuperType, values, null);
1735             }
1736             RawObject embed =
1737                 new RawObject(embedType, makeValues("f", 123), embedSuper);
1738             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1739             checkRawFields(obj, "key", 99, "ff", 88, "embed", embed);
1740         }
1741     }
1742 
1743     @Entity(version=1)
1744     static class DisallowNonKeyField_PrimitiveToObject
1745         extends EvolveCase {
1746 
1747         private static final String NAME =
1748             DisallowNonKeyField_PrimitiveToObject.class.getName();
1749 
1750         @PrimaryKey
1751         int key = 99;
1752 
1753         String ff;
1754 
1755         @Override
getStoreOpenException()1756         public String getStoreOpenException() {
1757             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_PrimitiveToObject version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_PrimitiveToObject version: 1 Error: Old field type: int is not compatible with the new type: java.lang.String for field: ff";
1758         }
1759 
1760         @Override
checkUnevolvedModel(EntityModel model, Environment env)1761         void checkUnevolvedModel(EntityModel model, Environment env) {
1762             checkEntity(true, model, env, NAME, 0, null);
1763             checkVersions(model, NAME, 0);
1764         }
1765 
1766         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)1767         void readRawObjects(RawStore store,
1768                             boolean expectEvolved,
1769                             boolean expectUpdated)
1770             throws DatabaseException {
1771 
1772             if (expectEvolved) {
1773                 TestCase.fail();
1774             }
1775             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1776             checkRawFields(obj, "key", 99, "ff", 88);
1777         }
1778     }
1779 
1780     @Entity(version=1)
1781     static class DisallowNonKeyField_ObjectToPrimitive
1782         extends EvolveCase {
1783 
1784         private static final String NAME =
1785             DisallowNonKeyField_ObjectToPrimitive.class.getName();
1786 
1787         @PrimaryKey
1788         int key = 99;
1789 
1790         int ff;
1791 
1792         @Override
getStoreOpenException()1793         public String getStoreOpenException() {
1794             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_ObjectToPrimitive version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_ObjectToPrimitive version: 1 Error: Old field type: java.lang.String is not compatible with the new type: int for field: ff";
1795         }
1796 
1797         @Override
checkUnevolvedModel(EntityModel model, Environment env)1798         void checkUnevolvedModel(EntityModel model, Environment env) {
1799             checkEntity(true, model, env, NAME, 0, null);
1800             checkVersions(model, NAME, 0);
1801         }
1802 
1803         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)1804         void readRawObjects(RawStore store,
1805                             boolean expectEvolved,
1806                             boolean expectUpdated)
1807             throws DatabaseException {
1808 
1809             if (expectEvolved) {
1810                 TestCase.fail();
1811             }
1812             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1813             checkRawFields(obj, "key", 99, "ff", "88");
1814         }
1815     }
1816 
1817     @Persistent
1818     static class MyType {
1819 
1820         @Override
equals(Object o)1821         public boolean equals(Object o) {
1822             return o instanceof MyType;
1823         }
1824     }
1825 
1826     @Persistent
1827     static class MySubtype extends MyType {
1828 
1829         @Override
equals(Object o)1830         public boolean equals(Object o) {
1831             return o instanceof MySubtype;
1832         }
1833     }
1834 
1835     @Entity(version=1)
1836     static class DisallowNonKeyField_ObjectToSubtype
1837         extends EvolveCase {
1838 
1839         private static final String NAME =
1840             DisallowNonKeyField_ObjectToSubtype.class.getName();
1841 
1842         @PrimaryKey
1843         int key = 99;
1844 
1845         MySubtype ff;
1846 
1847         @Override
getStoreOpenException()1848         public String getStoreOpenException() {
1849             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_ObjectToSubtype version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_ObjectToSubtype version: 1 Error: Old field type: com.sleepycat.persist.test.EvolveClasses$MyType is not compatible with the new type: com.sleepycat.persist.test.EvolveClasses$MySubtype for field: ff";
1850         }
1851 
1852         @Override
checkUnevolvedModel(EntityModel model, Environment env)1853         void checkUnevolvedModel(EntityModel model, Environment env) {
1854             checkEntity(true, model, env, NAME, 0, null);
1855             checkVersions(model, NAME, 0);
1856         }
1857 
1858         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)1859         void readRawObjects(RawStore store,
1860                             boolean expectEvolved,
1861                             boolean expectUpdated)
1862             throws DatabaseException {
1863 
1864             if (expectEvolved) {
1865                 TestCase.fail();
1866             }
1867             RawType embedType = store.getModel().getRawType
1868                 (MyType.class.getName());
1869             RawObject embed = new RawObject(embedType, makeValues(), null);
1870 
1871             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1872             checkRawFields(obj, "key", 99, "ff", embed);
1873         }
1874     }
1875 
1876     @Entity(version=1)
1877     static class DisallowNonKeyField_ObjectToUnrelatedSimple
1878         extends EvolveCase {
1879 
1880         private static final String NAME =
1881             DisallowNonKeyField_ObjectToUnrelatedSimple.class.getName();
1882 
1883         @PrimaryKey
1884         int key = 99;
1885 
1886         String ff;
1887 
1888         @Override
getStoreOpenException()1889         public String getStoreOpenException() {
1890             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_ObjectToUnrelatedSimple version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_ObjectToUnrelatedSimple version: 1 Error: Old field type: java.lang.Integer is not compatible with the new type: java.lang.String for field: ff";
1891         }
1892 
1893         @Override
checkUnevolvedModel(EntityModel model, Environment env)1894         void checkUnevolvedModel(EntityModel model, Environment env) {
1895             checkEntity(true, model, env, NAME, 0, null);
1896             checkVersions(model, NAME, 0);
1897         }
1898 
1899         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)1900         void readRawObjects(RawStore store,
1901                             boolean expectEvolved,
1902                             boolean expectUpdated)
1903             throws DatabaseException {
1904 
1905             if (expectEvolved) {
1906                 TestCase.fail();
1907             }
1908             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1909             checkRawFields(obj, "key", 99, "ff", 88);
1910         }
1911     }
1912 
1913     @Entity(version=1)
1914     static class DisallowNonKeyField_ObjectToUnrelatedOther
1915         extends EvolveCase {
1916 
1917         private static final String NAME =
1918             DisallowNonKeyField_ObjectToUnrelatedOther.class.getName();
1919 
1920         @PrimaryKey
1921         int key = 99;
1922 
1923         MyType ff;
1924 
1925         @Override
getStoreOpenException()1926         public String getStoreOpenException() {
1927             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_ObjectToUnrelatedOther version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_ObjectToUnrelatedOther version: 1 Error: Old field type: java.lang.Integer is not compatible with the new type: com.sleepycat.persist.test.EvolveClasses$MyType for field: ff";
1928         }
1929 
1930         @Override
checkUnevolvedModel(EntityModel model, Environment env)1931         void checkUnevolvedModel(EntityModel model, Environment env) {
1932             checkEntity(true, model, env, NAME, 0, null);
1933             checkVersions(model, NAME, 0);
1934         }
1935 
1936         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)1937         void readRawObjects(RawStore store,
1938                             boolean expectEvolved,
1939                             boolean expectUpdated)
1940             throws DatabaseException {
1941 
1942             if (expectEvolved) {
1943                 TestCase.fail();
1944             }
1945             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1946             checkRawFields(obj, "key", 99, "ff", 88);
1947         }
1948     }
1949 
1950     @Entity(version=1)
1951     static class DisallowNonKeyField_byte2boolean
1952         extends EvolveCase {
1953 
1954         private static final String NAME =
1955             DisallowNonKeyField_byte2boolean.class.getName();
1956 
1957         @PrimaryKey
1958         int key = 99;
1959 
1960         boolean ff;
1961 
1962         @Override
getStoreOpenException()1963         public String getStoreOpenException() {
1964             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_byte2boolean version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_byte2boolean version: 1 Error: Old field type: byte is not compatible with the new type: boolean for field: ff";
1965         }
1966 
1967         @Override
checkUnevolvedModel(EntityModel model, Environment env)1968         void checkUnevolvedModel(EntityModel model, Environment env) {
1969             checkEntity(true, model, env, NAME, 0, null);
1970             checkVersions(model, NAME, 0);
1971         }
1972 
1973         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)1974         void readRawObjects(RawStore store,
1975                             boolean expectEvolved,
1976                             boolean expectUpdated)
1977             throws DatabaseException {
1978 
1979             if (expectEvolved) {
1980                 TestCase.fail();
1981             }
1982             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1983             checkRawFields(obj, "key", 99, "ff", (byte) 88);
1984         }
1985     }
1986 
1987     @Entity(version=1)
1988     static class DisallowNonKeyField_short2byte
1989         extends EvolveCase {
1990 
1991         private static final String NAME =
1992             DisallowNonKeyField_short2byte.class.getName();
1993 
1994         @PrimaryKey
1995         int key = 99;
1996 
1997         byte ff;
1998 
1999         @Override
getStoreOpenException()2000         public String getStoreOpenException() {
2001             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_short2byte version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_short2byte version: 1 Error: Old field type: short is not compatible with the new type: byte for field: ff";
2002         }
2003 
2004         @Override
checkUnevolvedModel(EntityModel model, Environment env)2005         void checkUnevolvedModel(EntityModel model, Environment env) {
2006             checkEntity(true, model, env, NAME, 0, null);
2007             checkVersions(model, NAME, 0);
2008         }
2009 
2010         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2011         void readRawObjects(RawStore store,
2012                             boolean expectEvolved,
2013                             boolean expectUpdated)
2014             throws DatabaseException {
2015 
2016             if (expectEvolved) {
2017                 TestCase.fail();
2018             }
2019             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2020             checkRawFields(obj, "key", 99, "ff", (short) 88);
2021         }
2022     }
2023 
2024     @Entity(version=1)
2025     static class DisallowNonKeyField_int2short
2026         extends EvolveCase {
2027 
2028         private static final String NAME =
2029             DisallowNonKeyField_int2short.class.getName();
2030 
2031         @PrimaryKey
2032         int key = 99;
2033 
2034         short ff;
2035 
2036         @Override
getStoreOpenException()2037         public String getStoreOpenException() {
2038             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_int2short version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_int2short version: 1 Error: Old field type: int is not compatible with the new type: short for field: ff";
2039         }
2040 
2041         @Override
checkUnevolvedModel(EntityModel model, Environment env)2042         void checkUnevolvedModel(EntityModel model, Environment env) {
2043             checkEntity(true, model, env, NAME, 0, null);
2044             checkVersions(model, NAME, 0);
2045         }
2046 
2047         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2048         void readRawObjects(RawStore store,
2049                             boolean expectEvolved,
2050                             boolean expectUpdated)
2051             throws DatabaseException {
2052 
2053             if (expectEvolved) {
2054                 TestCase.fail();
2055             }
2056             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2057             checkRawFields(obj, "key", 99, "ff", 88);
2058         }
2059     }
2060 
2061     @Entity(version=1)
2062     static class DisallowNonKeyField_long2int
2063         extends EvolveCase {
2064 
2065         private static final String NAME =
2066             DisallowNonKeyField_long2int.class.getName();
2067 
2068         @PrimaryKey
2069         int key = 99;
2070 
2071         int ff;
2072 
2073         @Override
getStoreOpenException()2074         public String getStoreOpenException() {
2075             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_long2int version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_long2int version: 1 Error: Old field type: long is not compatible with the new type: int for field: ff";
2076         }
2077 
2078         @Override
checkUnevolvedModel(EntityModel model, Environment env)2079         void checkUnevolvedModel(EntityModel model, Environment env) {
2080             checkEntity(true, model, env, NAME, 0, null);
2081             checkVersions(model, NAME, 0);
2082         }
2083 
2084         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2085         void readRawObjects(RawStore store,
2086                             boolean expectEvolved,
2087                             boolean expectUpdated)
2088             throws DatabaseException {
2089 
2090             if (expectEvolved) {
2091                 TestCase.fail();
2092             }
2093             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2094             checkRawFields(obj, "key", 99, "ff", (long) 88);
2095         }
2096     }
2097 
2098     @Entity(version=1)
2099     static class DisallowNonKeyField_float2long
2100         extends EvolveCase {
2101 
2102         private static final String NAME =
2103             DisallowNonKeyField_float2long.class.getName();
2104 
2105         @PrimaryKey
2106         int key = 99;
2107 
2108         long ff;
2109 
2110         @Override
getStoreOpenException()2111         public String getStoreOpenException() {
2112             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_float2long version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_float2long version: 1 Error: Old field type: float is not compatible with the new type: long for field: ff";
2113         }
2114 
2115         @Override
checkUnevolvedModel(EntityModel model, Environment env)2116         void checkUnevolvedModel(EntityModel model, Environment env) {
2117             checkEntity(true, model, env, NAME, 0, null);
2118             checkVersions(model, NAME, 0);
2119         }
2120 
2121         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2122         void readRawObjects(RawStore store,
2123                             boolean expectEvolved,
2124                             boolean expectUpdated)
2125             throws DatabaseException {
2126 
2127             if (expectEvolved) {
2128                 TestCase.fail();
2129             }
2130             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2131             checkRawFields(obj, "key", 99, "ff", (float) 88);
2132         }
2133     }
2134 
2135     @Entity(version=1)
2136     static class DisallowNonKeyField_double2float
2137         extends EvolveCase {
2138 
2139         private static final String NAME =
2140             DisallowNonKeyField_double2float.class.getName();
2141 
2142         @PrimaryKey
2143         int key = 99;
2144 
2145         float ff;
2146 
2147         @Override
getStoreOpenException()2148         public String getStoreOpenException() {
2149             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_double2float version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_double2float version: 1 Error: Old field type: double is not compatible with the new type: float for field: ff";
2150         }
2151 
2152         @Override
checkUnevolvedModel(EntityModel model, Environment env)2153         void checkUnevolvedModel(EntityModel model, Environment env) {
2154             checkEntity(true, model, env, NAME, 0, null);
2155             checkVersions(model, NAME, 0);
2156         }
2157 
2158         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2159         void readRawObjects(RawStore store,
2160                             boolean expectEvolved,
2161                             boolean expectUpdated)
2162             throws DatabaseException {
2163 
2164             if (expectEvolved) {
2165                 TestCase.fail();
2166             }
2167             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2168             checkRawFields(obj, "key", 99, "ff", (double) 88);
2169         }
2170     }
2171 
2172     @Entity(version=1)
2173     static class DisallowNonKeyField_Byte2byte
2174         extends EvolveCase {
2175 
2176         private static final String NAME =
2177             DisallowNonKeyField_Byte2byte.class.getName();
2178 
2179         @PrimaryKey
2180         int key = 99;
2181 
2182         byte ff;
2183 
2184         @Override
getStoreOpenException()2185         public String getStoreOpenException() {
2186             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_Byte2byte version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_Byte2byte version: 1 Error: Old field type: java.lang.Byte is not compatible with the new type: byte for field: ff";
2187         }
2188 
2189         @Override
checkUnevolvedModel(EntityModel model, Environment env)2190         void checkUnevolvedModel(EntityModel model, Environment env) {
2191             checkEntity(true, model, env, NAME, 0, null);
2192             checkVersions(model, NAME, 0);
2193         }
2194 
2195         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2196         void readRawObjects(RawStore store,
2197                             boolean expectEvolved,
2198                             boolean expectUpdated)
2199             throws DatabaseException {
2200 
2201             if (expectEvolved) {
2202                 TestCase.fail();
2203             }
2204             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2205             checkRawFields(obj, "key", 99, "ff", (byte) 88);
2206         }
2207     }
2208 
2209     @Entity(version=1)
2210     static class DisallowNonKeyField_Character2char
2211         extends EvolveCase {
2212 
2213         private static final String NAME =
2214             DisallowNonKeyField_Character2char.class.getName();
2215 
2216         @PrimaryKey
2217         int key = 99;
2218 
2219         char ff;
2220 
2221         @Override
getStoreOpenException()2222         public String getStoreOpenException() {
2223             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_Character2char version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_Character2char version: 1 Error: Old field type: java.lang.Character is not compatible with the new type: char for field: ff";
2224         }
2225 
2226         @Override
checkUnevolvedModel(EntityModel model, Environment env)2227         void checkUnevolvedModel(EntityModel model, Environment env) {
2228             checkEntity(true, model, env, NAME, 0, null);
2229             checkVersions(model, NAME, 0);
2230         }
2231 
2232         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2233         void readRawObjects(RawStore store,
2234                             boolean expectEvolved,
2235                             boolean expectUpdated)
2236             throws DatabaseException {
2237 
2238             if (expectEvolved) {
2239                 TestCase.fail();
2240             }
2241             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2242             checkRawFields(obj, "key", 99, "ff", (char) 88);
2243         }
2244     }
2245 
2246     @Entity(version=1)
2247     static class DisallowNonKeyField_Short2short
2248         extends EvolveCase {
2249 
2250         private static final String NAME =
2251             DisallowNonKeyField_Short2short.class.getName();
2252 
2253         @PrimaryKey
2254         int key = 99;
2255 
2256         short ff;
2257 
2258         @Override
getStoreOpenException()2259         public String getStoreOpenException() {
2260             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_Short2short version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_Short2short version: 1 Error: Old field type: java.lang.Short is not compatible with the new type: short for field: ff";
2261         }
2262 
2263         @Override
checkUnevolvedModel(EntityModel model, Environment env)2264         void checkUnevolvedModel(EntityModel model, Environment env) {
2265             checkEntity(true, model, env, NAME, 0, null);
2266             checkVersions(model, NAME, 0);
2267         }
2268 
2269         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2270         void readRawObjects(RawStore store,
2271                             boolean expectEvolved,
2272                             boolean expectUpdated)
2273             throws DatabaseException {
2274 
2275             if (expectEvolved) {
2276                 TestCase.fail();
2277             }
2278             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2279             checkRawFields(obj, "key", 99, "ff", (short) 88);
2280         }
2281     }
2282 
2283     @Entity(version=1)
2284     static class DisallowNonKeyField_Integer2int
2285         extends EvolveCase {
2286 
2287         private static final String NAME =
2288             DisallowNonKeyField_Integer2int.class.getName();
2289 
2290         @PrimaryKey
2291         int key = 99;
2292 
2293         int ff;
2294 
2295         @Override
getStoreOpenException()2296         public String getStoreOpenException() {
2297             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_Integer2int version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_Integer2int version: 1 Error: Old field type: java.lang.Integer is not compatible with the new type: int for field: ff";
2298         }
2299 
2300         @Override
checkUnevolvedModel(EntityModel model, Environment env)2301         void checkUnevolvedModel(EntityModel model, Environment env) {
2302             checkEntity(true, model, env, NAME, 0, null);
2303             checkVersions(model, NAME, 0);
2304         }
2305 
2306         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2307         void readRawObjects(RawStore store,
2308                             boolean expectEvolved,
2309                             boolean expectUpdated)
2310             throws DatabaseException {
2311 
2312             if (expectEvolved) {
2313                 TestCase.fail();
2314             }
2315             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2316             checkRawFields(obj, "key", 99, "ff", 88);
2317         }
2318     }
2319 
2320     @Entity(version=1)
2321     static class DisallowNonKeyField_Long2long
2322         extends EvolveCase {
2323 
2324         private static final String NAME =
2325             DisallowNonKeyField_Long2long.class.getName();
2326 
2327         @PrimaryKey
2328         int key = 99;
2329 
2330         long ff;
2331 
2332         @Override
getStoreOpenException()2333         public String getStoreOpenException() {
2334             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_Long2long version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_Long2long version: 1 Error: Old field type: java.lang.Long is not compatible with the new type: long for field: ff";
2335         }
2336 
2337         @Override
checkUnevolvedModel(EntityModel model, Environment env)2338         void checkUnevolvedModel(EntityModel model, Environment env) {
2339             checkEntity(true, model, env, NAME, 0, null);
2340             checkVersions(model, NAME, 0);
2341         }
2342 
2343         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2344         void readRawObjects(RawStore store,
2345                             boolean expectEvolved,
2346                             boolean expectUpdated)
2347             throws DatabaseException {
2348 
2349             if (expectEvolved) {
2350                 TestCase.fail();
2351             }
2352             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2353             checkRawFields(obj, "key", 99, "ff", (long) 88);
2354         }
2355     }
2356 
2357     @Entity(version=1)
2358     static class DisallowNonKeyField_Float2float
2359         extends EvolveCase {
2360 
2361         private static final String NAME =
2362             DisallowNonKeyField_Float2float.class.getName();
2363 
2364         @PrimaryKey
2365         int key = 99;
2366 
2367         float ff;
2368 
2369         @Override
getStoreOpenException()2370         public String getStoreOpenException() {
2371             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_Float2float version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_Float2float version: 1 Error: Old field type: java.lang.Float is not compatible with the new type: float for field: ff";
2372         }
2373 
2374         @Override
checkUnevolvedModel(EntityModel model, Environment env)2375         void checkUnevolvedModel(EntityModel model, Environment env) {
2376             checkEntity(true, model, env, NAME, 0, null);
2377             checkVersions(model, NAME, 0);
2378         }
2379 
2380         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2381         void readRawObjects(RawStore store,
2382                             boolean expectEvolved,
2383                             boolean expectUpdated)
2384             throws DatabaseException {
2385 
2386             if (expectEvolved) {
2387                 TestCase.fail();
2388             }
2389             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2390             checkRawFields(obj, "key", 99, "ff", (float) 88);
2391         }
2392     }
2393 
2394     @Entity(version=1)
2395     static class DisallowNonKeyField_Double2double
2396         extends EvolveCase {
2397 
2398         private static final String NAME =
2399             DisallowNonKeyField_Double2double.class.getName();
2400 
2401         @PrimaryKey
2402         int key = 99;
2403 
2404         double ff;
2405 
2406         @Override
getStoreOpenException()2407         public String getStoreOpenException() {
2408             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_Double2double version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_Double2double version: 1 Error: Old field type: java.lang.Double is not compatible with the new type: double for field: ff";
2409         }
2410 
2411         @Override
checkUnevolvedModel(EntityModel model, Environment env)2412         void checkUnevolvedModel(EntityModel model, Environment env) {
2413             checkEntity(true, model, env, NAME, 0, null);
2414             checkVersions(model, NAME, 0);
2415         }
2416 
2417         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2418         void readRawObjects(RawStore store,
2419                             boolean expectEvolved,
2420                             boolean expectUpdated)
2421             throws DatabaseException {
2422 
2423             if (expectEvolved) {
2424                 TestCase.fail();
2425             }
2426             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2427             checkRawFields(obj, "key", 99, "ff", (double) 88);
2428         }
2429     }
2430 
2431     @Entity(version=1)
2432     static class DisallowNonKeyField_float2BigInt
2433         extends EvolveCase {
2434 
2435         private static final String NAME =
2436             DisallowNonKeyField_float2BigInt.class.getName();
2437 
2438         @PrimaryKey
2439         int key = 99;
2440 
2441         BigInteger ff;
2442 
2443         @Override
getStoreOpenException()2444         public String getStoreOpenException() {
2445             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_float2BigInt version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_float2BigInt version: 1 Error: Old field type: float is not compatible with the new type: java.math.BigInteger for field: ff";
2446         }
2447 
2448         @Override
checkUnevolvedModel(EntityModel model, Environment env)2449         void checkUnevolvedModel(EntityModel model, Environment env) {
2450             checkEntity(true, model, env, NAME, 0, null);
2451             checkVersions(model, NAME, 0);
2452         }
2453 
2454         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2455         void readRawObjects(RawStore store,
2456                             boolean expectEvolved,
2457                             boolean expectUpdated)
2458             throws DatabaseException {
2459 
2460             if (expectEvolved) {
2461                 TestCase.fail();
2462             }
2463             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2464             checkRawFields(obj, "key", 99, "ff", (float) 88);
2465         }
2466     }
2467 
2468     @Entity(version=1)
2469     static class DisallowNonKeyField_BigInt2long
2470         extends EvolveCase {
2471 
2472         private static final String NAME =
2473             DisallowNonKeyField_BigInt2long.class.getName();
2474 
2475         @PrimaryKey
2476         int key = 99;
2477 
2478         long ff;
2479 
2480         @Override
getStoreOpenException()2481         public String getStoreOpenException() {
2482             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_BigInt2long version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowNonKeyField_BigInt2long version: 1 Error: Old field type: java.math.BigInteger is not compatible with the new type: long for field: ff";
2483         }
2484 
2485         @Override
checkUnevolvedModel(EntityModel model, Environment env)2486         void checkUnevolvedModel(EntityModel model, Environment env) {
2487             checkEntity(true, model, env, NAME, 0, null);
2488             checkVersions(model, NAME, 0);
2489         }
2490 
2491         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2492         void readRawObjects(RawStore store,
2493                             boolean expectEvolved,
2494                             boolean expectUpdated)
2495             throws DatabaseException {
2496 
2497             if (expectEvolved) {
2498                 TestCase.fail();
2499             }
2500             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2501             checkRawFields(obj, "key", 99, "ff", BigInteger.valueOf(88));
2502         }
2503     }
2504 
2505     @Entity(version=1)
2506     static class DisallowSecKeyField_byte2short
2507         extends EvolveCase {
2508 
2509         private static final String NAME =
2510             DisallowSecKeyField_byte2short.class.getName();
2511 
2512         @PrimaryKey
2513         int key = 99;
2514 
2515         @SecondaryKey(relate=ONE_TO_ONE)
2516         short ff;
2517 
2518         @Override
getStoreOpenException()2519         public String getStoreOpenException() {
2520             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_byte2short version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_byte2short version: 1 Error: Old field type: byte is not compatible with the new type: short for field: ff";
2521         }
2522 
2523         @Override
checkUnevolvedModel(EntityModel model, Environment env)2524         void checkUnevolvedModel(EntityModel model, Environment env) {
2525             checkEntity(true, model, env, NAME, 0, "ff");
2526             checkVersions(model, NAME, 0);
2527         }
2528 
2529         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2530         void readRawObjects(RawStore store,
2531                             boolean expectEvolved,
2532                             boolean expectUpdated)
2533             throws DatabaseException {
2534 
2535             if (expectEvolved) {
2536                 TestCase.fail();
2537             }
2538             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2539             checkRawFields(obj, "key", 99, "ff", (byte) 88);
2540         }
2541     }
2542 
2543     @Entity(version=1)
2544     static class DisallowSecKeyField_char2int
2545         extends EvolveCase {
2546 
2547         private static final String NAME =
2548             DisallowSecKeyField_char2int.class.getName();
2549 
2550         @PrimaryKey
2551         int key = 99;
2552 
2553         @SecondaryKey(relate=ONE_TO_ONE)
2554         int ff;
2555 
2556         @Override
getStoreOpenException()2557         public String getStoreOpenException() {
2558             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_char2int version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_char2int version: 1 Error: Old field type: char is not compatible with the new type: int for field: ff";
2559         }
2560 
2561         @Override
checkUnevolvedModel(EntityModel model, Environment env)2562         void checkUnevolvedModel(EntityModel model, Environment env) {
2563             checkEntity(true, model, env, NAME, 0, "ff");
2564             checkVersions(model, NAME, 0);
2565         }
2566 
2567         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2568         void readRawObjects(RawStore store,
2569                             boolean expectEvolved,
2570                             boolean expectUpdated)
2571             throws DatabaseException {
2572 
2573             if (expectEvolved) {
2574                 TestCase.fail();
2575             }
2576             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2577             checkRawFields(obj, "key", 99, "ff", (char) 88);
2578         }
2579     }
2580 
2581     @Entity(version=1)
2582     static class DisallowSecKeyField_short2int
2583         extends EvolveCase {
2584 
2585         private static final String NAME =
2586             DisallowSecKeyField_short2int.class.getName();
2587 
2588         @PrimaryKey
2589         int key = 99;
2590 
2591         @SecondaryKey(relate=ONE_TO_ONE)
2592         int ff;
2593 
2594         @Override
getStoreOpenException()2595         public String getStoreOpenException() {
2596             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_short2int version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_short2int version: 1 Error: Old field type: short is not compatible with the new type: int for field: ff";
2597         }
2598 
2599         @Override
checkUnevolvedModel(EntityModel model, Environment env)2600         void checkUnevolvedModel(EntityModel model, Environment env) {
2601             checkEntity(true, model, env, NAME, 0, "ff");
2602             checkVersions(model, NAME, 0);
2603         }
2604 
2605         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2606         void readRawObjects(RawStore store,
2607                             boolean expectEvolved,
2608                             boolean expectUpdated)
2609             throws DatabaseException {
2610 
2611             if (expectEvolved) {
2612                 TestCase.fail();
2613             }
2614             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2615             checkRawFields(obj, "key", 99, "ff", (short) 88);
2616         }
2617     }
2618 
2619     @Entity(version=1)
2620     static class DisallowSecKeyField_int2long
2621         extends EvolveCase {
2622 
2623         private static final String NAME =
2624             DisallowSecKeyField_int2long.class.getName();
2625 
2626         @PrimaryKey
2627         int key = 99;
2628 
2629         @SecondaryKey(relate=ONE_TO_ONE)
2630         long ff;
2631 
2632         @Override
getStoreOpenException()2633         public String getStoreOpenException() {
2634             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_int2long version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_int2long version: 1 Error: Old field type: int is not compatible with the new type: long for field: ff";
2635         }
2636 
2637         @Override
checkUnevolvedModel(EntityModel model, Environment env)2638         void checkUnevolvedModel(EntityModel model, Environment env) {
2639             checkEntity(true, model, env, NAME, 0, "ff");
2640             checkVersions(model, NAME, 0);
2641         }
2642 
2643         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2644         void readRawObjects(RawStore store,
2645                             boolean expectEvolved,
2646                             boolean expectUpdated)
2647             throws DatabaseException {
2648 
2649             if (expectEvolved) {
2650                 TestCase.fail();
2651             }
2652             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2653             checkRawFields(obj, "key", 99, "ff", 88);
2654         }
2655     }
2656 
2657     @Entity(version=1)
2658     static class DisallowSecKeyField_long2float
2659         extends EvolveCase {
2660 
2661         private static final String NAME =
2662             DisallowSecKeyField_long2float.class.getName();
2663 
2664         @PrimaryKey
2665         int key = 99;
2666 
2667         @SecondaryKey(relate=ONE_TO_ONE)
2668         float ff;
2669 
2670         @Override
getStoreOpenException()2671         public String getStoreOpenException() {
2672             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_long2float version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_long2float version: 1 Error: Old field type: long is not compatible with the new type: float for field: ff";
2673         }
2674 
2675         @Override
checkUnevolvedModel(EntityModel model, Environment env)2676         void checkUnevolvedModel(EntityModel model, Environment env) {
2677             checkEntity(true, model, env, NAME, 0, "ff");
2678             checkVersions(model, NAME, 0);
2679         }
2680 
2681         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2682         void readRawObjects(RawStore store,
2683                             boolean expectEvolved,
2684                             boolean expectUpdated)
2685             throws DatabaseException {
2686 
2687             if (expectEvolved) {
2688                 TestCase.fail();
2689             }
2690             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2691             checkRawFields(obj, "key", 99, "ff", (long) 88);
2692         }
2693     }
2694 
2695     @Entity(version=1)
2696     static class DisallowSecKeyField_float2double
2697         extends EvolveCase {
2698 
2699         private static final String NAME =
2700             DisallowSecKeyField_float2double.class.getName();
2701 
2702         @PrimaryKey
2703         int key = 99;
2704 
2705         @SecondaryKey(relate=ONE_TO_ONE)
2706         double ff;
2707 
2708         @Override
getStoreOpenException()2709         public String getStoreOpenException() {
2710             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_float2double version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_float2double version: 1 Error: Old field type: float is not compatible with the new type: double for field: ff";
2711         }
2712 
2713         @Override
checkUnevolvedModel(EntityModel model, Environment env)2714         void checkUnevolvedModel(EntityModel model, Environment env) {
2715             checkEntity(true, model, env, NAME, 0, "ff");
2716             checkVersions(model, NAME, 0);
2717         }
2718 
2719         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2720         void readRawObjects(RawStore store,
2721                             boolean expectEvolved,
2722                             boolean expectUpdated)
2723             throws DatabaseException {
2724 
2725             if (expectEvolved) {
2726                 TestCase.fail();
2727             }
2728             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2729             checkRawFields(obj, "key", 99, "ff", (float) 88);
2730         }
2731     }
2732 
2733     @Entity(version=1)
2734     static class DisallowSecKeyField_Byte2short2
2735         extends EvolveCase {
2736 
2737         private static final String NAME =
2738             DisallowSecKeyField_Byte2short2.class.getName();
2739 
2740         @PrimaryKey
2741         int key = 99;
2742 
2743         @SecondaryKey(relate=ONE_TO_ONE)
2744         short ff;
2745 
2746         @Override
getStoreOpenException()2747         public String getStoreOpenException() {
2748             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_Byte2short2 version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_Byte2short2 version: 1 Error: Old field type: java.lang.Byte is not compatible with the new type: short for field: ff";
2749         }
2750 
2751         @Override
checkUnevolvedModel(EntityModel model, Environment env)2752         void checkUnevolvedModel(EntityModel model, Environment env) {
2753             checkEntity(true, model, env, NAME, 0, "ff");
2754             checkVersions(model, NAME, 0);
2755         }
2756 
2757         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2758         void readRawObjects(RawStore store,
2759                             boolean expectEvolved,
2760                             boolean expectUpdated)
2761             throws DatabaseException {
2762 
2763             if (expectEvolved) {
2764                 TestCase.fail();
2765             }
2766             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2767             checkRawFields(obj, "key", 99, "ff", (byte) 88);
2768         }
2769     }
2770 
2771     @Entity(version=1)
2772     static class DisallowSecKeyField_Character2int
2773         extends EvolveCase {
2774 
2775         private static final String NAME =
2776             DisallowSecKeyField_Character2int.class.getName();
2777 
2778         @PrimaryKey
2779         int key = 99;
2780 
2781         @SecondaryKey(relate=ONE_TO_ONE)
2782         int ff;
2783 
2784         @Override
getStoreOpenException()2785         public String getStoreOpenException() {
2786             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_Character2int version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_Character2int version: 1 Error: Old field type: java.lang.Character is not compatible with the new type: int for field: ff";
2787         }
2788 
2789         @Override
checkUnevolvedModel(EntityModel model, Environment env)2790         void checkUnevolvedModel(EntityModel model, Environment env) {
2791             checkEntity(true, model, env, NAME, 0, "ff");
2792             checkVersions(model, NAME, 0);
2793         }
2794 
2795         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2796         void readRawObjects(RawStore store,
2797                             boolean expectEvolved,
2798                             boolean expectUpdated)
2799             throws DatabaseException {
2800 
2801             if (expectEvolved) {
2802                 TestCase.fail();
2803             }
2804             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2805             checkRawFields(obj, "key", 99, "ff", (char) 88);
2806         }
2807     }
2808 
2809     @Entity(version=1)
2810     static class DisallowSecKeyField_Short2int2
2811         extends EvolveCase {
2812 
2813         private static final String NAME =
2814             DisallowSecKeyField_Short2int2.class.getName();
2815 
2816         @PrimaryKey
2817         int key = 99;
2818 
2819         @SecondaryKey(relate=ONE_TO_ONE)
2820         int ff;
2821 
2822         @Override
getStoreOpenException()2823         public String getStoreOpenException() {
2824             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_Short2int2 version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_Short2int2 version: 1 Error: Old field type: java.lang.Short is not compatible with the new type: int for field: ff";
2825         }
2826 
2827         @Override
checkUnevolvedModel(EntityModel model, Environment env)2828         void checkUnevolvedModel(EntityModel model, Environment env) {
2829             checkEntity(true, model, env, NAME, 0, "ff");
2830             checkVersions(model, NAME, 0);
2831         }
2832 
2833         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2834         void readRawObjects(RawStore store,
2835                             boolean expectEvolved,
2836                             boolean expectUpdated)
2837             throws DatabaseException {
2838 
2839             if (expectEvolved) {
2840                 TestCase.fail();
2841             }
2842             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2843             checkRawFields(obj, "key", 99, "ff", (short) 88);
2844         }
2845     }
2846 
2847     @Entity(version=1)
2848     static class DisallowSecKeyField_Integer2long
2849         extends EvolveCase {
2850 
2851         private static final String NAME =
2852             DisallowSecKeyField_Integer2long.class.getName();
2853 
2854         @PrimaryKey
2855         int key = 99;
2856 
2857         @SecondaryKey(relate=ONE_TO_ONE)
2858         long ff;
2859 
2860         @Override
getStoreOpenException()2861         public String getStoreOpenException() {
2862             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_Integer2long version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_Integer2long version: 1 Error: Old field type: java.lang.Integer is not compatible with the new type: long for field: ff";
2863         }
2864 
2865         @Override
checkUnevolvedModel(EntityModel model, Environment env)2866         void checkUnevolvedModel(EntityModel model, Environment env) {
2867             checkEntity(true, model, env, NAME, 0, "ff");
2868             checkVersions(model, NAME, 0);
2869         }
2870 
2871         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2872         void readRawObjects(RawStore store,
2873                             boolean expectEvolved,
2874                             boolean expectUpdated)
2875             throws DatabaseException {
2876 
2877             if (expectEvolved) {
2878                 TestCase.fail();
2879             }
2880             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2881             checkRawFields(obj, "key", 99, "ff", 88);
2882         }
2883     }
2884 
2885     @Entity(version=1)
2886     static class DisallowSecKeyField_Long2float2
2887         extends EvolveCase {
2888 
2889         private static final String NAME =
2890             DisallowSecKeyField_Long2float2.class.getName();
2891 
2892         @PrimaryKey
2893         int key = 99;
2894 
2895         @SecondaryKey(relate=ONE_TO_ONE)
2896         float ff;
2897 
2898         @Override
getStoreOpenException()2899         public String getStoreOpenException() {
2900             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_Long2float2 version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_Long2float2 version: 1 Error: Old field type: java.lang.Long is not compatible with the new type: float for field: ff";
2901         }
2902 
2903         @Override
checkUnevolvedModel(EntityModel model, Environment env)2904         void checkUnevolvedModel(EntityModel model, Environment env) {
2905             checkEntity(true, model, env, NAME, 0, "ff");
2906             checkVersions(model, NAME, 0);
2907         }
2908 
2909         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2910         void readRawObjects(RawStore store,
2911                             boolean expectEvolved,
2912                             boolean expectUpdated)
2913             throws DatabaseException {
2914 
2915             if (expectEvolved) {
2916                 TestCase.fail();
2917             }
2918             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2919             checkRawFields(obj, "key", 99, "ff", (long) 88);
2920         }
2921     }
2922 
2923     @Entity(version=1)
2924     static class DisallowSecKeyField_Float2double2
2925         extends EvolveCase {
2926 
2927         private static final String NAME =
2928             DisallowSecKeyField_Float2double2.class.getName();
2929 
2930         @PrimaryKey
2931         int key = 99;
2932 
2933         @SecondaryKey(relate=ONE_TO_ONE)
2934         double ff;
2935 
2936         @Override
getStoreOpenException()2937         public String getStoreOpenException() {
2938             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_Float2double2 version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_Float2double2 version: 1 Error: Old field type: java.lang.Float is not compatible with the new type: double for field: ff";
2939         }
2940 
2941         @Override
checkUnevolvedModel(EntityModel model, Environment env)2942         void checkUnevolvedModel(EntityModel model, Environment env) {
2943             checkEntity(true, model, env, NAME, 0, "ff");
2944             checkVersions(model, NAME, 0);
2945         }
2946 
2947         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2948         void readRawObjects(RawStore store,
2949                             boolean expectEvolved,
2950                             boolean expectUpdated)
2951             throws DatabaseException {
2952 
2953             if (expectEvolved) {
2954                 TestCase.fail();
2955             }
2956             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2957             checkRawFields(obj, "key", 99, "ff", (float) 88);
2958         }
2959     }
2960 
2961     @Entity(version=1)
2962     static class DisallowSecKeyField_int2BigInt
2963         extends EvolveCase {
2964 
2965         private static final String NAME =
2966             DisallowSecKeyField_int2BigInt.class.getName();
2967 
2968         @PrimaryKey
2969         int key = 99;
2970 
2971         @SecondaryKey(relate=ONE_TO_ONE)
2972         BigInteger ff;
2973 
2974         @Override
getStoreOpenException()2975         public String getStoreOpenException() {
2976             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_int2BigInt version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowSecKeyField_int2BigInt version: 1 Error: Old field type: int is not compatible with the new type: java.math.BigInteger for field: ff";
2977         }
2978 
2979         @Override
checkUnevolvedModel(EntityModel model, Environment env)2980         void checkUnevolvedModel(EntityModel model, Environment env) {
2981             checkEntity(true, model, env, NAME, 0, "ff");
2982             checkVersions(model, NAME, 0);
2983         }
2984 
2985         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)2986         void readRawObjects(RawStore store,
2987                             boolean expectEvolved,
2988                             boolean expectUpdated)
2989             throws DatabaseException {
2990 
2991             if (expectEvolved) {
2992                 TestCase.fail();
2993             }
2994             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2995             checkRawFields(obj, "key", 99, "ff", 88);
2996         }
2997     }
2998 
2999     // ---
3000 
3001     @Entity(version=1)
3002     static class DisallowPriKeyField_byte2short
3003         extends EvolveCase {
3004 
3005         private static final String NAME =
3006             DisallowPriKeyField_byte2short.class.getName();
3007 
3008         @PrimaryKey
3009         short key;
3010 
3011         @Override
getStoreOpenException()3012         public String getStoreOpenException() {
3013             return "com.sleepycat.persist.evolve.IncompatibleClassException: Type may not be changed for a primary key field or composite key class field when evolving class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_byte2short version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_byte2short version: 1 Error: Old field type: byte is not compatible with the new type: short for field: key";
3014         }
3015 
3016         @Override
checkUnevolvedModel(EntityModel model, Environment env)3017         void checkUnevolvedModel(EntityModel model, Environment env) {
3018             checkEntity(true, model, env, NAME, 0, null);
3019             checkVersions(model, NAME, 0);
3020         }
3021 
3022         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)3023         void readRawObjects(RawStore store,
3024                             boolean expectEvolved,
3025                             boolean expectUpdated)
3026             throws DatabaseException {
3027 
3028             if (expectEvolved) {
3029                 TestCase.fail();
3030             }
3031             RawObject obj = readRaw(store, (byte) 99, NAME, 0, CASECLS, 0);
3032             checkRawFields(obj, "key", (byte) 99);
3033         }
3034     }
3035 
3036     @Entity(version=1)
3037     static class DisallowPriKeyField_char2int
3038         extends EvolveCase {
3039 
3040         private static final String NAME =
3041             DisallowPriKeyField_char2int.class.getName();
3042 
3043         @PrimaryKey
3044         int key;
3045 
3046         @Override
getStoreOpenException()3047         public String getStoreOpenException() {
3048             return "com.sleepycat.persist.evolve.IncompatibleClassException: Type may not be changed for a primary key field or composite key class field when evolving class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_char2int version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_char2int version: 1 Error: Old field type: char is not compatible with the new type: int for field: key";
3049         }
3050 
3051         @Override
checkUnevolvedModel(EntityModel model, Environment env)3052         void checkUnevolvedModel(EntityModel model, Environment env) {
3053             checkEntity(true, model, env, NAME, 0, null);
3054             checkVersions(model, NAME, 0);
3055         }
3056 
3057         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)3058         void readRawObjects(RawStore store,
3059                             boolean expectEvolved,
3060                             boolean expectUpdated)
3061             throws DatabaseException {
3062 
3063             if (expectEvolved) {
3064                 TestCase.fail();
3065             }
3066             RawObject obj = readRaw(store, (char) 99, NAME, 0, CASECLS, 0);
3067             checkRawFields(obj, "key", (char) 99);
3068         }
3069     }
3070 
3071     @Entity(version=1)
3072     static class DisallowPriKeyField_short2int
3073         extends EvolveCase {
3074 
3075         private static final String NAME =
3076             DisallowPriKeyField_short2int.class.getName();
3077 
3078         @PrimaryKey
3079         int key;
3080 
3081         @Override
getStoreOpenException()3082         public String getStoreOpenException() {
3083             return "com.sleepycat.persist.evolve.IncompatibleClassException: Type may not be changed for a primary key field or composite key class field when evolving class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_short2int version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_short2int version: 1 Error: Old field type: short is not compatible with the new type: int for field: key";
3084         }
3085 
3086         @Override
checkUnevolvedModel(EntityModel model, Environment env)3087         void checkUnevolvedModel(EntityModel model, Environment env) {
3088             checkEntity(true, model, env, NAME, 0, null);
3089             checkVersions(model, NAME, 0);
3090         }
3091 
3092         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)3093         void readRawObjects(RawStore store,
3094                             boolean expectEvolved,
3095                             boolean expectUpdated)
3096             throws DatabaseException {
3097 
3098             if (expectEvolved) {
3099                 TestCase.fail();
3100             }
3101             RawObject obj = readRaw(store, (short) 99, NAME, 0, CASECLS, 0);
3102             checkRawFields(obj, "key", (short) 99);
3103         }
3104     }
3105 
3106     @Entity(version=1)
3107     static class DisallowPriKeyField_int2long
3108         extends EvolveCase {
3109 
3110         private static final String NAME =
3111             DisallowPriKeyField_int2long.class.getName();
3112 
3113         @PrimaryKey
3114         long key;
3115 
3116         @Override
getStoreOpenException()3117         public String getStoreOpenException() {
3118             return "com.sleepycat.persist.evolve.IncompatibleClassException: Type may not be changed for a primary key field or composite key class field when evolving class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_int2long version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_int2long version: 1 Error: Old field type: int is not compatible with the new type: long for field: key";
3119         }
3120 
3121         @Override
checkUnevolvedModel(EntityModel model, Environment env)3122         void checkUnevolvedModel(EntityModel model, Environment env) {
3123             checkEntity(true, model, env, NAME, 0, null);
3124             checkVersions(model, NAME, 0);
3125         }
3126 
3127         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)3128         void readRawObjects(RawStore store,
3129                             boolean expectEvolved,
3130                             boolean expectUpdated)
3131             throws DatabaseException {
3132 
3133             if (expectEvolved) {
3134                 TestCase.fail();
3135             }
3136             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
3137             checkRawFields(obj, "key", 99);
3138         }
3139     }
3140 
3141     @Entity(version=1)
3142     static class DisallowPriKeyField_long2float
3143         extends EvolveCase {
3144 
3145         private static final String NAME =
3146             DisallowPriKeyField_long2float.class.getName();
3147 
3148         @PrimaryKey
3149         float key;
3150 
3151         @Override
getStoreOpenException()3152         public String getStoreOpenException() {
3153             return "com.sleepycat.persist.evolve.IncompatibleClassException: Type may not be changed for a primary key field or composite key class field when evolving class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_long2float version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_long2float version: 1 Error: Old field type: long is not compatible with the new type: float for field: key";
3154         }
3155 
3156         @Override
checkUnevolvedModel(EntityModel model, Environment env)3157         void checkUnevolvedModel(EntityModel model, Environment env) {
3158             checkEntity(true, model, env, NAME, 0, null);
3159             checkVersions(model, NAME, 0);
3160         }
3161 
3162         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)3163         void readRawObjects(RawStore store,
3164                             boolean expectEvolved,
3165                             boolean expectUpdated)
3166             throws DatabaseException {
3167 
3168             if (expectEvolved) {
3169                 TestCase.fail();
3170             }
3171             RawObject obj = readRaw(store, (long) 99, NAME, 0, CASECLS, 0);
3172             checkRawFields(obj, "key", (long) 99);
3173         }
3174     }
3175 
3176     @Entity(version=1)
3177     static class DisallowPriKeyField_float2double
3178         extends EvolveCase {
3179 
3180         private static final String NAME =
3181             DisallowPriKeyField_float2double.class.getName();
3182 
3183         @PrimaryKey
3184         double key;
3185 
3186         @Override
getStoreOpenException()3187         public String getStoreOpenException() {
3188             return "com.sleepycat.persist.evolve.IncompatibleClassException: Type may not be changed for a primary key field or composite key class field when evolving class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_float2double version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_float2double version: 1 Error: Old field type: float is not compatible with the new type: double for field: key";
3189         }
3190 
3191         @Override
checkUnevolvedModel(EntityModel model, Environment env)3192         void checkUnevolvedModel(EntityModel model, Environment env) {
3193             checkEntity(true, model, env, NAME, 0, null);
3194             checkVersions(model, NAME, 0);
3195         }
3196 
3197         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)3198         void readRawObjects(RawStore store,
3199                             boolean expectEvolved,
3200                             boolean expectUpdated)
3201             throws DatabaseException {
3202 
3203             if (expectEvolved) {
3204                 TestCase.fail();
3205             }
3206             RawObject obj = readRaw(store, (float) 99, NAME, 0, CASECLS, 0);
3207             checkRawFields(obj, "key", (float) 99);
3208         }
3209     }
3210 
3211     @Entity(version=1)
3212     static class DisallowPriKeyField_Byte2short2
3213         extends EvolveCase {
3214 
3215         private static final String NAME =
3216             DisallowPriKeyField_Byte2short2.class.getName();
3217 
3218         @PrimaryKey
3219         short key;
3220 
3221         @Override
getStoreOpenException()3222         public String getStoreOpenException() {
3223             return "com.sleepycat.persist.evolve.IncompatibleClassException: Type may not be changed for a primary key field or composite key class field when evolving class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_Byte2short2 version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_Byte2short2 version: 1 Error: Old field type: java.lang.Byte is not compatible with the new type: short for field: key";
3224         }
3225 
3226         @Override
checkUnevolvedModel(EntityModel model, Environment env)3227         void checkUnevolvedModel(EntityModel model, Environment env) {
3228             checkEntity(true, model, env, NAME, 0, null);
3229             checkVersions(model, NAME, 0);
3230         }
3231 
3232         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)3233         void readRawObjects(RawStore store,
3234                             boolean expectEvolved,
3235                             boolean expectUpdated)
3236             throws DatabaseException {
3237 
3238             if (expectEvolved) {
3239                 TestCase.fail();
3240             }
3241             RawObject obj = readRaw(store, (byte) 99, NAME, 0, CASECLS, 0);
3242             checkRawFields(obj, "key", (byte) 99);
3243         }
3244     }
3245 
3246     @Entity(version=1)
3247     static class DisallowPriKeyField_Character2int
3248         extends EvolveCase {
3249 
3250         private static final String NAME =
3251             DisallowPriKeyField_Character2int.class.getName();
3252 
3253         @PrimaryKey
3254         int key;
3255 
3256         @Override
getStoreOpenException()3257         public String getStoreOpenException() {
3258             return "com.sleepycat.persist.evolve.IncompatibleClassException: Type may not be changed for a primary key field or composite key class field when evolving class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_Character2int version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_Character2int version: 1 Error: Old field type: java.lang.Character is not compatible with the new type: int for field: key";
3259         }
3260 
3261         @Override
checkUnevolvedModel(EntityModel model, Environment env)3262         void checkUnevolvedModel(EntityModel model, Environment env) {
3263             checkEntity(true, model, env, NAME, 0, null);
3264             checkVersions(model, NAME, 0);
3265         }
3266 
3267         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)3268         void readRawObjects(RawStore store,
3269                             boolean expectEvolved,
3270                             boolean expectUpdated)
3271             throws DatabaseException {
3272 
3273             if (expectEvolved) {
3274                 TestCase.fail();
3275             }
3276             RawObject obj = readRaw(store, (char) 99, NAME, 0, CASECLS, 0);
3277             checkRawFields(obj, "key", (char) 99);
3278         }
3279     }
3280 
3281     @Entity(version=1)
3282     static class DisallowPriKeyField_Short2int2
3283         extends EvolveCase {
3284 
3285         private static final String NAME =
3286             DisallowPriKeyField_Short2int2.class.getName();
3287 
3288         @PrimaryKey
3289         int key;
3290 
3291         @Override
getStoreOpenException()3292         public String getStoreOpenException() {
3293             return "com.sleepycat.persist.evolve.IncompatibleClassException: Type may not be changed for a primary key field or composite key class field when evolving class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_Short2int2 version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_Short2int2 version: 1 Error: Old field type: java.lang.Short is not compatible with the new type: int for field: key";
3294         }
3295 
3296         @Override
checkUnevolvedModel(EntityModel model, Environment env)3297         void checkUnevolvedModel(EntityModel model, Environment env) {
3298             checkEntity(true, model, env, NAME, 0, null);
3299             checkVersions(model, NAME, 0);
3300         }
3301 
3302         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)3303         void readRawObjects(RawStore store,
3304                             boolean expectEvolved,
3305                             boolean expectUpdated)
3306             throws DatabaseException {
3307 
3308             if (expectEvolved) {
3309                 TestCase.fail();
3310             }
3311             RawObject obj = readRaw(store, (short) 99, NAME, 0, CASECLS, 0);
3312             checkRawFields(obj, "key", (short) 99);
3313         }
3314     }
3315 
3316     @Entity(version=1)
3317     static class DisallowPriKeyField_Integer2long
3318         extends EvolveCase {
3319 
3320         private static final String NAME =
3321             DisallowPriKeyField_Integer2long.class.getName();
3322 
3323         @PrimaryKey
3324         long key;
3325 
3326         @Override
getStoreOpenException()3327         public String getStoreOpenException() {
3328             return "com.sleepycat.persist.evolve.IncompatibleClassException: Type may not be changed for a primary key field or composite key class field when evolving class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_Integer2long version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_Integer2long version: 1 Error: Old field type: java.lang.Integer is not compatible with the new type: long for field: key";
3329         }
3330 
3331         @Override
checkUnevolvedModel(EntityModel model, Environment env)3332         void checkUnevolvedModel(EntityModel model, Environment env) {
3333             checkEntity(true, model, env, NAME, 0, null);
3334             checkVersions(model, NAME, 0);
3335         }
3336 
3337         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)3338         void readRawObjects(RawStore store,
3339                             boolean expectEvolved,
3340                             boolean expectUpdated)
3341             throws DatabaseException {
3342 
3343             if (expectEvolved) {
3344                 TestCase.fail();
3345             }
3346             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
3347             checkRawFields(obj, "key", 99);
3348         }
3349     }
3350 
3351     @Entity(version=1)
3352     static class DisallowPriKeyField_Long2float2
3353         extends EvolveCase {
3354 
3355         private static final String NAME =
3356             DisallowPriKeyField_Long2float2.class.getName();
3357 
3358         @PrimaryKey
3359         float key;
3360 
3361         @Override
getStoreOpenException()3362         public String getStoreOpenException() {
3363             return "com.sleepycat.persist.evolve.IncompatibleClassException: Type may not be changed for a primary key field or composite key class field when evolving class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_Long2float2 version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_Long2float2 version: 1 Error: Old field type: java.lang.Long is not compatible with the new type: float for field: key";
3364         }
3365 
3366         @Override
checkUnevolvedModel(EntityModel model, Environment env)3367         void checkUnevolvedModel(EntityModel model, Environment env) {
3368             checkEntity(true, model, env, NAME, 0, null);
3369             checkVersions(model, NAME, 0);
3370         }
3371 
3372         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)3373         void readRawObjects(RawStore store,
3374                             boolean expectEvolved,
3375                             boolean expectUpdated)
3376             throws DatabaseException {
3377 
3378             if (expectEvolved) {
3379                 TestCase.fail();
3380             }
3381             RawObject obj = readRaw(store, (long) 99, NAME, 0, CASECLS, 0);
3382             checkRawFields(obj, "key", (long) 99);
3383         }
3384     }
3385 
3386     @Entity(version=1)
3387     static class DisallowPriKeyField_Float2double2
3388         extends EvolveCase {
3389 
3390         private static final String NAME =
3391             DisallowPriKeyField_Float2double2.class.getName();
3392 
3393         @PrimaryKey
3394         double key;
3395 
3396         @Override
getStoreOpenException()3397         public String getStoreOpenException() {
3398             return "com.sleepycat.persist.evolve.IncompatibleClassException: Type may not be changed for a primary key field or composite key class field when evolving class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_Float2double2 version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_Float2double2 version: 1 Error: Old field type: java.lang.Float is not compatible with the new type: double for field: key";
3399         }
3400 
3401         @Override
checkUnevolvedModel(EntityModel model, Environment env)3402         void checkUnevolvedModel(EntityModel model, Environment env) {
3403             checkEntity(true, model, env, NAME, 0, null);
3404             checkVersions(model, NAME, 0);
3405         }
3406 
3407         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)3408         void readRawObjects(RawStore store,
3409                             boolean expectEvolved,
3410                             boolean expectUpdated)
3411             throws DatabaseException {
3412 
3413             if (expectEvolved) {
3414                 TestCase.fail();
3415             }
3416             RawObject obj = readRaw(store, (float) 99, NAME, 0, CASECLS, 0);
3417             checkRawFields(obj, "key", (float) 99);
3418         }
3419     }
3420 
3421     @Entity(version=1)
3422     static class DisallowPriKeyField_Long2BigInt
3423         extends EvolveCase {
3424 
3425         private static final String NAME =
3426             DisallowPriKeyField_Long2BigInt.class.getName();
3427 
3428         @PrimaryKey
3429         BigInteger key;
3430 
3431         @Override
getStoreOpenException()3432         public String getStoreOpenException() {
3433             return "com.sleepycat.persist.evolve.IncompatibleClassException: Type may not be changed for a primary key field or composite key class field when evolving class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_Long2BigInt version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowPriKeyField_Long2BigInt version: 1 Error: Old field type: java.lang.Long is not compatible with the new type: java.math.BigInteger for field: key";
3434         }
3435 
3436         @Override
checkUnevolvedModel(EntityModel model, Environment env)3437         void checkUnevolvedModel(EntityModel model, Environment env) {
3438             checkEntity(true, model, env, NAME, 0, null);
3439             checkVersions(model, NAME, 0);
3440         }
3441 
3442         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)3443         void readRawObjects(RawStore store,
3444                             boolean expectEvolved,
3445                             boolean expectUpdated)
3446             throws DatabaseException {
3447 
3448             if (expectEvolved) {
3449                 TestCase.fail();
3450             }
3451             RawObject obj = readRaw(store, 99L, NAME, 0, CASECLS, 0);
3452             checkRawFields(obj, "key", 99L);
3453         }
3454     }
3455 
3456     @Persistent(version=1)
3457     static class DisallowCompositeKeyField_byte2short_Key {
3458 
3459         @KeyField(1)
3460         int f1 = 1;
3461 
3462         @KeyField(2)
3463         short f2 = 2;
3464 
3465         @KeyField(3)
3466         String f3 = "3";
3467     }
3468 
3469     @Entity
3470     static class DisallowCompositeKeyField_byte2short
3471         extends EvolveCase {
3472 
3473         private static final String NAME =
3474             DisallowCompositeKeyField_byte2short.class.getName();
3475         private static final String NAME2 =
3476             DisallowCompositeKeyField_byte2short_Key.class.getName();
3477 
3478         @PrimaryKey
3479         DisallowCompositeKeyField_byte2short_Key key;
3480 
3481         @Override
getStoreOpenException()3482         public String getStoreOpenException() {
3483             return "com.sleepycat.persist.evolve.IncompatibleClassException: Type may not be changed for a primary key field or composite key class field when evolving class: com.sleepycat.persist.test.EvolveClasses$DisallowCompositeKeyField_byte2short_Key version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowCompositeKeyField_byte2short_Key version: 1 Error: Old field type: byte is not compatible with the new type: short for field: f2";
3484         }
3485 
3486         @Override
checkUnevolvedModel(EntityModel model, Environment env)3487         void checkUnevolvedModel(EntityModel model, Environment env) {
3488             checkEntity(true, model, env, NAME, 0, null);
3489             checkNonEntity(true, model, env, NAME2, 0);
3490             checkVersions(model, NAME, 0);
3491             checkVersions(model, NAME2, 0);
3492         }
3493 
3494         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)3495         void readRawObjects(RawStore store,
3496                             boolean expectEvolved,
3497                             boolean expectUpdated)
3498             throws DatabaseException {
3499 
3500             if (expectEvolved) {
3501                 TestCase.fail();
3502             }
3503             RawType rawKeyType = store.getModel().getRawType(NAME2);
3504             RawObject rawKey = new RawObject
3505                 (rawKeyType,
3506                  makeValues("f1", 1, "f2", (byte) 2, "f3", "3"),
3507                  null);
3508 
3509             RawObject obj = readRaw(store, rawKey, NAME, 0, CASECLS, 0);
3510             checkRawFields(obj, "key", rawKey);
3511         }
3512     }
3513 
3514     @Entity(version=1)
3515     static class AllowPriKeyField_byte2Byte
3516         extends EvolveCase {
3517 
3518         private static final String NAME =
3519             AllowPriKeyField_byte2Byte.class.getName();
3520 
3521         @PrimaryKey
3522         Byte key = 99;
3523 
3524         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)3525         void checkEvolvedModel(EntityModel model,
3526                                Environment env,
3527                                boolean oldTypesExist) {
3528             checkEntity(true, model, env, NAME, 1, null);
3529             if (oldTypesExist) {
3530                 checkVersions(model, NAME, 1, NAME, 0);
3531             } else {
3532                 checkVersions(model, NAME, 1);
3533             }
3534         }
3535 
3536         @Override
readObjects(EntityStore store, boolean doUpdate)3537         void readObjects(EntityStore store, boolean doUpdate)
3538             throws DatabaseException {
3539 
3540             PrimaryIndex<Byte, AllowPriKeyField_byte2Byte>
3541                 index = store.getPrimaryIndex
3542                     (Byte.class,
3543                      AllowPriKeyField_byte2Byte.class);
3544             AllowPriKeyField_byte2Byte obj = index.get(key);
3545             TestCase.assertNotNull(obj);
3546             TestCase.assertEquals(Byte.valueOf((byte) 99), obj.key);
3547 
3548             if (doUpdate) {
3549                 index.put(obj);
3550             }
3551         }
3552 
3553         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)3554         void copyRawObjects(RawStore rawStore, EntityStore newStore)
3555             throws DatabaseException {
3556 
3557             PrimaryIndex<Byte, AllowPriKeyField_byte2Byte>
3558                 index = newStore.getPrimaryIndex
3559                     (Byte.class,
3560                      AllowPriKeyField_byte2Byte.class);
3561             RawObject raw = rawStore.getPrimaryIndex(NAME).get((byte) 99);
3562             index.put((AllowPriKeyField_byte2Byte)
3563                       newStore.getModel().convertRawObject(raw));
3564         }
3565 
3566         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)3567         void readRawObjects(RawStore store,
3568                             boolean expectEvolved,
3569                             boolean expectUpdated)
3570             throws DatabaseException {
3571 
3572             RawObject obj;
3573             if (expectEvolved) {
3574                 obj = readRaw(store, (byte) 99, NAME, 1, CASECLS, 0);
3575             } else {
3576                 obj = readRaw(store, (byte) 99, NAME, 0, CASECLS, 0);
3577             }
3578             checkRawFields(obj, "key", (byte) 99);
3579         }
3580     }
3581 
3582     @Entity(version=1)
3583     static class AllowPriKeyField_Byte2byte2
3584         extends EvolveCase {
3585 
3586         private static final String NAME =
3587             AllowPriKeyField_Byte2byte2.class.getName();
3588 
3589         @PrimaryKey
3590         byte key = 99;
3591 
3592         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)3593         void checkEvolvedModel(EntityModel model,
3594                                Environment env,
3595                                boolean oldTypesExist) {
3596             checkEntity(true, model, env, NAME, 1, null);
3597             if (oldTypesExist) {
3598                 checkVersions(model, NAME, 1, NAME, 0);
3599             } else {
3600                 checkVersions(model, NAME, 1);
3601             }
3602         }
3603 
3604         @Override
readObjects(EntityStore store, boolean doUpdate)3605         void readObjects(EntityStore store, boolean doUpdate)
3606             throws DatabaseException {
3607 
3608             PrimaryIndex<Byte, AllowPriKeyField_Byte2byte2>
3609                 index = store.getPrimaryIndex
3610                     (Byte.class,
3611                      AllowPriKeyField_Byte2byte2.class);
3612             AllowPriKeyField_Byte2byte2 obj = index.get(key);
3613             TestCase.assertNotNull(obj);
3614             TestCase.assertEquals((byte) 99, obj.key);
3615 
3616             if (doUpdate) {
3617                 index.put(obj);
3618             }
3619         }
3620 
3621         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)3622         void copyRawObjects(RawStore rawStore, EntityStore newStore)
3623             throws DatabaseException {
3624 
3625             PrimaryIndex<Byte, AllowPriKeyField_Byte2byte2>
3626                 index = newStore.getPrimaryIndex
3627                     (Byte.class,
3628                      AllowPriKeyField_Byte2byte2.class);
3629             RawObject raw = rawStore.getPrimaryIndex(NAME).get((byte) 99);
3630             index.put((AllowPriKeyField_Byte2byte2)
3631                       newStore.getModel().convertRawObject(raw));
3632         }
3633 
3634         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)3635         void readRawObjects(RawStore store,
3636                             boolean expectEvolved,
3637                             boolean expectUpdated)
3638             throws DatabaseException {
3639 
3640             RawObject obj;
3641             if (expectEvolved) {
3642                 obj = readRaw(store, (byte) 99, NAME, 1, CASECLS, 0);
3643             } else {
3644                 obj = readRaw(store, (byte) 99, NAME, 0, CASECLS, 0);
3645             }
3646             checkRawFields(obj, "key", (byte) 99);
3647         }
3648     }
3649 
3650     @Persistent(version=1)
3651     static class AllowFieldTypeChanges_Key {
3652 
AllowFieldTypeChanges_Key()3653         AllowFieldTypeChanges_Key() {
3654             this(false);
3655         }
3656 
AllowFieldTypeChanges_Key(boolean init)3657         AllowFieldTypeChanges_Key(boolean init) {
3658             if (init) {
3659                 f1 = true;
3660                 f2 = (byte) 2;
3661                 f3 = (short) 3;
3662                 f4 = 4;
3663                 f5 = 5L;
3664                 f6 = 6F;
3665                 f7 = 7D;
3666                 f8 = (char) 8;
3667                 f9 = true;
3668                 f10 = (byte) 10;
3669                 f11 = (short) 11;
3670                 f12 = 12;
3671                 f13 = 13L;
3672                 f14 = 14F;
3673                 f15 = 15D;
3674                 f16 = (char) 16;
3675             }
3676         }
3677 
3678         @KeyField(1)
3679         boolean f1;
3680 
3681         @KeyField(2)
3682         byte f2;
3683 
3684         @KeyField(3)
3685         short f3;
3686 
3687         @KeyField(4)
3688         int f4;
3689 
3690         @KeyField(5)
3691         long f5;
3692 
3693         @KeyField(6)
3694         float f6;
3695 
3696         @KeyField(7)
3697         double f7;
3698 
3699         @KeyField(8)
3700         char f8;
3701 
3702         @KeyField(9)
3703         Boolean f9;
3704 
3705         @KeyField(10)
3706         Byte f10;
3707 
3708         @KeyField(11)
3709         Short f11;
3710 
3711         @KeyField(12)
3712         Integer f12;
3713 
3714         @KeyField(13)
3715         Long f13;
3716 
3717         @KeyField(14)
3718         Float f14;
3719 
3720         @KeyField(15)
3721         Double f15;
3722 
3723         @KeyField(16)
3724         Character f16;
3725     }
3726 
3727     @Persistent(version=1)
3728     static class AllowFieldTypeChanges_Base
3729         extends EvolveCase {
3730 
3731         @SecondaryKey(relate=ONE_TO_ONE)
3732         AllowFieldTypeChanges_Key kComposite1;
3733 
3734         Integer f_long2Integer;
3735         Long f_String2Long;
3736     }
3737 
3738     /**
3739      * Allow field type changes: automatic widening, supported widening,
3740      * and Converter mutations.  Also tests primary and secondary key field
3741      * renaming.
3742      */
3743     @Entity(version=1)
3744     static class AllowFieldTypeChanges
3745         extends AllowFieldTypeChanges_Base {
3746 
3747         private static final String NAME =
3748             AllowFieldTypeChanges.class.getName();
3749         private static final String NAME2 =
3750             AllowFieldTypeChanges_Base.class.getName();
3751         private static final String NAME3 =
3752             AllowFieldTypeChanges_Key.class.getName();
3753 
3754         @PrimaryKey
3755         Integer pkeyInt1;
3756 
3757         @SecondaryKey(relate=ONE_TO_ONE)
3758         Boolean kBoolean1;
3759 
3760         @SecondaryKey(relate=ONE_TO_ONE)
3761         Byte kByte1;
3762 
3763         @SecondaryKey(relate=ONE_TO_ONE)
3764         Short kShort1;
3765 
3766         @SecondaryKey(relate=ONE_TO_ONE)
3767         Integer kInt1;
3768 
3769         @SecondaryKey(relate=ONE_TO_ONE)
3770         Long kLong1;
3771 
3772         @SecondaryKey(relate=ONE_TO_ONE)
3773         Float kFloat1;
3774 
3775         @SecondaryKey(relate=ONE_TO_ONE)
3776         Double kDouble1;
3777 
3778         @SecondaryKey(relate=ONE_TO_ONE)
3779         Character kCharacter1;
3780 
3781         short f01;
3782         int f02;
3783         long f03;
3784         float f04;
3785         double f06;
3786         int f07;
3787         long f08;
3788         float f09;
3789         double f10;
3790         int f11;
3791         long f12;
3792         float f13;
3793         double f14;
3794         long f15;
3795         float f16;
3796         double f17;
3797         float f18;
3798         double f19;
3799         double f20;
3800 
3801         Short f21;
3802         Integer f22;
3803         Long f23;
3804         Float f24;
3805         Double f26;
3806         Integer f27;
3807         Long f28;
3808         Float f29;
3809         Double f30;
3810         Integer f31;
3811         Long f32;
3812         Float f33;
3813         Double f34;
3814         Long f35;
3815         Float f36;
3816         Double f37;
3817         Float f38;
3818         Double f39;
3819         Double f40;
3820 
3821         Short f41;
3822         Integer f42;
3823         Long f43;
3824         Float f44;
3825         Double f46;
3826         Integer f47;
3827         Long f48;
3828         Float f49;
3829         Double f50;
3830         Integer f51;
3831         Long f52;
3832         Float f53;
3833         Double f54;
3834         Long f55;
3835         Float f56;
3836         Double f57;
3837         Float f58;
3838         Double f59;
3839         Double f60;
3840 
3841         BigInteger f70;
3842         BigInteger f71;
3843         BigInteger f72;
3844         BigInteger f73;
3845         BigInteger f74;
3846         BigInteger f75;
3847         BigInteger f76;
3848         BigInteger f77;
3849         BigInteger f78;
3850         BigInteger f79;
3851 
3852         int f_long2int;
3853         long f_String2long;
3854 
3855         @Override
getMutations()3856         Mutations getMutations() {
3857             Mutations m = new Mutations();
3858             m.addRenamer(new Renamer(NAME, 0, "pkeyint", "pkeyInt1"));
3859             m.addRenamer(new Renamer(NAME, 0, "kboolean", "kBoolean1"));
3860             m.addRenamer(new Renamer(NAME, 0, "kbyte", "kByte1"));
3861             m.addRenamer(new Renamer(NAME, 0, "kshort", "kShort1"));
3862             m.addRenamer(new Renamer(NAME, 0, "kint", "kInt1"));
3863             m.addRenamer(new Renamer(NAME, 0, "klong", "kLong1"));
3864             m.addRenamer(new Renamer(NAME, 0, "kfloat", "kFloat1"));
3865             m.addRenamer(new Renamer(NAME, 0, "kdouble", "kDouble1"));
3866             m.addRenamer(new Renamer(NAME, 0, "kchar", "kCharacter1"));
3867             m.addRenamer(new Renamer(NAME2, 0, "kcomposite", "kComposite1"));
3868 
3869             Conversion conv1 = new MyConversion1();
3870             Conversion conv2 = new MyConversion2();
3871 
3872             m.addConverter(new Converter(NAME, 0, "f_long2int", conv1));
3873             m.addConverter(new Converter(NAME, 0, "f_String2long", conv2));
3874             m.addConverter(new Converter(NAME2, 0, "f_long2Integer", conv1));
3875             m.addConverter(new Converter(NAME2, 0, "f_String2Long", conv2));
3876             return m;
3877         }
3878 
3879         @SuppressWarnings("serial")
3880         static class MyConversion1 implements Conversion {
3881 
initialize(EntityModel model)3882             public void initialize(EntityModel model) {}
3883 
convert(Object o)3884             public Object convert(Object o) {
3885                 return ((Long) o).intValue();
3886             }
3887 
3888             @Override
equals(Object other)3889             public boolean equals(Object other) { return true; }
3890         }
3891 
3892         @SuppressWarnings("serial")
3893         static class MyConversion2 implements Conversion {
3894 
initialize(EntityModel model)3895             public void initialize(EntityModel model) {}
3896 
convert(Object o)3897             public Object convert(Object o) {
3898                 return Long.valueOf((String) o);
3899             }
3900 
3901             @Override
equals(Object other)3902             public boolean equals(Object other) { return true; }
3903         }
3904 
3905         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)3906         void checkEvolvedModel(EntityModel model,
3907                                Environment env,
3908                                boolean oldTypesExist) {
3909             checkEntity(true, model, env, NAME, 1, null);
3910             checkNonEntity(true, model, env, NAME2, 1);
3911             if (oldTypesExist) {
3912                 checkVersions(model, NAME, 1, NAME, 0);
3913                 checkVersions(model, NAME2, 1, NAME2, 0);
3914                 checkVersions(model, NAME3, 1, NAME3, 0);
3915             } else {
3916                 checkVersions(model, NAME, 1);
3917                 checkVersions(model, NAME2, 1);
3918                 checkVersions(model, NAME3, 1);
3919             }
3920         }
3921 
3922         @Override
readObjects(EntityStore store, boolean doUpdate)3923         void readObjects(EntityStore store, boolean doUpdate)
3924             throws DatabaseException {
3925 
3926             PrimaryIndex<Integer, AllowFieldTypeChanges>
3927                 index = store.getPrimaryIndex
3928                     (Integer.class, AllowFieldTypeChanges.class);
3929             AllowFieldTypeChanges obj = index.get(99);
3930             checkValues(obj);
3931             checkSecondaries(store, index);
3932 
3933             if (doUpdate) {
3934                 index.put(obj);
3935                 checkSecondaries(store, index);
3936             }
3937         }
3938 
3939         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)3940         void copyRawObjects(RawStore rawStore, EntityStore newStore)
3941             throws DatabaseException {
3942 
3943             PrimaryIndex<Integer, AllowFieldTypeChanges>
3944                 index = newStore.getPrimaryIndex
3945                     (Integer.class, AllowFieldTypeChanges.class);
3946             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
3947             index.put((AllowFieldTypeChanges)
3948                       newStore.getModel().convertRawObject(raw));
3949         }
3950 
checkSecondaries(EntityStore store, PrimaryIndex<Integer, AllowFieldTypeChanges> index)3951         private void checkSecondaries(EntityStore store,
3952                                       PrimaryIndex<Integer,
3953                                                    AllowFieldTypeChanges>
3954                                                    index)
3955             throws DatabaseException {
3956 
3957             if (!newMetadataWritten) {
3958                 return;
3959             }
3960             checkValues(store.getSecondaryIndex
3961                 (index, Boolean.class, "kBoolean1").get(true));
3962             checkValues(store.getSecondaryIndex
3963                 (index, Byte.class, "kByte1").get((byte) 77));
3964             checkValues(store.getSecondaryIndex
3965                 (index, Short.class, "kShort1").get((short) 66));
3966             checkValues(store.getSecondaryIndex
3967                 (index, Integer.class, "kInt1").get(55));
3968             checkValues(store.getSecondaryIndex
3969                 (index, Long.class, "kLong1").get((long) 44));
3970             checkValues(store.getSecondaryIndex
3971                 (index, Float.class, "kFloat1").get((float) 33));
3972             checkValues(store.getSecondaryIndex
3973                 (index, Double.class, "kDouble1").get((double) 22));
3974             checkValues(store.getSecondaryIndex
3975                 (index, Character.class, "kCharacter1").get((char) 11));
3976             checkValues(store.getSecondaryIndex
3977                 (index, AllowFieldTypeChanges_Key.class, "kComposite1").get
3978                     (new AllowFieldTypeChanges_Key(true)));
3979         }
3980 
checkValues(AllowFieldTypeChanges obj)3981         private void checkValues(AllowFieldTypeChanges obj) {
3982             TestCase.assertNotNull(obj);
3983             TestCase.assertEquals(obj.pkeyInt1, Integer.valueOf(99));
3984             TestCase.assertEquals(obj.kBoolean1, Boolean.valueOf(true));
3985             TestCase.assertEquals(obj.kByte1, Byte.valueOf((byte) 77));
3986             TestCase.assertEquals(obj.kShort1, Short.valueOf((short) 66));
3987             TestCase.assertEquals(obj.kInt1, Integer.valueOf(55));
3988             TestCase.assertEquals(obj.kLong1, Long.valueOf(44));
3989             TestCase.assertEquals(obj.kFloat1, Float.valueOf(33));
3990             TestCase.assertEquals(obj.kDouble1, Double.valueOf(22));
3991             TestCase.assertEquals(obj.kCharacter1,
3992                                   Character.valueOf((char) 11));
3993 
3994             AllowFieldTypeChanges_Key embed = obj.kComposite1;
3995             TestCase.assertNotNull(embed);
3996             TestCase.assertEquals(embed.f1, true);
3997             TestCase.assertEquals(embed.f2, (byte) 2);
3998             TestCase.assertEquals(embed.f3, (short) 3);
3999             TestCase.assertEquals(embed.f4, 4);
4000             TestCase.assertEquals(embed.f5, 5L);
4001             TestCase.assertEquals(embed.f6, 6F);
4002             TestCase.assertEquals(embed.f7, 7D);
4003             TestCase.assertEquals(embed.f8, (char) 8);
4004             TestCase.assertEquals(embed.f9, Boolean.valueOf(true));
4005             TestCase.assertEquals(embed.f10, Byte.valueOf((byte) 10));
4006             TestCase.assertEquals(embed.f11, Short.valueOf((short) 11));
4007             TestCase.assertEquals(embed.f12, Integer.valueOf(12));
4008             TestCase.assertEquals(embed.f13, Long.valueOf(13L));
4009             TestCase.assertEquals(embed.f14, Float.valueOf(14F));
4010             TestCase.assertEquals(embed.f15, Double.valueOf(15D));
4011             TestCase.assertEquals(embed.f16, Character.valueOf((char) 16));
4012 
4013             TestCase.assertEquals(obj.f01, (short) 1);
4014             TestCase.assertEquals(obj.f02, 2);
4015             TestCase.assertEquals(obj.f03, 3);
4016             TestCase.assertEquals(obj.f04, (float) 4);
4017             TestCase.assertEquals(obj.f06, (double) 6);
4018             TestCase.assertEquals(obj.f07, 7);
4019             TestCase.assertEquals(obj.f08, 8);
4020             TestCase.assertEquals(obj.f09, (float) 9);
4021             TestCase.assertEquals(obj.f10, (double) 10);
4022             TestCase.assertEquals(obj.f11, 11);
4023             TestCase.assertEquals(obj.f12, 12);
4024             TestCase.assertEquals(obj.f13, (float) 13);
4025             TestCase.assertEquals(obj.f14, (double) 14);
4026             TestCase.assertEquals(obj.f15, 15L);
4027             TestCase.assertEquals(obj.f16, 16F);
4028             TestCase.assertEquals(obj.f17, 17D);
4029             TestCase.assertEquals(obj.f18, (float) 18);
4030             TestCase.assertEquals(obj.f19, (double) 19);
4031             TestCase.assertEquals(obj.f20, (double) 20);
4032 
4033             TestCase.assertEquals(obj.f21, Short.valueOf((byte) 21));
4034             TestCase.assertEquals(obj.f22, Integer.valueOf((byte) 22));
4035             TestCase.assertEquals(obj.f23, Long.valueOf((byte) 23));
4036             TestCase.assertEquals(obj.f24, Float.valueOf((byte) 24));
4037             TestCase.assertEquals(obj.f26, Double.valueOf((byte) 26));
4038             TestCase.assertEquals(obj.f27, Integer.valueOf((short) 27));
4039             TestCase.assertEquals(obj.f28, Long.valueOf((short) 28));
4040             TestCase.assertEquals(obj.f29, Float.valueOf((short) 29));
4041             TestCase.assertEquals(obj.f30, Double.valueOf((short) 30));
4042             TestCase.assertEquals(obj.f31, Integer.valueOf((char) 31));
4043             TestCase.assertEquals(obj.f32, Long.valueOf((char) 32));
4044             TestCase.assertEquals(obj.f33, Float.valueOf((char) 33));
4045             TestCase.assertEquals(obj.f34, Double.valueOf((char) 34));
4046             TestCase.assertEquals(obj.f35, Long.valueOf(35));
4047             TestCase.assertEquals(obj.f36, Float.valueOf(36));
4048             TestCase.assertEquals(obj.f37, Double.valueOf(37));
4049             TestCase.assertEquals(obj.f38, Float.valueOf(38));
4050             TestCase.assertEquals(obj.f39, Double.valueOf(39));
4051             TestCase.assertEquals(obj.f40, Double.valueOf(40));
4052 
4053             TestCase.assertEquals(obj.f41, Short.valueOf((byte) 41));
4054             TestCase.assertEquals(obj.f42, Integer.valueOf((byte) 42));
4055             TestCase.assertEquals(obj.f43, Long.valueOf((byte) 43));
4056             TestCase.assertEquals(obj.f44, Float.valueOf((byte) 44));
4057             TestCase.assertEquals(obj.f46, Double.valueOf((byte) 46));
4058             TestCase.assertEquals(obj.f47, Integer.valueOf((short) 47));
4059             TestCase.assertEquals(obj.f48, Long.valueOf((short) 48));
4060             TestCase.assertEquals(obj.f49, Float.valueOf((short) 49));
4061             TestCase.assertEquals(obj.f50, Double.valueOf((short) 50));
4062             TestCase.assertEquals(obj.f51, Integer.valueOf((char) 51));
4063             TestCase.assertEquals(obj.f52, Long.valueOf((char) 52));
4064             TestCase.assertEquals(obj.f53, Float.valueOf((char) 53));
4065             TestCase.assertEquals(obj.f54, Double.valueOf((char) 54));
4066             TestCase.assertEquals(obj.f55, Long.valueOf(55));
4067             TestCase.assertEquals(obj.f56, Float.valueOf(56));
4068             TestCase.assertEquals(obj.f57, Double.valueOf(57));
4069             TestCase.assertEquals(obj.f58, Float.valueOf(58));
4070             TestCase.assertEquals(obj.f59, Double.valueOf(59));
4071             TestCase.assertEquals(obj.f60, Double.valueOf(60));
4072 
4073             TestCase.assertEquals(obj.f70, BigInteger.valueOf(70));
4074             TestCase.assertEquals(obj.f71, BigInteger.valueOf(71));
4075             TestCase.assertEquals(obj.f72, BigInteger.valueOf(72));
4076             TestCase.assertEquals(obj.f73, BigInteger.valueOf(73));
4077             TestCase.assertEquals(obj.f74, BigInteger.valueOf(74));
4078             TestCase.assertEquals(obj.f75, BigInteger.valueOf(75));
4079             TestCase.assertEquals(obj.f76, BigInteger.valueOf(76));
4080             TestCase.assertEquals(obj.f77, BigInteger.valueOf(77));
4081             TestCase.assertEquals(obj.f78, BigInteger.valueOf(78));
4082             TestCase.assertEquals(obj.f79, BigInteger.valueOf(79));
4083 
4084             TestCase.assertEquals(obj.f_long2Integer, Integer.valueOf(111));
4085             TestCase.assertEquals(obj.f_String2Long, Long.valueOf(222));
4086             TestCase.assertEquals(obj.f_long2int, 333);
4087             TestCase.assertEquals(obj.f_String2long, 444L);
4088         }
4089 
4090         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)4091         void readRawObjects(RawStore store,
4092                             boolean expectEvolved,
4093                             boolean expectUpdated)
4094             throws DatabaseException {
4095 
4096             RawType embedType = store.getModel().getRawType(NAME3);
4097             RawObject embed = new RawObject
4098                 (embedType,
4099                  makeValues
4100                     ("f1", true,
4101                      "f2", (byte) 2,
4102                      "f3", (short) 3,
4103                      "f4", 4,
4104                      "f5", 5L,
4105                      "f6", 6F,
4106                      "f7", 7D,
4107                      "f8", (char) 8,
4108                      "f9", true,
4109                      "f10", (byte) 10,
4110                      "f11", (short) 11,
4111                      "f12", 12,
4112                      "f13", 13L,
4113                      "f14", 14F,
4114                      "f15", 15D,
4115                      "f16", (char) 16),
4116                  null);
4117 
4118             RawObject obj;
4119             if (expectEvolved) {
4120                 obj = readRaw(store, 99, NAME, 1, NAME2, 1, CASECLS, 0);
4121                 checkRawFields(obj, "pkeyInt1", 99,
4122                                "kBoolean1", true,
4123                                "kByte1", (byte) 77,
4124                                "kShort1", (short) 66,
4125                                "kInt1", 55,
4126                                "kLong1", (long) 44,
4127                                "kFloat1", (float) 33,
4128                                "kDouble1", (double) 22,
4129                                "kCharacter1", (char) 11,
4130 
4131                                "f01", (short) 1,
4132                                "f02", 2,
4133                                "f03", (long) 3,
4134                                "f04", (float) 4,
4135                                "f06", (double) 6,
4136                                "f07", 7,
4137                                "f08", (long) 8,
4138                                "f09", (float) 9,
4139                                "f10", (double) 10,
4140                                "f11", 11,
4141                                "f12", (long) 12,
4142                                "f13", (float) 13,
4143                                "f14", (double) 14,
4144                                "f15", 15L,
4145                                "f16", 16F,
4146                                "f17", 17D,
4147                                "f18", (float) 18,
4148                                "f19", (double) 19,
4149                                "f20", (double) 20,
4150 
4151                                "f21", (short) 21,
4152                                "f22", 22,
4153                                "f23", (long) 23,
4154                                "f24", (float) 24,
4155                                "f26", (double) 26,
4156                                "f27", 27,
4157                                "f28", (long) 28,
4158                                "f29", (float) 29,
4159                                "f30", (double) 30,
4160                                "f31", 31,
4161                                "f32", (long) 32,
4162                                "f33", (float) 33,
4163                                "f34", (double) 34,
4164                                "f35", 35L,
4165                                "f36", 36F,
4166                                "f37", 37D,
4167                                "f38", (float) 38,
4168                                "f39", (double) 39,
4169                                "f40", (double) 40,
4170 
4171                                "f41", (short) 41,
4172                                "f42", 42,
4173                                "f43", (long) 43,
4174                                "f44", (float) 44,
4175                                "f46", (double) 46,
4176                                "f47", 47,
4177                                "f48", (long) 48,
4178                                "f49", (float) 49,
4179                                "f50", (double) 50,
4180                                "f51", 51,
4181                                "f52", (long) 52,
4182                                "f53", (float) 53,
4183                                "f54", (double) 54,
4184                                "f55", 55L,
4185                                "f56", 56F,
4186                                "f57", 57D,
4187                                "f58", (float) 58,
4188                                "f59", (double) 59,
4189                                "f60", (double) 60,
4190 
4191                                "f70", BigInteger.valueOf(70),
4192                                "f71", BigInteger.valueOf(71),
4193                                "f72", BigInteger.valueOf(72),
4194                                "f73", BigInteger.valueOf(73),
4195                                "f74", BigInteger.valueOf(74),
4196                                "f75", BigInteger.valueOf(75),
4197                                "f76", BigInteger.valueOf(76),
4198                                "f77", BigInteger.valueOf(77),
4199                                "f78", BigInteger.valueOf(78),
4200                                "f79", BigInteger.valueOf(79),
4201 
4202                                "f_long2int", 333,
4203                                "f_String2long", 444L);
4204                 checkRawFields(obj.getSuper(),
4205                                "kComposite1", embed,
4206                                "f_long2Integer", 111,
4207                                "f_String2Long", 222L);
4208             } else {
4209                 obj = readRaw(store, 99, NAME, 0, NAME2, 0, CASECLS, 0);
4210                 checkRawFields(obj, "pkeyint", 99,
4211                                "kboolean", true,
4212                                "kbyte", (byte) 77,
4213                                "kshort", (short) 66,
4214                                "kint", 55,
4215                                "klong", (long) 44,
4216                                "kfloat", (float) 33,
4217                                "kdouble", (double) 22,
4218                                "kchar", (char) 11,
4219 
4220                                "f01", (byte) 1,
4221                                "f02", (byte) 2,
4222                                "f03", (byte) 3,
4223                                "f04", (byte) 4,
4224                                "f06", (byte) 6,
4225                                "f07", (short) 7,
4226                                "f08", (short) 8,
4227                                "f09", (short) 9,
4228                                "f10", (short) 10,
4229                                "f11", (char) 11,
4230                                "f12", (char) 12,
4231                                "f13", (char) 13,
4232                                "f14", (char) 14,
4233                                "f15", 15,
4234                                "f16", 16,
4235                                "f17", 17,
4236                                "f18", (long) 18,
4237                                "f19", (long) 19,
4238                                "f20", (float) 20,
4239 
4240                                "f21", (byte) 21,
4241                                "f22", (byte) 22,
4242                                "f23", (byte) 23,
4243                                "f24", (byte) 24,
4244                                "f26", (byte) 26,
4245                                "f27", (short) 27,
4246                                "f28", (short) 28,
4247                                "f29", (short) 29,
4248                                "f30", (short) 30,
4249                                "f31", (char) 31,
4250                                "f32", (char) 32,
4251                                "f33", (char) 33,
4252                                "f34", (char) 34,
4253                                "f35", 35,
4254                                "f36", 36,
4255                                "f37", 37,
4256                                "f38", (long) 38,
4257                                "f39", (long) 39,
4258                                "f40", (float) 40,
4259 
4260                                "f41", (byte) 41,
4261                                "f42", (byte) 42,
4262                                "f43", (byte) 43,
4263                                "f44", (byte) 44,
4264                                "f46", (byte) 46,
4265                                "f47", (short) 47,
4266                                "f48", (short) 48,
4267                                "f49", (short) 49,
4268                                "f50", (short) 50,
4269                                "f51", (char) 51,
4270                                "f52", (char) 52,
4271                                "f53", (char) 53,
4272                                "f54", (char) 54,
4273                                "f55", 55,
4274                                "f56", 56,
4275                                "f57", 57,
4276                                "f58", (long) 58,
4277                                "f59", (long) 59,
4278                                "f60", (float) 60,
4279 
4280                                "f70", (byte) 70,
4281                                "f71", (short) 71,
4282                                "f72", (char) 72,
4283                                "f73", 73,
4284                                "f74", (long) 74,
4285                                "f75", (byte) 75,
4286                                "f76", (short) 76,
4287                                "f77", (char) 77,
4288                                "f78", 78,
4289                                "f79", (long) 79,
4290 
4291                                "f_long2int", 333L,
4292                                "f_String2long", "444");
4293 
4294                 checkRawFields(obj.getSuper(),
4295                                "kcomposite", embed,
4296                                "f_long2Integer", 111L,
4297                                "f_String2Long", "222");
4298             }
4299             Environment env = store.getEnvironment();
4300 
4301             assertDbExists(expectEvolved, env, NAME, "kBoolean1");
4302             assertDbExists(expectEvolved, env, NAME, "kByte1");
4303             assertDbExists(expectEvolved, env, NAME, "kShort1");
4304             assertDbExists(expectEvolved, env, NAME, "kInt1");
4305             assertDbExists(expectEvolved, env, NAME, "kLong1");
4306             assertDbExists(expectEvolved, env, NAME, "kFloat1");
4307             assertDbExists(expectEvolved, env, NAME, "kDouble1");
4308             assertDbExists(expectEvolved, env, NAME, "kCharacter1");
4309             assertDbExists(expectEvolved, env, NAME, "kComposite1");
4310 
4311             assertDbExists(!expectEvolved, env, NAME, "kboolean");
4312             assertDbExists(!expectEvolved, env, NAME, "kbyte");
4313             assertDbExists(!expectEvolved, env, NAME, "kshort");
4314             assertDbExists(!expectEvolved, env, NAME, "kint");
4315             assertDbExists(!expectEvolved, env, NAME, "klong");
4316             assertDbExists(!expectEvolved, env, NAME, "kfloat");
4317             assertDbExists(!expectEvolved, env, NAME, "kdouble");
4318             assertDbExists(!expectEvolved, env, NAME, "kchar");
4319             assertDbExists(!expectEvolved, env, NAME, "kcomposite");
4320         }
4321     }
4322 
4323     @SuppressWarnings("serial")
4324     static class ConvertFieldContent_Conversion implements Conversion {
4325 
initialize(EntityModel model)4326         public void initialize(EntityModel model) {
4327         }
4328 
convert(Object fromValue)4329         public Object convert(Object fromValue) {
4330             String s1 = (String) fromValue;
4331             return (new StringBuilder(s1)).reverse().toString();
4332         }
4333 
4334         @Override
equals(Object o)4335         public boolean equals(Object o) {
4336             return o instanceof ConvertFieldContent_Conversion;
4337         }
4338     }
4339 
4340     @Entity(version=1)
4341     static class ConvertFieldContent_Entity
4342         extends EvolveCase {
4343 
4344         private static final String NAME =
4345             ConvertFieldContent_Entity.class.getName();
4346 
4347         @PrimaryKey
4348         int key = 99;
4349 
4350         String f1;
4351         String f2;
4352 
4353         @Override
getMutations()4354         Mutations getMutations() {
4355             Mutations m = new Mutations();
4356             Converter converter = new Converter
4357                 (ConvertFieldContent_Entity.class.getName(), 0,
4358                  "f1", new ConvertFieldContent_Conversion());
4359             m.addConverter(converter);
4360             converter = new Converter
4361                 (ConvertFieldContent_Entity.class.getName(), 0,
4362                  "f2", new ConvertFieldContent_Conversion());
4363             m.addConverter(converter);
4364             return m;
4365         }
4366 
4367         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)4368         void checkEvolvedModel(EntityModel model,
4369                                Environment env,
4370                                boolean oldTypesExist) {
4371             checkEntity(true, model, env, NAME, 1, null);
4372             if (oldTypesExist) {
4373                 checkVersions(model, NAME, 1, NAME, 0);
4374             } else {
4375                 checkVersions(model, NAME, 1);
4376             }
4377         }
4378 
4379         @Override
readObjects(EntityStore store, boolean doUpdate)4380         void readObjects(EntityStore store, boolean doUpdate)
4381             throws DatabaseException {
4382 
4383             PrimaryIndex<Integer, ConvertFieldContent_Entity>
4384                 index = store.getPrimaryIndex
4385                     (Integer.class,
4386                      ConvertFieldContent_Entity.class);
4387             ConvertFieldContent_Entity obj = index.get(99);
4388             TestCase.assertNotNull(obj);
4389             TestCase.assertEquals(99, obj.key);
4390             TestCase.assertEquals("43210", obj.f1);
4391             TestCase.assertEquals("98765", obj.f2);
4392 
4393             if (doUpdate) {
4394                 index.put(obj);
4395             }
4396         }
4397 
4398         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)4399         void copyRawObjects(RawStore rawStore, EntityStore newStore)
4400             throws DatabaseException {
4401 
4402             PrimaryIndex<Integer, ConvertFieldContent_Entity>
4403                 index = newStore.getPrimaryIndex
4404                     (Integer.class,
4405                      ConvertFieldContent_Entity.class);
4406             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
4407             index.put((ConvertFieldContent_Entity)
4408                       newStore.getModel().convertRawObject(raw));
4409         }
4410 
4411         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)4412         void readRawObjects(RawStore store,
4413                             boolean expectEvolved,
4414                             boolean expectUpdated)
4415             throws DatabaseException {
4416 
4417             RawObject obj =
4418                 readRaw(store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
4419             if (expectEvolved) {
4420                 checkRawFields(obj, "key", 99,
4421                                     "f1", "43210",
4422                                     "f2", "98765");
4423             } else {
4424                 checkRawFields(obj, "key", 99,
4425                                     "f1", "01234",
4426                                     "f2", "56789");
4427             }
4428         }
4429     }
4430 
4431     @Persistent(version=1)
4432     static class ConvertExample1_Address {
4433         String street;
4434         String city;
4435         String state;
4436         int zipCode;
4437     }
4438 
4439     @SuppressWarnings("serial")
4440     static class ConvertExample1_Conversion implements Conversion {
4441 
initialize(EntityModel model)4442         public void initialize(EntityModel model) {
4443         }
4444 
convert(Object fromValue)4445         public Object convert(Object fromValue) {
4446             return Integer.valueOf((String) fromValue);
4447         }
4448 
4449         @Override
equals(Object o)4450         public boolean equals(Object o) {
4451             return o instanceof ConvertExample1_Conversion;
4452         }
4453     }
4454 
4455     @Entity
4456     static class ConvertExample1_Entity
4457         extends EvolveCase {
4458 
4459         private static final String NAME =
4460             ConvertExample1_Entity.class.getName();
4461         private static final String NAME2 =
4462             ConvertExample1_Address.class.getName();
4463 
4464         @PrimaryKey
4465         int key = 99;
4466 
4467         ConvertExample1_Address embed;
4468 
4469         @Override
getMutations()4470         Mutations getMutations() {
4471             Mutations m = new Mutations();
4472             Converter converter = new Converter
4473                 (ConvertExample1_Address.class.getName(), 0,
4474                  "zipCode", new ConvertExample1_Conversion());
4475             m.addConverter(converter);
4476             return m;
4477         }
4478 
4479         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)4480         void checkEvolvedModel(EntityModel model,
4481                                Environment env,
4482                                boolean oldTypesExist) {
4483             checkEntity(true, model, env, NAME, 0, null);
4484             checkVersions(model, NAME, 0);
4485             if (oldTypesExist) {
4486                 checkVersions(model, NAME2, 1, NAME2, 0);
4487             } else {
4488                 checkVersions(model, NAME2, 1);
4489             }
4490         }
4491 
4492         @Override
readObjects(EntityStore store, boolean doUpdate)4493         void readObjects(EntityStore store, boolean doUpdate)
4494             throws DatabaseException {
4495 
4496             PrimaryIndex<Integer, ConvertExample1_Entity>
4497                 index = store.getPrimaryIndex
4498                     (Integer.class,
4499                      ConvertExample1_Entity.class);
4500             ConvertExample1_Entity obj = index.get(99);
4501             TestCase.assertNotNull(obj);
4502             TestCase.assertEquals(99, obj.key);
4503             TestCase.assertNotNull(obj.embed);
4504             TestCase.assertEquals("street", obj.embed.street);
4505             TestCase.assertEquals("city", obj.embed.city);
4506             TestCase.assertEquals("state", obj.embed.state);
4507             TestCase.assertEquals(12345, obj.embed.zipCode);
4508 
4509             if (doUpdate) {
4510                 index.put(obj);
4511             }
4512         }
4513 
4514         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)4515         void copyRawObjects(RawStore rawStore, EntityStore newStore)
4516             throws DatabaseException {
4517 
4518             PrimaryIndex<Integer, ConvertExample1_Entity>
4519                 index = newStore.getPrimaryIndex
4520                     (Integer.class,
4521                      ConvertExample1_Entity.class);
4522             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
4523             index.put((ConvertExample1_Entity)
4524                       newStore.getModel().convertRawObject(raw));
4525         }
4526 
4527         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)4528         void readRawObjects(RawStore store,
4529                             boolean expectEvolved,
4530                             boolean expectUpdated)
4531             throws DatabaseException {
4532 
4533             RawType embedType = store.getModel().getRawType(NAME2);
4534             RawObject embed;
4535             if (expectEvolved) {
4536                 embed = new RawObject
4537                     (embedType,
4538                      makeValues("street", "street",
4539                                 "city", "city",
4540                                 "state", "state",
4541                                 "zipCode", 12345),
4542                      null);
4543             } else {
4544                 embed = new RawObject
4545                     (embedType,
4546                      makeValues("street", "street",
4547                                 "city", "city",
4548                                 "state", "state",
4549                                 "zipCode", "12345"),
4550                      null);
4551             }
4552             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
4553             checkRawFields(obj, "key", 99, "embed", embed);
4554         }
4555     }
4556 
4557     @Persistent
4558     static class ConvertExample2_Address {
4559         String street;
4560         String city;
4561         String state;
4562         int zipCode;
4563     }
4564 
4565     @Entity(version=1)
4566     static class ConvertExample2_Person
4567         extends EvolveCase {
4568 
4569         private static final String NAME =
4570             ConvertExample2_Person.class.getName();
4571         private static final String NAME2 =
4572             ConvertExample2_Address .class.getName();
4573 
4574         @PrimaryKey
4575         int key;
4576 
4577         ConvertExample2_Address address;
4578 
4579         @Override
getMutations()4580         Mutations getMutations() {
4581             Mutations m = new Mutations();
4582             Converter converter = new Converter
4583                 (ConvertExample2_Person.class.getName(), 0,
4584                  "address", new ConvertExample2_Conversion());
4585             m.addConverter(converter);
4586             return m;
4587         }
4588 
4589         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)4590         void checkEvolvedModel(EntityModel model,
4591                                Environment env,
4592                                boolean oldTypesExist) {
4593             checkEntity(true, model, env, NAME, 1, null);
4594             if (oldTypesExist) {
4595                 checkVersions(model, NAME, 1, NAME, 0);
4596             } else {
4597                 checkVersions(model, NAME, 1);
4598             }
4599             checkVersions(model, NAME2, 0);
4600         }
4601 
4602         @Override
readObjects(EntityStore store, boolean doUpdate)4603         void readObjects(EntityStore store, boolean doUpdate)
4604             throws DatabaseException {
4605 
4606             PrimaryIndex<Integer, ConvertExample2_Person>
4607                 index = store.getPrimaryIndex
4608                     (Integer.class,
4609                      ConvertExample2_Person.class);
4610             ConvertExample2_Person obj = index.get(99);
4611             TestCase.assertNotNull(obj);
4612             TestCase.assertEquals(99, obj.key);
4613             TestCase.assertNotNull(obj.address);
4614             TestCase.assertEquals("street", obj.address.street);
4615             TestCase.assertEquals("city", obj.address.city);
4616             TestCase.assertEquals("state", obj.address.state);
4617             TestCase.assertEquals(12345, obj.address.zipCode);
4618 
4619             if (doUpdate) {
4620                 index.put(obj);
4621             }
4622         }
4623 
4624         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)4625         void copyRawObjects(RawStore rawStore, EntityStore newStore)
4626             throws DatabaseException {
4627 
4628             PrimaryIndex<Integer, ConvertExample2_Person>
4629                 index = newStore.getPrimaryIndex
4630                     (Integer.class,
4631                      ConvertExample2_Person.class);
4632             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
4633             index.put((ConvertExample2_Person)
4634                       newStore.getModel().convertRawObject(raw));
4635         }
4636 
4637         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)4638         void readRawObjects(RawStore store,
4639                             boolean expectEvolved,
4640                             boolean expectUpdated)
4641             throws DatabaseException {
4642 
4643             Object embed;
4644             if (expectEvolved) {
4645                 RawType embedType = store.getModel().getRawType(NAME2);
4646                 embed = new RawObject
4647                     (embedType,
4648                      makeValues("street", "street",
4649                                 "city", "city",
4650                                 "state", "state",
4651                                 "zipCode", 12345),
4652                      null);
4653             } else {
4654                 embed = "street#city#state#12345";
4655             }
4656             RawObject obj = readRaw
4657                 (store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
4658             checkRawFields(obj, "key", 99, "address", embed);
4659         }
4660     }
4661 
4662     @SuppressWarnings("serial")
4663     static class ConvertExample2_Conversion implements Conversion {
4664         private transient RawType addressType;
4665 
initialize(EntityModel model)4666         public void initialize(EntityModel model) {
4667             addressType = model.getRawType
4668                 (ConvertExample2_Address.class.getName());
4669         }
4670 
convert(Object fromValue)4671         public Object convert(Object fromValue) {
4672 
4673             String oldAddress = (String) fromValue;
4674             Map<String, Object> addressValues = new HashMap<String, Object>();
4675             addressValues.put("street", parseAddress(1, oldAddress));
4676             addressValues.put("city", parseAddress(2, oldAddress));
4677             addressValues.put("state", parseAddress(3, oldAddress));
4678             addressValues.put("zipCode",
4679                               Integer.valueOf(parseAddress(4, oldAddress)));
4680 
4681             return new RawObject(addressType, addressValues, null);
4682         }
4683 
4684         @Override
equals(Object o)4685         public boolean equals(Object o) {
4686             return o instanceof ConvertExample2_Conversion;
4687         }
4688 
parseAddress(int fieldNum, String oldAddress)4689         private String parseAddress(int fieldNum, String oldAddress) {
4690             StringTokenizer tokens = new StringTokenizer(oldAddress, "#");
4691             String field = null;
4692             for (int i = 0; i < fieldNum; i += 1) {
4693                 field = tokens.nextToken();
4694             }
4695             return field;
4696         }
4697     }
4698 
4699     @Persistent
4700     static class ConvertExample3_Address {
4701         String street;
4702         String city;
4703         String state;
4704         int zipCode;
4705     }
4706 
4707     @SuppressWarnings("serial")
4708     static class ConvertExample3_Conversion implements Conversion {
4709         private transient RawType newPersonType;
4710         private transient RawType addressType;
4711 
initialize(EntityModel model)4712         public void initialize(EntityModel model) {
4713             newPersonType = model.getRawType
4714                 (ConvertExample3_Person.class.getName());
4715             addressType = model.getRawType
4716                 (ConvertExample3_Address.class.getName());
4717         }
4718 
convert(Object fromValue)4719         public Object convert(Object fromValue) {
4720 
4721             RawObject person = (RawObject) fromValue;
4722             Map<String, Object> personValues = person.getValues();
4723             Map<String, Object> addressValues = new HashMap<String, Object>();
4724             RawObject address = new RawObject
4725                 (addressType, addressValues, null);
4726 
4727             addressValues.put("street", personValues.remove("street"));
4728             addressValues.put("city", personValues.remove("city"));
4729             addressValues.put("state", personValues.remove("state"));
4730             addressValues.put("zipCode", personValues.remove("zipCode"));
4731             personValues.put("address", address);
4732 
4733             return new RawObject
4734                 (newPersonType, personValues, person.getSuper());
4735         }
4736 
4737         @Override
equals(Object o)4738         public boolean equals(Object o) {
4739             return o instanceof ConvertExample3_Conversion;
4740         }
4741     }
4742 
4743     @Entity(version=1)
4744     static class ConvertExample3_Person
4745         extends EvolveCase {
4746 
4747         private static final String NAME =
4748             ConvertExample3_Person.class.getName();
4749         private static final String NAME2 =
4750             ConvertExample3_Address .class.getName();
4751 
4752         @PrimaryKey
4753         int key;
4754 
4755         ConvertExample3_Address address;
4756 
4757         @Override
getMutations()4758         Mutations getMutations() {
4759             Mutations m = new Mutations();
4760             Converter converter = new Converter
4761                 (ConvertExample3_Person.class.getName(), 0,
4762                  new ConvertExample3_Conversion());
4763             m.addConverter(converter);
4764             return m;
4765         }
4766 
4767         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)4768         void checkEvolvedModel(EntityModel model,
4769                                Environment env,
4770                                boolean oldTypesExist) {
4771             checkEntity(true, model, env, NAME, 1, null);
4772             if (oldTypesExist) {
4773                 checkVersions(model, NAME, 1, NAME, 0);
4774             } else {
4775                 checkVersions(model, NAME, 1);
4776             }
4777             checkVersions(model, NAME2, 0);
4778         }
4779 
4780         @Override
readObjects(EntityStore store, boolean doUpdate)4781         void readObjects(EntityStore store, boolean doUpdate)
4782             throws DatabaseException {
4783 
4784             PrimaryIndex<Integer, ConvertExample3_Person>
4785                 index = store.getPrimaryIndex
4786                     (Integer.class,
4787                      ConvertExample3_Person.class);
4788             ConvertExample3_Person obj = index.get(99);
4789             TestCase.assertNotNull(obj);
4790             TestCase.assertEquals(99, obj.key);
4791             TestCase.assertNotNull(obj.address);
4792             TestCase.assertEquals("street", obj.address.street);
4793             TestCase.assertEquals("city", obj.address.city);
4794             TestCase.assertEquals("state", obj.address.state);
4795             TestCase.assertEquals(12345, obj.address.zipCode);
4796 
4797             if (doUpdate) {
4798                 index.put(obj);
4799             }
4800         }
4801 
4802         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)4803         void copyRawObjects(RawStore rawStore, EntityStore newStore)
4804             throws DatabaseException {
4805 
4806             PrimaryIndex<Integer, ConvertExample3_Person>
4807                 index = newStore.getPrimaryIndex
4808                     (Integer.class,
4809                      ConvertExample3_Person.class);
4810             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
4811             index.put((ConvertExample3_Person)
4812                       newStore.getModel().convertRawObject(raw));
4813         }
4814 
4815         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)4816         void readRawObjects(RawStore store,
4817                             boolean expectEvolved,
4818                             boolean expectUpdated)
4819             throws DatabaseException {
4820 
4821             RawObject obj = readRaw
4822                 (store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
4823             if (expectEvolved) {
4824                 RawType embedType = store.getModel().getRawType(NAME2);
4825                 Object embed = new RawObject
4826                     (embedType,
4827                      makeValues("street", "street",
4828                                 "city", "city",
4829                                 "state", "state",
4830                                 "zipCode", 12345),
4831                      null);
4832                 checkRawFields(obj, "key", 99, "address", embed);
4833             } else {
4834                 checkRawFields(obj, "key", 99,
4835                                     "street", "street",
4836                                     "city", "city",
4837                                     "state", "state",
4838                                     "zipCode", 12345);
4839             }
4840         }
4841     }
4842 
4843     @SuppressWarnings("serial")
4844     static class ConvertExample3Reverse_Conversion implements Conversion {
4845         private transient RawType newPersonType;
4846 
initialize(EntityModel model)4847         public void initialize(EntityModel model) {
4848             newPersonType = model.getRawType
4849                 (ConvertExample3Reverse_Person.class.getName());
4850         }
4851 
convert(Object fromValue)4852         public Object convert(Object fromValue) {
4853 
4854             RawObject person = (RawObject) fromValue;
4855             Map<String, Object> personValues = person.getValues();
4856             RawObject address = (RawObject) personValues.remove("address");
4857             Map<String, Object> addressValues = address.getValues();
4858 
4859             personValues.put("street", addressValues.remove("street"));
4860             personValues.put("city", addressValues.remove("city"));
4861             personValues.put("state", addressValues.remove("state"));
4862             personValues.put("zipCode", addressValues.remove("zipCode"));
4863 
4864             return new RawObject
4865                 (newPersonType, personValues, person.getSuper());
4866         }
4867 
4868         @Override
equals(Object o)4869         public boolean equals(Object o) {
4870             return o instanceof ConvertExample3Reverse_Conversion;
4871         }
4872     }
4873 
4874     @Entity(version=1)
4875     static class ConvertExample3Reverse_Person
4876         extends EvolveCase {
4877 
4878         private static final String NAME =
4879             ConvertExample3Reverse_Person.class.getName();
4880         private static final String NAME2 =
4881             PREFIX + "ConvertExample3Reverse_Address";
4882 
4883         @PrimaryKey
4884         int key;
4885 
4886         String street;
4887         String city;
4888         String state;
4889         int zipCode;
4890 
4891         @Override
getMutations()4892         Mutations getMutations() {
4893             Mutations m = new Mutations();
4894             Converter converter = new Converter
4895                 (ConvertExample3Reverse_Person.class.getName(), 0,
4896                  new ConvertExample3Reverse_Conversion());
4897             m.addConverter(converter);
4898             m.addDeleter(new Deleter(NAME2, 0));
4899             return m;
4900         }
4901 
4902         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)4903         void checkEvolvedModel(EntityModel model,
4904                                Environment env,
4905                                boolean oldTypesExist) {
4906             checkEntity(true, model, env, NAME, 1, null);
4907             if (oldTypesExist) {
4908                 checkVersions(model, NAME, 1, NAME, 0);
4909                 checkVersions(model, NAME2, 0);
4910             } else {
4911                 checkVersions(model, NAME, 1);
4912             }
4913         }
4914 
4915         @Override
readObjects(EntityStore store, boolean doUpdate)4916         void readObjects(EntityStore store, boolean doUpdate)
4917             throws DatabaseException {
4918 
4919             PrimaryIndex<Integer, ConvertExample3Reverse_Person>
4920                 index = store.getPrimaryIndex
4921                     (Integer.class,
4922                      ConvertExample3Reverse_Person.class);
4923             ConvertExample3Reverse_Person obj = index.get(99);
4924             TestCase.assertNotNull(obj);
4925             TestCase.assertEquals(99, obj.key);
4926             TestCase.assertEquals("street", obj.street);
4927             TestCase.assertEquals("city", obj.city);
4928             TestCase.assertEquals("state", obj.state);
4929             TestCase.assertEquals(12345, obj.zipCode);
4930 
4931             if (doUpdate) {
4932                 index.put(obj);
4933             }
4934         }
4935 
4936         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)4937         void copyRawObjects(RawStore rawStore, EntityStore newStore)
4938             throws DatabaseException {
4939 
4940             PrimaryIndex<Integer, ConvertExample3Reverse_Person>
4941                 index = newStore.getPrimaryIndex
4942                     (Integer.class,
4943                      ConvertExample3Reverse_Person.class);
4944             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
4945             index.put((ConvertExample3Reverse_Person)
4946                       newStore.getModel().convertRawObject(raw));
4947         }
4948 
4949         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)4950         void readRawObjects(RawStore store,
4951                             boolean expectEvolved,
4952                             boolean expectUpdated)
4953             throws DatabaseException {
4954 
4955             RawObject obj = readRaw
4956                 (store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
4957             if (expectEvolved) {
4958                 checkRawFields(obj, "key", 99,
4959                                     "street", "street",
4960                                     "city", "city",
4961                                     "state", "state",
4962                                     "zipCode", 12345);
4963             } else {
4964                 RawType embedType = store.getModel().getRawType(NAME2);
4965                 Object embed = new RawObject
4966                     (embedType,
4967                      makeValues("street", "street",
4968                                 "city", "city",
4969                                 "state", "state",
4970                                 "zipCode", 12345),
4971                      null);
4972                 checkRawFields(obj, "key", 99, "address", embed);
4973             }
4974         }
4975     }
4976 
4977     @Persistent(version=1)
4978     static class ConvertExample4_A extends ConvertExample4_B {
4979     }
4980 
4981     @Persistent(version=1)
4982     static class ConvertExample4_B {
4983         String name;
4984     }
4985 
4986     @SuppressWarnings("serial")
4987     static class Example4_Conversion implements Conversion {
4988         private transient RawType newAType;
4989         private transient RawType newBType;
4990 
initialize(EntityModel model)4991         public void initialize(EntityModel model) {
4992             newAType = model.getRawType(ConvertExample4_A.class.getName());
4993             newBType = model.getRawType(ConvertExample4_B.class.getName());
4994         }
4995 
convert(Object fromValue)4996         public Object convert(Object fromValue) {
4997             RawObject oldA = (RawObject) fromValue;
4998             RawObject oldB = oldA.getSuper();
4999             Map<String, Object> aValues = oldA.getValues();
5000             Map<String, Object> bValues = oldB.getValues();
5001             bValues.put("name", aValues.remove("name"));
5002             RawObject newB = new RawObject(newBType, bValues, oldB.getSuper());
5003             RawObject newA = new RawObject(newAType, aValues, newB);
5004             return newA;
5005         }
5006 
5007         @Override
equals(Object o)5008         public boolean equals(Object o) {
5009             return o instanceof Example4_Conversion;
5010         }
5011     }
5012 
5013     @Entity(version=1)
5014     static class ConvertExample4_Entity
5015         extends EvolveCase {
5016 
5017         private static final String NAME =
5018             ConvertExample4_Entity.class.getName();
5019         private static final String NAME2 =
5020             ConvertExample4_A .class.getName();
5021         private static final String NAME3 =
5022             ConvertExample4_B .class.getName();
5023 
5024         @PrimaryKey
5025         int key;
5026 
5027         ConvertExample4_A embed;
5028 
5029         @Override
getMutations()5030         Mutations getMutations() {
5031             Mutations m = new Mutations();
5032             Converter converter = new Converter
5033                 (ConvertExample4_A.class.getName(), 0,
5034                  new Example4_Conversion());
5035             m.addConverter(converter);
5036             return m;
5037         }
5038 
5039         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)5040         void checkEvolvedModel(EntityModel model,
5041                                Environment env,
5042                                boolean oldTypesExist) {
5043             checkEntity(true, model, env, NAME, 1, null);
5044             if (oldTypesExist) {
5045                 checkVersions(model, NAME, 1, NAME, 0);
5046                 checkVersions(model, NAME2, 1, NAME2, 0);
5047                 checkVersions(model, NAME3, 1, NAME3, 0);
5048             } else {
5049                 checkVersions(model, NAME, 1);
5050                 checkVersions(model, NAME2, 1);
5051                 checkVersions(model, NAME3, 1);
5052             }
5053         }
5054 
5055         @Override
readObjects(EntityStore store, boolean doUpdate)5056         void readObjects(EntityStore store, boolean doUpdate)
5057             throws DatabaseException {
5058 
5059             PrimaryIndex<Integer, ConvertExample4_Entity>
5060                 index = store.getPrimaryIndex
5061                     (Integer.class,
5062                      ConvertExample4_Entity.class);
5063             ConvertExample4_Entity obj = index.get(99);
5064             TestCase.assertNotNull(obj);
5065             TestCase.assertEquals(99, obj.key);
5066             TestCase.assertNotNull(obj.embed);
5067             TestCase.assertEquals("name", obj.embed.name);
5068 
5069             if (doUpdate) {
5070                 index.put(obj);
5071             }
5072         }
5073 
5074         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)5075         void copyRawObjects(RawStore rawStore, EntityStore newStore)
5076             throws DatabaseException {
5077 
5078             PrimaryIndex<Integer, ConvertExample4_Entity>
5079                 index = newStore.getPrimaryIndex
5080                     (Integer.class,
5081                      ConvertExample4_Entity.class);
5082             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
5083             index.put((ConvertExample4_Entity)
5084                       newStore.getModel().convertRawObject(raw));
5085         }
5086 
5087         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)5088         void readRawObjects(RawStore store,
5089                             boolean expectEvolved,
5090                             boolean expectUpdated)
5091             throws DatabaseException {
5092 
5093             RawType embedTypeA = store.getModel().getRawType(NAME2);
5094             RawType embedTypeB = store.getModel().getRawType(NAME3);
5095             Object embed;
5096             if (expectEvolved) {
5097                 embed = new RawObject(embedTypeA, makeValues(),
5098                         new RawObject
5099                             (embedTypeB, makeValues("name", "name"), null));
5100             } else {
5101                 embed = new RawObject(embedTypeA, makeValues("name", "name"),
5102                         new RawObject
5103                             (embedTypeB, makeValues(), null));
5104             }
5105             RawObject obj = readRaw
5106                 (store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
5107             checkRawFields(obj, "key", 99, "embed", embed);
5108         }
5109     }
5110 
5111     @Persistent(version=1)
5112     static class ConvertExample5_Pet {
5113         String name;
5114     }
5115 
5116     @Persistent
5117     static class ConvertExample5_Cat extends ConvertExample5_Pet {
5118         int finickyLevel;
5119     }
5120 
5121     @Persistent
5122     static class ConvertExample5_Dog extends ConvertExample5_Pet {
5123         double barkVolume;
5124     }
5125 
5126     @SuppressWarnings("serial")
5127     static class ConvertExample5_Conversion implements Conversion {
5128         private transient RawType newPetType;
5129         private transient RawType dogType;
5130         private transient RawType catType;
5131 
initialize(EntityModel model)5132         public void initialize(EntityModel model) {
5133             newPetType = model.getRawType(ConvertExample5_Pet.class.getName());
5134             dogType = model.getRawType(ConvertExample5_Dog.class.getName());
5135             catType = model.getRawType(ConvertExample5_Cat.class.getName());
5136         }
5137 
convert(Object fromValue)5138         public Object convert(Object fromValue) {
5139             RawObject pet = (RawObject) fromValue;
5140             Map<String, Object> petValues = pet.getValues();
5141             Map<String, Object> subTypeValues = new HashMap<String, Object>();
5142             Boolean isCat = (Boolean) petValues.remove("isCatNotDog");
5143             Integer finickyLevel = (Integer) petValues.remove("finickyLevel");
5144             Double barkVolume = (Double) petValues.remove("barkVolume");
5145             RawType newSubType;
5146             if (isCat) {
5147                 newSubType = catType;
5148                 subTypeValues.put("finickyLevel", finickyLevel);
5149             } else {
5150                 newSubType = dogType;
5151                 subTypeValues.put("barkVolume", barkVolume);
5152             }
5153             RawObject newPet = new RawObject
5154                 (newPetType, petValues, pet.getSuper());
5155             return new RawObject(newSubType, subTypeValues, newPet);
5156         }
5157 
5158         @Override
equals(Object o)5159         public boolean equals(Object o) {
5160             return o instanceof ConvertExample5_Conversion;
5161         }
5162     }
5163 
5164     @Entity(version=1)
5165     static class ConvertExample5_Entity
5166         extends EvolveCase {
5167 
5168         private static final String NAME =
5169             ConvertExample5_Entity.class.getName();
5170         private static final String NAME2 =
5171             ConvertExample5_Pet.class.getName();
5172         private static final String NAME3 =
5173             ConvertExample5_Cat.class.getName();
5174         private static final String NAME4 =
5175             ConvertExample5_Dog.class.getName();
5176 
5177         @PrimaryKey
5178         int key;
5179 
5180         ConvertExample5_Cat cat;
5181         ConvertExample5_Dog dog;
5182 
5183         @Override
getMutations()5184         Mutations getMutations() {
5185             Mutations m = new Mutations();
5186             Converter converter = new Converter
5187                 (ConvertExample5_Pet.class.getName(), 0,
5188                  new ConvertExample5_Conversion());
5189             m.addConverter(converter);
5190             return m;
5191         }
5192 
5193         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)5194         void checkEvolvedModel(EntityModel model,
5195                                Environment env,
5196                                boolean oldTypesExist) {
5197             checkEntity(true, model, env, NAME, 1, null);
5198             if (oldTypesExist) {
5199                 checkVersions(model, NAME, 1, NAME, 0);
5200                 checkVersions(model, NAME2, 1, NAME2, 0);
5201             } else {
5202                 checkVersions(model, NAME, 1);
5203                 checkVersions(model, NAME2, 1);
5204             }
5205             checkVersions(model, NAME3, 0);
5206             checkVersions(model, NAME4, 0);
5207         }
5208 
5209         @Override
readObjects(EntityStore store, boolean doUpdate)5210         void readObjects(EntityStore store, boolean doUpdate)
5211             throws DatabaseException {
5212 
5213             PrimaryIndex<Integer, ConvertExample5_Entity>
5214                 index = store.getPrimaryIndex
5215                     (Integer.class,
5216                      ConvertExample5_Entity.class);
5217             ConvertExample5_Entity obj = index.get(99);
5218             TestCase.assertNotNull(obj);
5219             TestCase.assertEquals(99, obj.key);
5220             TestCase.assertNotNull(obj.cat);
5221             TestCase.assertEquals("Jeffry", obj.cat.name);
5222             TestCase.assertEquals(999, obj.cat.finickyLevel);
5223             TestCase.assertNotNull(obj.dog);
5224             TestCase.assertEquals("Nelson", obj.dog.name);
5225             TestCase.assertEquals(0.01, obj.dog.barkVolume);
5226 
5227             if (doUpdate) {
5228                 index.put(obj);
5229             }
5230         }
5231 
5232         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)5233         void copyRawObjects(RawStore rawStore, EntityStore newStore)
5234             throws DatabaseException {
5235 
5236             PrimaryIndex<Integer, ConvertExample5_Entity>
5237                 index = newStore.getPrimaryIndex
5238                     (Integer.class,
5239                      ConvertExample5_Entity.class);
5240             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
5241             index.put((ConvertExample5_Entity)
5242                       newStore.getModel().convertRawObject(raw));
5243         }
5244 
5245         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)5246         void readRawObjects(RawStore store,
5247                             boolean expectEvolved,
5248                             boolean expectUpdated)
5249             throws DatabaseException {
5250 
5251             RawType petType = store.getModel().getRawType(NAME2);
5252             RawObject cat;
5253             RawObject dog;
5254             if (expectEvolved) {
5255                 RawType catType = store.getModel().getRawType(NAME3);
5256                 RawType dogType = store.getModel().getRawType(NAME4);
5257                 cat = new RawObject(catType, makeValues("finickyLevel", 999),
5258                       new RawObject(petType, makeValues("name", "Jeffry"),
5259                                     null));
5260                 dog = new RawObject(dogType, makeValues("barkVolume", 0.01),
5261                       new RawObject(petType, makeValues("name", "Nelson"),
5262                                     null));
5263             } else {
5264                 cat = new RawObject(petType, makeValues("name", "Jeffry",
5265                                                         "isCatNotDog", true,
5266                                                         "finickyLevel", 999,
5267                                                         "barkVolume", 0.0),
5268                                     null);
5269                 dog = new RawObject(petType, makeValues("name", "Nelson",
5270                                                         "isCatNotDog", false,
5271                                                         "finickyLevel", 0,
5272                                                         "barkVolume", 0.01),
5273                                     null);
5274             }
5275             RawObject obj = readRaw
5276                 (store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
5277             checkRawFields(obj, "key", 99, "cat", cat, "dog", dog);
5278         }
5279     }
5280 
5281     @Persistent(version=1)
5282     static class AllowFieldAddDelete_Embed {
5283         private final String f0 = "0";
5284         private String f2;
5285         private final int f3 = 3;
5286         private String f4;
5287         private final int f5 = 5;
5288         private final String f8 = "8";
5289         private final int f9 = 9;
5290     }
5291 
5292     @Persistent(version=1)
5293     static class AllowFieldAddDelete_Base
5294         extends EvolveCase {
5295 
5296         private final String f0 = "0";
5297         private String f2;
5298         private final int f3 = 3;
5299         private String f4;
5300         private final int f5 = 5;
5301         private final String f8 = "8";
5302         private final int f9 = 9;
5303     }
5304 
5305     @Entity(version=1)
5306     static class AllowFieldAddDelete
5307         extends AllowFieldAddDelete_Base {
5308 
5309         private static final String NAME =
5310             AllowFieldAddDelete.class.getName();
5311         private static final String NAME2 =
5312             AllowFieldAddDelete_Base.class.getName();
5313         private static final String NAME3 =
5314             AllowFieldAddDelete_Embed.class.getName();
5315 
5316         @PrimaryKey
5317         int key;
5318 
5319         AllowFieldAddDelete_Embed embed;
5320 
5321         private final String f0 = "0";
5322         private String f2;
5323         private final int f3 = 3;
5324         private String f4;
5325         private final int f5 = 5;
5326         private final String f8 = "8";
5327         private final int f9 = 9;
5328 
5329         @Override
getMutations()5330         Mutations getMutations() {
5331             Mutations m = new Mutations();
5332             for (String name : new String[] {NAME, NAME2, NAME3}) {
5333                 m.addDeleter(new Deleter(name, 0, "f1"));
5334                 m.addDeleter(new Deleter(name, 0, "f6"));
5335                 m.addDeleter(new Deleter(name, 0, "f7"));
5336             }
5337             return m;
5338         }
5339 
5340         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)5341         void checkEvolvedModel(EntityModel model,
5342                                Environment env,
5343                                boolean oldTypesExist) {
5344             checkEntity(true, model, env, NAME, 1, null);
5345             if (oldTypesExist) {
5346                 checkVersions(model, NAME, 1, NAME, 0);
5347                 checkVersions(model, NAME2, 1, NAME2, 0);
5348                 checkVersions(model, NAME3, 1, NAME3, 0);
5349             } else {
5350                 checkVersions(model, NAME, 1);
5351                 checkVersions(model, NAME2, 1);
5352                 checkVersions(model, NAME3, 1);
5353             }
5354         }
5355 
5356         @Override
readObjects(EntityStore store, boolean doUpdate)5357         void readObjects(EntityStore store, boolean doUpdate)
5358             throws DatabaseException {
5359 
5360             PrimaryIndex<Integer, AllowFieldAddDelete>
5361                 index = store.getPrimaryIndex
5362                     (Integer.class,
5363                      AllowFieldAddDelete.class);
5364             AllowFieldAddDelete obj = index.get(99);
5365             TestCase.assertNotNull(obj);
5366             TestCase.assertEquals(99, obj.key);
5367             {
5368                 AllowFieldAddDelete o = obj;
5369 
5370                 TestCase.assertNotNull(o);
5371                 TestCase.assertEquals("0", o.f0);
5372                 TestCase.assertEquals("2", o.f2);
5373                 TestCase.assertEquals(3, o.f3);
5374                 TestCase.assertEquals("4", o.f4);
5375                 TestCase.assertEquals(5, o.f5);
5376                 TestCase.assertEquals("8", o.f8);
5377                 TestCase.assertEquals(9, o.f9);
5378             }
5379             {
5380                 AllowFieldAddDelete_Base o = obj;
5381 
5382                 TestCase.assertNotNull(o);
5383                 TestCase.assertEquals("0", o.f0);
5384                 TestCase.assertEquals("2", o.f2);
5385                 TestCase.assertEquals(3, o.f3);
5386                 TestCase.assertEquals("4", o.f4);
5387                 TestCase.assertEquals(5, o.f5);
5388                 TestCase.assertEquals("8", o.f8);
5389                 TestCase.assertEquals(9, o.f9);
5390             }
5391             {
5392                 AllowFieldAddDelete_Embed o = obj.embed;
5393 
5394                 TestCase.assertNotNull(o);
5395                 TestCase.assertEquals("0", o.f0);
5396                 TestCase.assertEquals("2", o.f2);
5397                 TestCase.assertEquals(3, o.f3);
5398                 TestCase.assertEquals("4", o.f4);
5399                 TestCase.assertEquals(5, o.f5);
5400                 TestCase.assertEquals("8", o.f8);
5401                 TestCase.assertEquals(9, o.f9);
5402             }
5403 
5404             if (doUpdate) {
5405                 index.put(obj);
5406             }
5407         }
5408 
5409         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)5410         void copyRawObjects(RawStore rawStore, EntityStore newStore)
5411             throws DatabaseException {
5412 
5413             PrimaryIndex<Integer, AllowFieldAddDelete>
5414                 index = newStore.getPrimaryIndex
5415                     (Integer.class,
5416                      AllowFieldAddDelete.class);
5417             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
5418             index.put((AllowFieldAddDelete)
5419                       newStore.getModel().convertRawObject(raw));
5420         }
5421 
5422         static final Object[] fixedFields0 = {
5423             "f1", 1,
5424             "f2", "2",
5425             "f4", "4",
5426             "f6", 6,
5427             "f7", "7",
5428         };
5429 
5430         static final Object[] fixedFields1 = {
5431             "f2", "2",
5432             "f4", "4",
5433         };
5434 
5435         static final Object[] fixedFields2 = {
5436             "f0", "0",
5437             "f2", "2",
5438             "f3", 3,
5439             "f4", "4",
5440             "f5", 5,
5441             "f8", "8",
5442             "f9", 9,
5443         };
5444 
5445         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)5446         void readRawObjects(RawStore store,
5447                             boolean expectEvolved,
5448                             boolean expectUpdated)
5449             throws DatabaseException {
5450 
5451             RawType baseType = store.getModel().getRawType(NAME2);
5452             RawType embedType = store.getModel().getRawType(NAME3);
5453 
5454             Object[] ff;
5455             if (expectEvolved) {
5456                 if (expectUpdated) {
5457                     ff = fixedFields2;
5458                 } else {
5459                     ff = fixedFields1;
5460                 }
5461             } else {
5462                 ff = fixedFields0;
5463             }
5464             RawObject embed = new RawObject(embedType, makeValues(ff), null);
5465             RawObject obj = readRaw
5466                 (store, 99, NAME, expectEvolved ? 1 : 0,
5467                             NAME2, expectEvolved ? 1 : 0,
5468                             CASECLS, 0);
5469             checkRaw(obj, ff, "key", 99, "embed", embed);
5470             checkRaw(obj.getSuper(), ff);
5471         }
5472 
checkRaw(RawObject obj, Object[] fixedFields, Object... otherFields)5473         private void checkRaw(RawObject obj,
5474                               Object[] fixedFields,
5475                               Object... otherFields) {
5476             Object[] allFields =
5477                 new Object[otherFields.length + fixedFields.length];
5478             System.arraycopy(otherFields, 0, allFields, 0, otherFields.length);
5479             System.arraycopy(fixedFields, 0, allFields,
5480                              otherFields.length, fixedFields.length);
5481             checkRawFields(obj, allFields);
5482         }
5483     }
5484 
5485     static class ProxiedClass {
5486         int data;
5487 
ProxiedClass(int data)5488         ProxiedClass(int data) {
5489             this.data = data;
5490         }
5491     }
5492 
5493     @Persistent(version=1, proxyFor=ProxiedClass.class)
5494     static class ProxiedClass_Proxy implements PersistentProxy<ProxiedClass> {
5495         long data;
5496 
initializeProxy(ProxiedClass o)5497         public void initializeProxy(ProxiedClass o) {
5498             data = o.data;
5499         }
5500 
convertProxy()5501         public ProxiedClass convertProxy() {
5502             return new ProxiedClass((int) data);
5503         }
5504     }
5505 
5506     @Entity
5507     static class ProxiedClass_Entity
5508         extends EvolveCase {
5509 
5510         private static final String NAME =
5511             ProxiedClass_Entity.class.getName();
5512         private static final String NAME2 =
5513             ProxiedClass_Proxy.class.getName();
5514 
5515         @PrimaryKey
5516         int key;
5517 
5518         ProxiedClass embed;
5519 
5520         @Override
configure(EntityModel model, StoreConfig config)5521         void configure(EntityModel model, StoreConfig config) {
5522             model.registerClass(ProxiedClass_Proxy.class);
5523         }
5524 
5525         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)5526         void checkEvolvedModel(EntityModel model,
5527                                Environment env,
5528                                boolean oldTypesExist) {
5529             checkEntity(true, model, env, NAME, 0, null);
5530             checkVersions(model, NAME, 0);
5531             if (oldTypesExist) {
5532                 checkVersions(model, NAME2, 1, NAME2, 0);
5533             } else {
5534                 checkVersions(model, NAME2, 1);
5535             }
5536         }
5537 
5538         @Override
readObjects(EntityStore store, boolean doUpdate)5539         void readObjects(EntityStore store, boolean doUpdate)
5540             throws DatabaseException {
5541 
5542             PrimaryIndex<Integer, ProxiedClass_Entity>
5543                 index = store.getPrimaryIndex
5544                     (Integer.class,
5545                      ProxiedClass_Entity.class);
5546             ProxiedClass_Entity obj = index.get(99);
5547             TestCase.assertNotNull(obj);
5548             TestCase.assertEquals(99, obj.key);
5549             TestCase.assertNotNull(obj.embed);
5550             TestCase.assertEquals(88, obj.embed.data);
5551 
5552             if (doUpdate) {
5553                 index.put(obj);
5554             }
5555         }
5556 
5557         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)5558         void copyRawObjects(RawStore rawStore, EntityStore newStore)
5559             throws DatabaseException {
5560 
5561             PrimaryIndex<Integer, ProxiedClass_Entity>
5562                 index = newStore.getPrimaryIndex
5563                     (Integer.class,
5564                      ProxiedClass_Entity.class);
5565             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
5566             index.put((ProxiedClass_Entity)
5567                       newStore.getModel().convertRawObject(raw));
5568         }
5569 
5570         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)5571         void readRawObjects(RawStore store,
5572                             boolean expectEvolved,
5573                             boolean expectUpdated)
5574             throws DatabaseException {
5575 
5576             RawType embedType = store.getModel().getRawType(NAME2);
5577             RawObject embed;
5578             if (expectEvolved) {
5579                 embed = new RawObject
5580                     (embedType, makeValues("data", 88L), null);
5581             } else {
5582                 embed = new RawObject
5583                     (embedType, makeValues("data", 88), null);
5584             }
5585             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
5586             checkRawFields(obj, "key", 99, "embed", embed);
5587         }
5588     }
5589 
5590     @Persistent(proxyFor=StringBuilder.class)
5591     static class DisallowChangeProxyFor_Proxy2
5592         implements PersistentProxy<StringBuilder> {
5593 
5594         String data;
5595 
initializeProxy(StringBuilder o)5596         public void initializeProxy(StringBuilder o) {
5597             data = o.toString();
5598         }
5599 
convertProxy()5600         public StringBuilder convertProxy() {
5601             return new StringBuilder(data);
5602         }
5603     }
5604 
5605     @Persistent(proxyFor=StringBuilder.class)
5606     static class DisallowChangeProxyFor_Proxy
5607         implements PersistentProxy<StringBuilder> {
5608 
5609         String data;
5610 
initializeProxy(StringBuilder o)5611         public void initializeProxy(StringBuilder o) {
5612             data = o.toString();
5613         }
5614 
convertProxy()5615         public StringBuilder convertProxy() {
5616             return new StringBuilder(data);
5617         }
5618     }
5619 
5620     @Entity
5621     static class DisallowChangeProxyFor
5622         extends EvolveCase {
5623 
5624         @PrimaryKey
5625         int key;
5626 
5627         @Override
getStoreOpenException()5628         public String getStoreOpenException() {
5629             return "com.sleepycat.persist.evolve.IncompatibleClassException: Error when evolving class: java.lang.StringBuilder version: 0 to class: java.lang.StringBuilder version: 0 Error: The proxy class for this type has been changed from: com.sleepycat.persist.test.EvolveClasses$DisallowChangeProxyFor_Proxy to: com.sleepycat.persist.test.EvolveClasses$DisallowChangeProxyFor_Proxy2";
5630         }
5631 
5632         @Override
configure(EntityModel model, StoreConfig config)5633         void configure(EntityModel model, StoreConfig config) {
5634             //model.registerClass(DisallowChangeProxyFor_Proxy.class);
5635             model.registerClass(DisallowChangeProxyFor_Proxy2.class);
5636         }
5637     }
5638 
5639     @Persistent
5640     static class DisallowDeleteProxyFor_Proxy {
5641         String data;
5642     }
5643 
5644     @Entity
5645     static class DisallowDeleteProxyFor
5646         extends EvolveCase {
5647 
5648         @PrimaryKey
5649         int key;
5650 
5651         @Override
getStoreOpenException()5652         public String getStoreOpenException() {
5653             return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: java.lang.StringBuilder version: 0 Error: java.lang.IllegalArgumentException: Class could not be loaded or is not persistent: java.lang.StringBuilder";
5654         }
5655     }
5656 
5657     @Persistent(version=1)
5658     static class ArrayNameChange_Component_Renamed {
5659 
5660         long data;
5661     }
5662 
5663     @Entity
5664     static class ArrayNameChange_Entity
5665         extends EvolveCase {
5666 
5667         private static final String NAME =
5668             ArrayNameChange_Entity.class.getName();
5669         private static final String NAME2 =
5670             ArrayNameChange_Component_Renamed.class.getName();
5671         private static final String NAME3 =
5672             PREFIX + "ArrayNameChange_Component";
5673 
5674         @PrimaryKey
5675         int key;
5676 
5677         ArrayNameChange_Component_Renamed[] embed;
5678         ArrayNameChange_Component_Renamed embed2;
5679 
5680         @Override
getMutations()5681         Mutations getMutations() {
5682             Mutations m = new Mutations();
5683             m.addRenamer(new Renamer(NAME3, 0, NAME2));
5684             return m;
5685         }
5686 
5687         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)5688         void checkEvolvedModel(EntityModel model,
5689                                Environment env,
5690                                boolean oldTypesExist) {
5691             checkEntity(true, model, env, NAME, 0, null);
5692             checkVersions(model, NAME, 0);
5693             if (oldTypesExist) {
5694                 checkVersions(model, NAME2, 1, NAME3, 0);
5695             } else {
5696                 checkVersions(model, NAME2, 1);
5697             }
5698         }
5699 
5700         @Override
readObjects(EntityStore store, boolean doUpdate)5701         void readObjects(EntityStore store, boolean doUpdate)
5702             throws DatabaseException {
5703 
5704             PrimaryIndex<Integer, ArrayNameChange_Entity>
5705                 index = store.getPrimaryIndex
5706                     (Integer.class,
5707                      ArrayNameChange_Entity.class);
5708             ArrayNameChange_Entity obj = index.get(99);
5709             TestCase.assertNotNull(obj);
5710             TestCase.assertEquals(99, obj.key);
5711             TestCase.assertNotNull(obj.embed);
5712             TestCase.assertEquals(1, obj.embed.length);
5713             TestCase.assertEquals(88L, obj.embed[0].data);
5714             TestCase.assertSame(obj.embed2, obj.embed[0]);
5715 
5716             if (doUpdate) {
5717                 index.put(obj);
5718             }
5719         }
5720 
5721         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)5722         void copyRawObjects(RawStore rawStore, EntityStore newStore)
5723             throws DatabaseException {
5724 
5725             PrimaryIndex<Integer, ArrayNameChange_Entity>
5726                 index = newStore.getPrimaryIndex
5727                     (Integer.class,
5728                      ArrayNameChange_Entity.class);
5729             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
5730             index.put((ArrayNameChange_Entity)
5731                       newStore.getModel().convertRawObject(raw));
5732         }
5733 
5734         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)5735         void readRawObjects(RawStore store,
5736                             boolean expectEvolved,
5737                             boolean expectUpdated)
5738             throws DatabaseException {
5739 
5740             String compTypeName = expectEvolved ? NAME2 : NAME3;
5741             String arrayTypeName = "[L" + compTypeName + ';';
5742             RawType compType = store.getModel().getRawType(compTypeName);
5743             RawType arrayType = store.getModel().getRawType(arrayTypeName);
5744             RawObject embed2;
5745             if (expectEvolved) {
5746                 embed2 = new RawObject
5747                     (compType, makeValues("data", 88L), null);
5748             } else {
5749                 embed2 = new RawObject
5750                     (compType, makeValues("data", 88), null);
5751             }
5752             RawObject embed = new RawObject
5753                 (arrayType, new Object[] { embed2 });
5754             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
5755             checkRawFields(obj, "key", 99, "embed", embed, "embed2", embed2);
5756         }
5757     }
5758 
5759     enum AddEnumConstant_Enum {
5760         A, B, C;
5761     }
5762 
5763     @Entity(version=1)
5764     static class AddEnumConstant_Entity
5765         extends EvolveCase {
5766 
5767         private static final String NAME =
5768             AddEnumConstant_Entity.class.getName();
5769         private static final String NAME2 =
5770             AddEnumConstant_Enum.class.getName();
5771 
5772         @PrimaryKey
5773         int key;
5774 
5775         AddEnumConstant_Enum e1;
5776         AddEnumConstant_Enum e2;
5777         AddEnumConstant_Enum e3 = AddEnumConstant_Enum.C;
5778 
5779         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)5780         void checkEvolvedModel(EntityModel model,
5781                                Environment env,
5782                                boolean oldTypesExist) {
5783             checkEntity(true, model, env, NAME, 1, null);
5784             if (oldTypesExist) {
5785                 checkVersions(model, NAME, 1, NAME, 0);
5786                 checkVersions(model, NAME2, 0, NAME2, 0);
5787             } else {
5788                 checkVersions(model, NAME, 1);
5789                 checkVersions(model, NAME2, 0);
5790             }
5791         }
5792 
5793         @Override
readObjects(EntityStore store, boolean doUpdate)5794         void readObjects(EntityStore store, boolean doUpdate)
5795             throws DatabaseException {
5796 
5797             PrimaryIndex<Integer, AddEnumConstant_Entity>
5798                 index = store.getPrimaryIndex
5799                     (Integer.class,
5800                      AddEnumConstant_Entity.class);
5801             AddEnumConstant_Entity obj = index.get(99);
5802             TestCase.assertNotNull(obj);
5803             TestCase.assertEquals(99, obj.key);
5804             TestCase.assertSame(AddEnumConstant_Enum.A, obj.e1);
5805             TestCase.assertSame(AddEnumConstant_Enum.B, obj.e2);
5806             TestCase.assertSame(AddEnumConstant_Enum.C, obj.e3);
5807 
5808             if (doUpdate) {
5809                 index.put(obj);
5810             }
5811         }
5812 
5813         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)5814         void copyRawObjects(RawStore rawStore, EntityStore newStore)
5815             throws DatabaseException {
5816 
5817             PrimaryIndex<Integer, AddEnumConstant_Entity>
5818                 index = newStore.getPrimaryIndex
5819                     (Integer.class,
5820                      AddEnumConstant_Entity.class);
5821             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
5822             index.put((AddEnumConstant_Entity)
5823                       newStore.getModel().convertRawObject(raw));
5824         }
5825 
5826         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)5827         void readRawObjects(RawStore store,
5828                             boolean expectEvolved,
5829                             boolean expectUpdated)
5830             throws DatabaseException {
5831 
5832             RawObject obj = readRaw
5833                 (store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
5834             RawType enumType = store.getModel().getRawType(NAME2);
5835             if (expectUpdated) {
5836                 checkRawFields(obj, "key", 99,
5837                                "e1", new RawObject(enumType, "A"),
5838                                "e2", new RawObject(enumType, "B"),
5839                                "e3", new RawObject(enumType, "C"));
5840             } else {
5841                 checkRawFields(obj, "key", 99,
5842                                "e1", new RawObject(enumType, "A"),
5843                                "e2", new RawObject(enumType, "B"));
5844             }
5845         }
5846     }
5847 
5848     enum InsertEnumConstant_Enum {
5849         X, A, Y, B, Z;
5850     }
5851 
5852     @Persistent
5853     static class InsertEnumConstant_KeyClass
5854         implements Comparable<InsertEnumConstant_KeyClass > {
5855 
5856         @KeyField(1)
5857         InsertEnumConstant_Enum key;
5858 
InsertEnumConstant_KeyClass()5859         private InsertEnumConstant_KeyClass() {}
5860 
InsertEnumConstant_KeyClass(InsertEnumConstant_Enum key)5861         InsertEnumConstant_KeyClass(InsertEnumConstant_Enum key) {
5862             this.key = key;
5863         }
5864 
compareTo(InsertEnumConstant_KeyClass o)5865         public int compareTo(InsertEnumConstant_KeyClass o) {
5866             /* Use the natural order, in spite of insertions. */
5867             return key.compareTo(o.key);
5868         }
5869     }
5870 
5871     @Entity(version=1)
5872     static class InsertEnumConstant_Entity
5873         extends EvolveCase {
5874 
5875         private static final String NAME =
5876             InsertEnumConstant_Entity.class.getName();
5877         private static final String NAME2 =
5878             InsertEnumConstant_Enum.class.getName();
5879         private static final String NAME3 =
5880             InsertEnumConstant_KeyClass.class.getName();
5881 
5882         @PrimaryKey
5883         int key;
5884 
5885         @SecondaryKey(relate=MANY_TO_ONE)
5886         InsertEnumConstant_KeyClass secKey;
5887 
5888         InsertEnumConstant_Enum e1;
5889         InsertEnumConstant_Enum e2;
5890         InsertEnumConstant_Enum e3 = InsertEnumConstant_Enum.X;
5891         InsertEnumConstant_Enum e4 = InsertEnumConstant_Enum.Y;
5892         InsertEnumConstant_Enum e5 = InsertEnumConstant_Enum.Z;
5893 
5894         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)5895         void checkEvolvedModel(EntityModel model,
5896                                Environment env,
5897                                boolean oldTypesExist) {
5898             checkEntity(true, model, env, NAME, 1, null);
5899             if (oldTypesExist) {
5900                 checkVersions(model, NAME, 1, NAME, 0);
5901                 checkVersions(model, NAME2, 0, NAME2, 0);
5902                 checkVersions(model, NAME3, 0, NAME3, 0);
5903             } else {
5904                 checkVersions(model, NAME, 1);
5905                 checkVersions(model, NAME2, 0);
5906                 checkVersions(model, NAME3, 0);
5907             }
5908         }
5909 
5910         @Override
readObjects(EntityStore store, boolean doUpdate)5911         void readObjects(EntityStore store, boolean doUpdate)
5912             throws DatabaseException {
5913 
5914             PrimaryIndex<Integer, InsertEnumConstant_Entity>
5915                 index = store.getPrimaryIndex
5916                     (Integer.class,
5917                      InsertEnumConstant_Entity.class);
5918             InsertEnumConstant_Entity obj = index.get(99);
5919             TestCase.assertNotNull(obj);
5920             TestCase.assertEquals(99, obj.key);
5921             if (updated) {
5922                 TestCase.assertSame(InsertEnumConstant_Enum.X, obj.secKey.key);
5923             } else {
5924                 TestCase.assertSame(InsertEnumConstant_Enum.A, obj.secKey.key);
5925             }
5926             TestCase.assertSame(InsertEnumConstant_Enum.A, obj.e1);
5927             TestCase.assertSame(InsertEnumConstant_Enum.B, obj.e2);
5928             TestCase.assertSame(InsertEnumConstant_Enum.X, obj.e3);
5929             TestCase.assertSame(InsertEnumConstant_Enum.Y, obj.e4);
5930             TestCase.assertSame(InsertEnumConstant_Enum.Z, obj.e5);
5931 
5932             if (doUpdate) {
5933                 obj.secKey =
5934                     new InsertEnumConstant_KeyClass(InsertEnumConstant_Enum.X);
5935                 index.put(obj);
5936                 updated = true;
5937             }
5938         }
5939 
5940         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)5941         void copyRawObjects(RawStore rawStore, EntityStore newStore)
5942             throws DatabaseException {
5943 
5944             PrimaryIndex<Integer, InsertEnumConstant_Entity>
5945                 index = newStore.getPrimaryIndex
5946                     (Integer.class,
5947                      InsertEnumConstant_Entity.class);
5948             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
5949             index.put((InsertEnumConstant_Entity)
5950                       newStore.getModel().convertRawObject(raw));
5951         }
5952 
5953         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)5954         void readRawObjects(RawStore store,
5955                             boolean expectEvolved,
5956                             boolean expectUpdated)
5957             throws DatabaseException {
5958 
5959             RawObject obj = readRaw
5960                 (store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
5961             RawType enumType = store.getModel().getRawType(NAME2);
5962 
5963             Map<String, Object> secKeyFields = new HashMap<String, Object>();
5964             RawType secKeyType = store.getModel().getRawType(NAME3);
5965             RawObject secKeyObject =
5966                 new RawObject(secKeyType, secKeyFields, null /*superObject*/);
5967 
5968             if (expectUpdated) {
5969                 secKeyFields.put("key", new RawObject(enumType, "X"));
5970                 checkRawFields(obj, "key", 99,
5971                                "secKey", secKeyObject,
5972                                "e1", new RawObject(enumType, "A"),
5973                                "e2", new RawObject(enumType, "B"),
5974                                "e3", new RawObject(enumType, "X"),
5975                                "e4", new RawObject(enumType, "Y"),
5976                                "e5", new RawObject(enumType, "Z"));
5977             } else {
5978                 secKeyFields.put("key", new RawObject(enumType, "A"));
5979                 checkRawFields(obj, "key", 99,
5980                                "secKey", secKeyObject,
5981                                "e1", new RawObject(enumType, "A"),
5982                                "e2", new RawObject(enumType, "B"));
5983             }
5984         }
5985     }
5986 
5987     enum DeleteEnumConstant_Enum {
5988         A, C;
5989     }
5990 
5991     /**
5992      * Don't allow deleting (or renaming, which appears as a deletion) enum
5993      * values without mutations.
5994      */
5995     @Entity
5996     static class DeleteEnumConstant_NoMutation
5997         extends EvolveCase {
5998 
5999         @PrimaryKey
6000         int key;
6001 
6002         DeleteEnumConstant_Enum e1;
6003         DeleteEnumConstant_Enum e2;
6004         DeleteEnumConstant_Enum e3;
6005 
6006         @Override
getStoreOpenException()6007         public String getStoreOpenException() {
6008             return "com.sleepycat.persist.evolve.IncompatibleClassException: Incompatible enum type changed detected when evolving class: com.sleepycat.persist.test.EvolveClasses$DeleteEnumConstant_Enum version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DeleteEnumConstant_Enum version: 0 Error: Enum values may not be removed: [B]";
6009         }
6010     }
6011 
6012     /**
6013      * With a Deleter, deleted enum values are null.  Note that version is not
6014      * bumped.
6015      */
6016     /* Disabled until support for enum deletion is added.
6017     @Entity
6018     static class DeleteEnumConstant_WithDeleter
6019         extends EvolveCase {
6020 
6021         private static final String NAME =
6022             DeleteEnumConstant_WithDeleter.class.getName();
6023         private static final String NAME2 =
6024             DeleteEnumConstant_Enum.class.getName();
6025 
6026         @PrimaryKey
6027         int key;
6028 
6029         DeleteEnumConstant_Enum e1;
6030         DeleteEnumConstant_Enum e2;
6031         DeleteEnumConstant_Enum e3;
6032 
6033         @Override
6034         void checkEvolvedModel(EntityModel model,
6035                                Environment env,
6036                                boolean oldTypesExist) {
6037             checkEntity(true, model, env, NAME, 0, null);
6038             checkVersions(model, NAME, 0);
6039             if (oldTypesExist) {
6040                 checkVersions(model, NAME2, 0, NAME2, 0);
6041             } else {
6042                 checkVersions(model, NAME2, 0);
6043             }
6044         }
6045 
6046         @Override
6047         void readObjects(EntityStore store, boolean doUpdate)
6048             throws DatabaseException {
6049 
6050             PrimaryIndex<Integer, DeleteEnumConstant_WithDeleter>
6051                 index = store.getPrimaryIndex
6052                     (Integer.class,
6053                      DeleteEnumConstant_WithDeleter.class);
6054             DeleteEnumConstant_WithDeleter obj = index.get(99);
6055             TestCase.assertNotNull(obj);
6056             TestCase.assertEquals(99, obj.key);
6057             TestCase.assertSame(DeleteEnumConstant_Enum.A, obj.e1);
6058             TestCase.assertSame(null, obj.e2);
6059             TestCase.assertSame(DeleteEnumConstant_Enum.C, obj.e3);
6060 
6061             if (doUpdate) {
6062                 index.put(obj);
6063             }
6064         }
6065 
6066         @Override
6067         void copyRawObjects(RawStore rawStore, EntityStore newStore)
6068             throws DatabaseException {
6069 
6070             PrimaryIndex<Integer, DeleteEnumConstant_WithDeleter>
6071                 index = newStore.getPrimaryIndex
6072                     (Integer.class,
6073                      DeleteEnumConstant_WithDeleter.class);
6074             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
6075             index.put((DeleteEnumConstant_WithDeleter)
6076                       newStore.getModel().convertRawObject(raw));
6077         }
6078 
6079         @Override
6080         void readRawObjects(RawStore store,
6081                             boolean expectEvolved,
6082                             boolean expectUpdated)
6083             throws DatabaseException {
6084 
6085             RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
6086             RawType enumType = store.getModel().getRawType(NAME2);
6087             if (expectUpdated) {
6088                 checkRawFields(obj, "key", 99,
6089                                "e1", new RawObject(enumType, "A"),
6090                                "e2", null,
6091                                "e3", new RawObject(enumType, "C"));
6092             } else {
6093                 checkRawFields(obj, "key", 99,
6094                                "e1", new RawObject(enumType, "A"),
6095                                "e2", new RawObject(enumType, "B"),
6096                                "e3", new RawObject(enumType, "C"));
6097             }
6098         }
6099     }
6100     */
6101 
6102     /**
6103      * A field converter can assign deleted enum values.  Version must be
6104      * bumped when a converter is added.
6105      */
6106     /* Disabled until support for enum deletion is added.
6107     @Entity(version=1)
6108     static class DeleteEnumConstant_WithConverter
6109         extends EvolveCase {
6110 
6111         private static final String NAME =
6112             DeleteEnumConstant_WithConverter.class.getName();
6113         private static final String NAME2 =
6114             DeleteEnumConstant_Enum.class.getName();
6115 
6116         @PrimaryKey
6117         int key;
6118 
6119         DeleteEnumConstant_Enum e1;
6120         DeleteEnumConstant_Enum e2;
6121         DeleteEnumConstant_Enum e3;
6122 
6123         @Override
6124         Mutations getMutations() {
6125             Mutations m = new Mutations();
6126             Conversion c = new MyConversion();
6127             m.addConverter(new Converter(NAME, 0, "e1", c));
6128             m.addConverter(new Converter(NAME, 0, "e2", c));
6129             m.addConverter(new Converter(NAME, 0, "e3", c));
6130             return m;
6131         }
6132 
6133         @SuppressWarnings("serial")
6134         static class MyConversion implements Conversion {
6135 
6136             transient RawType newType;
6137 
6138             public void initialize(EntityModel model) {
6139                 newType = model.getRawType(NAME2);
6140                 TestCase.assertNotNull(newType);
6141             }
6142 
6143             public Object convert(Object fromValue) {
6144                 TestCase.assertNotNull(newType);
6145                 RawObject obj = (RawObject) fromValue;
6146                 String val = obj.getEnum();
6147                 TestCase.assertNotNull(val);
6148                 if ("B".equals(val)) {
6149                     val = "C";
6150                 }
6151                 return new RawObject(newType, val);
6152             }
6153 
6154             @Override
6155             public boolean equals(Object other) {
6156                 return other instanceof MyConversion;
6157             }
6158         }
6159 
6160         @Override
6161         void checkEvolvedModel(EntityModel model,
6162                                Environment env,
6163                                boolean oldTypesExist) {
6164             checkEntity(true, model, env, NAME, 1, null);
6165             if (oldTypesExist) {
6166                 checkVersions(model, NAME, 1, NAME, 0);
6167                 checkVersions(model, NAME2, 0, NAME2, 0);
6168             } else {
6169                 checkVersions(model, NAME, 1);
6170                 checkVersions(model, NAME2, 0);
6171             }
6172         }
6173 
6174         @Override
6175         void readObjects(EntityStore store, boolean doUpdate)
6176             throws DatabaseException {
6177 
6178             PrimaryIndex<Integer, DeleteEnumConstant_WithConverter>
6179                 index = store.getPrimaryIndex
6180                     (Integer.class,
6181                      DeleteEnumConstant_WithConverter.class);
6182             DeleteEnumConstant_WithConverter obj = index.get(99);
6183             TestCase.assertNotNull(obj);
6184             TestCase.assertEquals(99, obj.key);
6185             TestCase.assertSame(DeleteEnumConstant_Enum.A, obj.e1);
6186             TestCase.assertSame(DeleteEnumConstant_Enum.C, obj.e2);
6187             TestCase.assertSame(DeleteEnumConstant_Enum.C, obj.e3);
6188 
6189             if (doUpdate) {
6190                 index.put(obj);
6191             }
6192         }
6193 
6194         @Override
6195         void copyRawObjects(RawStore rawStore, EntityStore newStore)
6196             throws DatabaseException {
6197 
6198             PrimaryIndex<Integer, DeleteEnumConstant_WithConverter>
6199                 index = newStore.getPrimaryIndex
6200                     (Integer.class,
6201                      DeleteEnumConstant_WithConverter.class);
6202             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
6203             index.put((DeleteEnumConstant_WithConverter)
6204                       newStore.getModel().convertRawObject(raw));
6205         }
6206 
6207         @Override
6208         void readRawObjects(RawStore store,
6209                             boolean expectEvolved,
6210                             boolean expectUpdated)
6211             throws DatabaseException {
6212 
6213             RawObject obj = readRaw(store, 99, NAME, expectEvolved ? 1 : 0,
6214                                     CASECLS, 0);
6215             RawType enumType = store.getModel().getRawType(NAME2);
6216             if (expectEvolved) {
6217                 checkRawFields(obj, "key", 99,
6218                                "e1", new RawObject(enumType, "A"),
6219                                "e2", new RawObject(enumType, "C"),
6220                                "e3", new RawObject(enumType, "C"));
6221             } else {
6222                 checkRawFields(obj, "key", 99,
6223                                "e1", new RawObject(enumType, "A"),
6224                                "e2", new RawObject(enumType, "B"),
6225                                "e3", new RawObject(enumType, "C"));
6226             }
6227         }
6228     }
6229     */
6230 
6231     @Entity
6232     static class DisallowChangeKeyRelate
6233         extends EvolveCase {
6234 
6235         private static final String NAME =
6236             DisallowChangeKeyRelate.class.getName();
6237 
6238         @PrimaryKey
6239         int key;
6240 
6241         @SecondaryKey(relate=MANY_TO_ONE)
6242         int skey;
6243 
6244         @Override
getStoreOpenException()6245         public String getStoreOpenException() {
6246             return "com.sleepycat.persist.evolve.IncompatibleClassException: Change detected in the relate attribute (Relationship) of a secondary key when evolving class: com.sleepycat.persist.test.EvolveClasses$DisallowChangeKeyRelate version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DisallowChangeKeyRelate version: 0 Error: Old key: skey relate: ONE_TO_ONE new key: skey relate: MANY_TO_ONE";
6247         }
6248     }
6249 
6250     @Entity(version=1)
6251     static class AllowChangeKeyMetadata
6252         extends EvolveCase {
6253 
6254         private static final String NAME =
6255             AllowChangeKeyMetadata.class.getName();
6256 
6257         @PrimaryKey
6258         int key;
6259 
6260         /*
6261          * Combined fields from version 0 and 1:
6262          *  addAnnotation = 88;
6263          *  dropField = 77;
6264          *  dropAnnotation = 66;
6265          *  addField = 55;
6266          *  renamedField = 44; // was toBeRenamedField
6267          *  aa = 33;
6268          *  ff = 22;
6269          */
6270 
6271         int aa;
6272 
6273         @SecondaryKey(relate=ONE_TO_ONE)
6274         int addAnnotation;
6275 
6276         int dropAnnotation;
6277 
6278         @SecondaryKey(relate=ONE_TO_ONE)
6279         Integer addField;
6280 
6281         @SecondaryKey(relate=ONE_TO_ONE)
6282         int renamedField;
6283 
6284         int ff;
6285 
6286         @Override
getMutations()6287         Mutations getMutations() {
6288             Mutations m = new Mutations();
6289             m.addDeleter(new Deleter(NAME, 0, "dropField"));
6290             m.addRenamer(new Renamer(NAME, 0, "toBeRenamedField",
6291                                               "renamedField"));
6292             return m;
6293         }
6294 
6295         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)6296         void checkEvolvedModel(EntityModel model,
6297                                Environment env,
6298                                boolean oldTypesExist) {
6299             checkEntity(true, model, env, NAME, 1, null);
6300             if (oldTypesExist) {
6301                 checkVersions(model, NAME, 1, NAME, 0);
6302             } else {
6303                 checkVersions(model, NAME, 1);
6304             }
6305         }
6306 
6307         @Override
readObjects(EntityStore store, boolean doUpdate)6308         void readObjects(EntityStore store, boolean doUpdate)
6309             throws DatabaseException {
6310 
6311             PrimaryIndex<Integer, AllowChangeKeyMetadata>
6312                 index = store.getPrimaryIndex
6313                     (Integer.class,
6314                      AllowChangeKeyMetadata.class);
6315             AllowChangeKeyMetadata obj = index.get(99);
6316             checkValues(obj);
6317 
6318             if (newMetadataWritten) {
6319                 checkValues(store.getSecondaryIndex
6320                     (index, Integer.class, "addAnnotation").get(88));
6321                 checkValues(store.getSecondaryIndex
6322                     (index, Integer.class, "renamedField").get(44));
6323                 if (updated) {
6324                     checkValues(store.getSecondaryIndex
6325                         (index, Integer.class, "addField").get(55));
6326                 } else {
6327                     TestCase.assertNull(store.getSecondaryIndex
6328                         (index, Integer.class, "addField").get(55));
6329                 }
6330 
6331                 if (doUpdate) {
6332                     obj.addField = 55;
6333                     index.put(obj);
6334                     updated = true;
6335                     checkValues(store.getSecondaryIndex
6336                         (index, Integer.class, "addAnnotation").get(88));
6337                     checkValues(store.getSecondaryIndex
6338                         (index, Integer.class, "addField").get(55));
6339                 }
6340             }
6341         }
6342 
6343         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)6344         void copyRawObjects(RawStore rawStore, EntityStore newStore)
6345             throws DatabaseException {
6346 
6347             PrimaryIndex<Integer, AllowChangeKeyMetadata>
6348                 index = newStore.getPrimaryIndex
6349                     (Integer.class,
6350                      AllowChangeKeyMetadata.class);
6351             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
6352             index.put((AllowChangeKeyMetadata)
6353                       newStore.getModel().convertRawObject(raw));
6354         }
6355 
checkValues(AllowChangeKeyMetadata obj)6356         private void checkValues(AllowChangeKeyMetadata obj) {
6357             TestCase.assertNotNull(obj);
6358             TestCase.assertEquals(99, obj.key);
6359             TestCase.assertEquals(88, obj.addAnnotation);
6360             TestCase.assertEquals(66, obj.dropAnnotation);
6361             TestCase.assertEquals(44, obj.renamedField);
6362             TestCase.assertEquals(33, obj.aa);
6363             TestCase.assertEquals(22, obj.ff);
6364             if (updated) {
6365                 TestCase.assertEquals(Integer.valueOf(55), obj.addField);
6366             } else {
6367                 TestCase.assertNull(obj.addField);
6368             }
6369         }
6370 
6371         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)6372         void readRawObjects(RawStore store,
6373                             boolean expectEvolved,
6374                             boolean expectUpdated)
6375             throws DatabaseException {
6376 
6377             RawObject obj = readRaw
6378                 (store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
6379             if (expectUpdated) {
6380                 checkRawFields(obj, "key", 99,
6381                                "addAnnotation", 88,
6382                                "dropAnnotation", 66,
6383                                "addField", 55,
6384                                "renamedField", 44,
6385                                "aa", 33,
6386                                "ff", 22);
6387             } else if (expectEvolved) {
6388                 checkRawFields(obj, "key", 99,
6389                                "addAnnotation", 88,
6390                                "dropAnnotation", 66,
6391                                "renamedField", 44,
6392                                "aa", 33,
6393                                "ff", 22);
6394             } else {
6395                 checkRawFields(obj, "key", 99,
6396                                "addAnnotation", 88,
6397                                "dropField", 77,
6398                                "dropAnnotation", 66,
6399                                "toBeRenamedField", 44,
6400                                "aa", 33,
6401                                "ff", 22);
6402             }
6403             Environment env = store.getEnvironment();
6404             assertDbExists(expectEvolved, env, NAME, "addAnnotation");
6405             assertDbExists(expectEvolved, env, NAME, "addField");
6406             assertDbExists(expectEvolved, env, NAME, "renamedField");
6407             assertDbExists(!expectEvolved, env, NAME, "toBeRenamedField");
6408             assertDbExists(!expectEvolved, env, NAME, "dropField");
6409             assertDbExists(!expectEvolved, env, NAME, "dropAnnotation");
6410         }
6411     }
6412 
6413     /**
6414      * Same test as AllowChangeKeyMetadata but with the secondary keys in an
6415      * entity subclass.  [#16253]
6416      */
6417     @Persistent(version=1)
6418     static class AllowChangeKeyMetadataInSubclass
6419         extends AllowChangeKeyMetadataEntity {
6420 
6421         private static final String NAME =
6422             AllowChangeKeyMetadataInSubclass.class.getName();
6423         private static final String NAME2 =
6424             AllowChangeKeyMetadataEntity.class.getName();
6425 
6426         /*
6427          * Combined fields from version 0 and 1:
6428          *  addAnnotation = 88;
6429          *  dropField = 77;
6430          *  dropAnnotation = 66;
6431          *  addField = 55;
6432          *  renamedField = 44; // was toBeRenamedField
6433          *  aa = 33;
6434          *  ff = 22;
6435          */
6436 
6437         int aa;
6438 
6439         @SecondaryKey(relate=ONE_TO_ONE)
6440         int addAnnotation;
6441 
6442         int dropAnnotation;
6443 
6444         @SecondaryKey(relate=ONE_TO_ONE)
6445         Integer addField;
6446 
6447         @SecondaryKey(relate=ONE_TO_ONE)
6448         int renamedField;
6449 
6450         int ff;
6451 
6452         @Override
configure(EntityModel model, StoreConfig config)6453         void configure(EntityModel model, StoreConfig config) {
6454             model.registerClass(AllowChangeKeyMetadataInSubclass.class);
6455         }
6456 
6457         @Override
getMutations()6458         Mutations getMutations() {
6459             Mutations m = new Mutations();
6460             m.addDeleter(new Deleter(NAME, 0, "dropField"));
6461             m.addRenamer(new Renamer(NAME, 0, "toBeRenamedField",
6462                                               "renamedField"));
6463             return m;
6464         }
6465 
6466         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)6467         void checkEvolvedModel(EntityModel model,
6468                                Environment env,
6469                                boolean oldTypesExist) {
6470             checkNonEntity(true, model, env, NAME, 1);
6471             checkEntity(true, model, env, NAME2, 0, null);
6472             if (oldTypesExist) {
6473                 checkVersions(model, NAME, 1, NAME, 0);
6474                 checkVersions(model, NAME2, 0);
6475             } else {
6476                 checkVersions(model, NAME, 1);
6477                 checkVersions(model, NAME2, 0);
6478             }
6479         }
6480 
6481         @Override
readObjects(EntityStore store, boolean doUpdate)6482         void readObjects(EntityStore store, boolean doUpdate)
6483             throws DatabaseException {
6484 
6485             PrimaryIndex<Integer, AllowChangeKeyMetadataEntity>
6486                 index = store.getPrimaryIndex
6487                     (Integer.class,
6488                      AllowChangeKeyMetadataEntity.class);
6489             AllowChangeKeyMetadataEntity obj = index.get(99);
6490             checkValues(obj);
6491 
6492             if (newMetadataWritten) {
6493                 checkValues(store.getSecondaryIndex
6494                     (index, Integer.class, "addAnnotation").get(88));
6495                 checkValues(store.getSecondaryIndex
6496                     (index, Integer.class, "renamedField").get(44));
6497                 if (updated) {
6498                     checkValues(store.getSecondaryIndex
6499                         (index, Integer.class, "addField").get(55));
6500                 } else {
6501                     TestCase.assertNull(store.getSecondaryIndex
6502                         (index, Integer.class, "addField").get(55));
6503                 }
6504 
6505                 if (doUpdate) {
6506                     ((AllowChangeKeyMetadataInSubclass) obj).addField = 55;
6507                     index.put(obj);
6508                     updated = true;
6509                     checkValues(store.getSecondaryIndex
6510                         (index, Integer.class, "addAnnotation").get(88));
6511                     checkValues(store.getSecondaryIndex
6512                         (index, Integer.class, "addField").get(55));
6513                 }
6514             }
6515         }
6516 
6517         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)6518         void copyRawObjects(RawStore rawStore, EntityStore newStore)
6519             throws DatabaseException {
6520 
6521             PrimaryIndex<Integer, AllowChangeKeyMetadataEntity>
6522                 index = newStore.getPrimaryIndex
6523                     (Integer.class,
6524                      AllowChangeKeyMetadataEntity.class);
6525             RawObject raw = rawStore.getPrimaryIndex(NAME2).get(99);
6526             index.put((AllowChangeKeyMetadataInSubclass)
6527                       newStore.getModel().convertRawObject(raw));
6528         }
6529 
checkValues(AllowChangeKeyMetadataEntity objParam)6530         private void checkValues(AllowChangeKeyMetadataEntity objParam) {
6531             AllowChangeKeyMetadataInSubclass obj =
6532                 (AllowChangeKeyMetadataInSubclass) objParam;
6533             TestCase.assertNotNull(obj);
6534             TestCase.assertEquals(99, obj.key);
6535             TestCase.assertEquals(88, obj.addAnnotation);
6536             TestCase.assertEquals(66, obj.dropAnnotation);
6537             TestCase.assertEquals(44, obj.renamedField);
6538             TestCase.assertEquals(33, obj.aa);
6539             TestCase.assertEquals(22, obj.ff);
6540             if (updated) {
6541                 TestCase.assertEquals(Integer.valueOf(55), obj.addField);
6542             } else {
6543                 TestCase.assertNull(obj.addField);
6544             }
6545         }
6546 
6547         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)6548         void readRawObjects(RawStore store,
6549                             boolean expectEvolved,
6550                             boolean expectUpdated)
6551             throws DatabaseException {
6552 
6553             RawObject obj = readRaw
6554                 (store, NAME2, 99, NAME, expectEvolved ? 1 : 0,
6555                  NAME2, 0, CASECLS, 0);
6556             checkRawFields(obj.getSuper(), "key", 99);
6557             if (expectUpdated) {
6558                 checkRawFields(obj,
6559                                "addAnnotation", 88,
6560                                "dropAnnotation", 66,
6561                                "addField", 55,
6562                                "renamedField", 44,
6563                                "aa", 33,
6564                                "ff", 22);
6565             } else if (expectEvolved) {
6566                 checkRawFields(obj,
6567                                "addAnnotation", 88,
6568                                "dropAnnotation", 66,
6569                                "renamedField", 44,
6570                                "aa", 33,
6571                                "ff", 22);
6572             } else {
6573                 checkRawFields(obj,
6574                                "addAnnotation", 88,
6575                                "dropField", 77,
6576                                "dropAnnotation", 66,
6577                                "toBeRenamedField", 44,
6578                                "aa", 33,
6579                                "ff", 22);
6580             }
6581             Environment env = store.getEnvironment();
6582             assertDbExists(expectEvolved, env, NAME2, "addAnnotation");
6583             assertDbExists(expectEvolved, env, NAME2, "addField");
6584             assertDbExists(expectEvolved, env, NAME2, "renamedField");
6585             assertDbExists(!expectEvolved, env, NAME2, "toBeRenamedField");
6586             assertDbExists(!expectEvolved, env, NAME2, "dropField");
6587             assertDbExists(!expectEvolved, env, NAME2, "dropAnnotation");
6588         }
6589     }
6590 
6591     @Entity
6592     static class AllowChangeKeyMetadataEntity
6593         extends EvolveCase {
6594 
6595         @PrimaryKey
6596         int key;
6597     }
6598 
6599     /**
6600      * Special case of adding secondaries that caused
6601      * IndexOutOfBoundsException. [#15524]
6602      */
6603     @Entity(version=1)
6604     static class AllowAddSecondary
6605         extends EvolveCase {
6606 
6607         private static final String NAME =
6608             AllowAddSecondary.class.getName();
6609 
6610         @PrimaryKey
6611         long key;
6612 
6613         @SecondaryKey(relate=ONE_TO_ONE)
6614         int a;
6615 
6616         @SecondaryKey(relate=ONE_TO_ONE)
6617         int b;
6618 
6619         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)6620         void checkEvolvedModel(EntityModel model,
6621                                Environment env,
6622                                boolean oldTypesExist) {
6623             checkEntity(true, model, env, NAME, 1, null);
6624             if (oldTypesExist) {
6625                 checkVersions(model, NAME, 1, NAME, 0);
6626             } else {
6627                 checkVersions(model, NAME, 1);
6628             }
6629         }
6630 
6631         @Override
readObjects(EntityStore store, boolean doUpdate)6632         void readObjects(EntityStore store, boolean doUpdate)
6633             throws DatabaseException {
6634 
6635             PrimaryIndex<Long, AllowAddSecondary>
6636                 index = store.getPrimaryIndex
6637                     (Long.class,
6638                      AllowAddSecondary.class);
6639             AllowAddSecondary obj = index.get(99L);
6640             checkValues(obj);
6641 
6642             if (newMetadataWritten) {
6643                 checkValues(store.getSecondaryIndex
6644                     (index, Integer.class, "a").get(1));
6645                 if (updated) {
6646                     checkValues(store.getSecondaryIndex
6647                         (index, Integer.class, "b").get(3));
6648                     TestCase.assertNull(store.getSecondaryIndex
6649                         (index, Integer.class, "b").get(2));
6650                 } else {
6651                     checkValues(store.getSecondaryIndex
6652                         (index, Integer.class, "b").get(2));
6653                     TestCase.assertNull(store.getSecondaryIndex
6654                         (index, Integer.class, "b").get(3));
6655                 }
6656 
6657                 if (doUpdate) {
6658                     obj.b = 3;
6659                     index.put(obj);
6660                     updated = true;
6661                     checkValues(store.getSecondaryIndex
6662                         (index, Integer.class, "a").get(1));
6663                     checkValues(store.getSecondaryIndex
6664                         (index, Integer.class, "b").get(3));
6665                 }
6666             }
6667         }
6668 
6669         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)6670         void copyRawObjects(RawStore rawStore, EntityStore newStore)
6671             throws DatabaseException {
6672 
6673             PrimaryIndex<Long, AllowAddSecondary>
6674                 index = newStore.getPrimaryIndex
6675                     (Long.class,
6676                      AllowAddSecondary.class);
6677             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99L);
6678             index.put((AllowAddSecondary)
6679                       newStore.getModel().convertRawObject(raw));
6680         }
6681 
checkValues(AllowAddSecondary obj)6682         private void checkValues(AllowAddSecondary obj) {
6683             TestCase.assertNotNull(obj);
6684             TestCase.assertEquals(99L, obj.key);
6685             TestCase.assertEquals(1, obj.a);
6686             if (updated) {
6687                 TestCase.assertEquals(3, obj.b);
6688             } else {
6689                 TestCase.assertEquals(2, obj.b);
6690             }
6691         }
6692 
6693         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)6694         void readRawObjects(RawStore store,
6695                             boolean expectEvolved,
6696                             boolean expectUpdated)
6697             throws DatabaseException {
6698 
6699             RawObject obj = readRaw
6700                 (store, 99L, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
6701             if (expectUpdated) {
6702                 checkRawFields(obj, "key", 99L,
6703                                "a", 1,
6704                                "b", 3);
6705             } else {
6706                 checkRawFields(obj, "key", 99L,
6707                                "a", 1,
6708                                "b", 2);
6709             }
6710             Environment env = store.getEnvironment();
6711             assertDbExists(expectEvolved, env, NAME, "a");
6712             assertDbExists(expectEvolved, env, NAME, "b");
6713         }
6714     }
6715 
6716     @Entity(version=1)
6717     static class FieldAddAndConvert
6718         extends EvolveCase {
6719 
6720         private static final String NAME =
6721             FieldAddAndConvert.class.getName();
6722 
6723         @PrimaryKey
6724         int key;
6725 
6726         private final String f0 = "0"; // new field
6727         private final String f1 = "1"; // converted field
6728         private final String f2 = "2"; // new field
6729         private final String f3 = "3"; // converted field
6730         private final String f4 = "4"; // new field
6731 
6732         @Override
getMutations()6733         Mutations getMutations() {
6734             Mutations m = new Mutations();
6735             m.addConverter(new Converter(NAME, 0, "f1", new IntToString()));
6736             m.addConverter(new Converter(NAME, 0, "f3", new IntToString()));
6737             return m;
6738         }
6739 
6740         @SuppressWarnings("serial")
6741         private static class IntToString implements Conversion {
6742 
initialize(EntityModel model)6743             public void initialize(EntityModel model) {
6744             }
6745 
convert(Object fromValue)6746             public Object convert(Object fromValue) {
6747                 return fromValue.toString();
6748             }
6749 
6750             @Override
equals(Object other)6751             public boolean equals(Object other) {
6752                 return other instanceof IntToString;
6753             }
6754         }
6755 
6756         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)6757         void checkEvolvedModel(EntityModel model,
6758                                Environment env,
6759                                boolean oldTypesExist) {
6760             checkEntity(true, model, env, NAME, 1, null);
6761             if (oldTypesExist) {
6762                 checkVersions(model, NAME, 1, NAME, 0);
6763             } else {
6764                 checkVersions(model, NAME, 1);
6765             }
6766         }
6767 
6768         @Override
readObjects(EntityStore store, boolean doUpdate)6769         void readObjects(EntityStore store, boolean doUpdate)
6770             throws DatabaseException {
6771 
6772             PrimaryIndex<Integer, FieldAddAndConvert>
6773                 index = store.getPrimaryIndex
6774                     (Integer.class,
6775                      FieldAddAndConvert.class);
6776             FieldAddAndConvert obj = index.get(99);
6777             TestCase.assertNotNull(obj);
6778             TestCase.assertEquals(99, obj.key);
6779             TestCase.assertEquals("0", obj.f0);
6780             TestCase.assertEquals("1", obj.f1);
6781             TestCase.assertEquals("2", obj.f2);
6782             TestCase.assertEquals("3", obj.f3);
6783             TestCase.assertEquals("4", obj.f4);
6784 
6785             if (doUpdate) {
6786                 index.put(obj);
6787             }
6788         }
6789 
6790         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)6791         void copyRawObjects(RawStore rawStore, EntityStore newStore)
6792             throws DatabaseException {
6793 
6794             PrimaryIndex<Integer, FieldAddAndConvert>
6795                 index = newStore.getPrimaryIndex
6796                     (Integer.class,
6797                      FieldAddAndConvert.class);
6798             RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
6799             index.put((FieldAddAndConvert)
6800                       newStore.getModel().convertRawObject(raw));
6801         }
6802 
6803         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)6804         void readRawObjects(RawStore store,
6805                             boolean expectEvolved,
6806                             boolean expectUpdated)
6807             throws DatabaseException {
6808 
6809             RawObject obj = readRaw
6810                 (store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
6811             if (expectUpdated) {
6812                 checkRawFields(obj,
6813                                "key", 99,
6814                                "f0", "0",
6815                                "f1", "1",
6816                                "f2", "2",
6817                                "f3", "3",
6818                                "f4", "4");
6819             } else if (expectEvolved) {
6820                 checkRawFields(obj,
6821                                "key", 99,
6822                                "f1", "1",
6823                                "f3", "3");
6824             } else {
6825                 checkRawFields(obj,
6826                                "key", 99,
6827                                "f1", 1,
6828                                "f3", 3);
6829             }
6830         }
6831     }
6832 
6833     /*
6834      * [18961]Rename secKey2, so the order of secondary keys' names is changed
6835      * from: secKey->seckey2->secKey3 to new_seckey2->secKey->secKey3.
6836      */
6837     @Entity(version=1)
6838     static class RenameSecFieldDestroyOrder_1 extends EvolveCase{
6839 
6840         private static final String NAME =
6841             RenameSecFieldDestroyOrder_1.class.getName();
6842 
6843         @PrimaryKey
6844         int key;
6845 
6846         @SecondaryKey(relate=MANY_TO_ONE)
6847         String secKey;
6848 
6849         /* Rename secKey2 to new_secKey2. */
6850         @SecondaryKey(relate=MANY_TO_ONE)
6851         int new_secKey2;
6852 
6853         @SecondaryKey(relate=MANY_TO_ONE)
6854         String secKey3;
6855 
6856         @Override
getMutations()6857         Mutations getMutations() {
6858             Mutations m = new Mutations();
6859             m.addRenamer(new Renamer(NAME, 0, "secKey2", "new_secKey2"));
6860             return m;
6861         }
6862 
6863         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)6864         void checkEvolvedModel(EntityModel model,
6865                                Environment env,
6866                                boolean oldTypesExist) {
6867             checkEntity(true, model, env, NAME, 1, null);
6868             if (oldTypesExist) {
6869                 checkVersions(model, NAME, 1, NAME, 0);
6870             } else {
6871                 checkVersions(model, NAME, 1);
6872             }
6873         }
6874 
6875         @Override
readObjects(EntityStore store, boolean doUpdate)6876         void readObjects(EntityStore store, boolean doUpdate)
6877             throws DatabaseException {
6878 
6879             PrimaryIndex<Integer, RenameSecFieldDestroyOrder_1>
6880                 index = store.getPrimaryIndex
6881                     (Integer.class, RenameSecFieldDestroyOrder_1.class);
6882             RenameSecFieldDestroyOrder_1 obj = index.get(1);
6883             checkValues(obj);
6884             checkSecondaries(store, index);
6885 
6886             if (doUpdate) {
6887                 index.put(obj);
6888                 checkSecondaries(store, index);
6889             }
6890         }
6891 
6892         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)6893         void copyRawObjects(RawStore rawStore, EntityStore newStore)
6894             throws DatabaseException {
6895 
6896             PrimaryIndex<Integer, RenameSecFieldDestroyOrder_1>
6897                 index = newStore.getPrimaryIndex
6898                     (Integer.class, RenameSecFieldDestroyOrder_1.class);
6899             RawObject raw = rawStore.getPrimaryIndex(NAME).get(1);
6900             index.put((RenameSecFieldDestroyOrder_1)
6901                       newStore.getModel().convertRawObject(raw));
6902         }
6903 
checkSecondaries(EntityStore store, PrimaryIndex<Integer, RenameSecFieldDestroyOrder_1> index)6904         private void checkSecondaries(EntityStore store,
6905                 PrimaryIndex<Integer,
6906                              RenameSecFieldDestroyOrder_1>
6907                              index)
6908             throws DatabaseException {
6909 
6910             if (!newMetadataWritten) {
6911                 return;
6912             }
6913             checkValues(store.getSecondaryIndex
6914                 (index, String.class, "secKey").get("aa"));
6915             checkValues(store.getSecondaryIndex
6916                 (index, Integer.class, "new_secKey2").get(2));
6917             checkValues(store.getSecondaryIndex
6918                 (index, String.class, "secKey3").get("bb"));
6919         }
6920 
checkValues(RenameSecFieldDestroyOrder_1 obj)6921         private void checkValues(RenameSecFieldDestroyOrder_1 obj) {
6922             TestCase.assertNotNull(obj);
6923             TestCase.assertEquals(obj.key, 1);
6924             TestCase.assertEquals(obj.secKey, "aa");
6925             TestCase.assertEquals(obj.new_secKey2, 2);
6926             TestCase.assertEquals(obj.secKey3, "bb");
6927         }
6928 
6929         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)6930         void readRawObjects(RawStore store,
6931                             boolean expectEvolved,
6932                             boolean expectUpdated)
6933             throws DatabaseException {
6934 
6935             RawObject obj;
6936             if (expectEvolved) {
6937                 obj = readRaw(store, 1, NAME, 1, CASECLS, 0);
6938                 checkRawFields(obj, "key", 1,
6939                                "secKey", "aa",
6940                                "new_secKey2", 2,
6941                                "secKey3", "bb");
6942             } else {
6943                 obj = readRaw(store, 1, NAME, 0, CASECLS, 0);
6944                 checkRawFields(obj, "key", 1,
6945                                "secKey", "aa",
6946                                "secKey2", 2,
6947                                "secKey3", "bb");
6948             }
6949             Environment env = store.getEnvironment();
6950 
6951             assertDbExists(expectEvolved, env, NAME, "new_secKey2");
6952             assertDbExists(!expectEvolved, env, NAME, "secKey2");
6953         }
6954     }
6955 
6956     /*
6957      * [18961]Rename secKey2 and secKey3, so the order of secondary keys' names
6958      * is changed from : secKey->seckey2->secKey3 to new_seckey2->new_secKey3->
6959      * secKey1.
6960      */
6961     @Entity(version=1)
6962     static class RenameSecFieldDestroyOrder_2 extends EvolveCase{
6963 
6964         private static final String NAME =
6965             RenameSecFieldDestroyOrder_2.class.getName();
6966 
6967         @PrimaryKey
6968         int key;
6969 
6970         @SecondaryKey(relate=MANY_TO_ONE)
6971         String secKey;
6972 
6973         /* Rename secKey2 to new_secKey2. */
6974         @SecondaryKey(relate=MANY_TO_ONE)
6975         int new_secKey2;
6976 
6977         /* Rename secKey3 to new_secKey3. */
6978         @SecondaryKey(relate=MANY_TO_ONE)
6979         String new_secKey3;
6980 
6981         @Override
getMutations()6982         Mutations getMutations() {
6983             Mutations m = new Mutations();
6984             m.addRenamer(new Renamer(NAME, 0, "secKey2", "new_secKey2"));
6985             m.addRenamer(new Renamer(NAME, 0, "secKey3", "new_secKey3"));
6986             return m;
6987         }
6988 
6989         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)6990         void checkEvolvedModel(EntityModel model,
6991                                Environment env,
6992                                boolean oldTypesExist) {
6993             checkEntity(true, model, env, NAME, 1, null);
6994             if (oldTypesExist) {
6995                 checkVersions(model, NAME, 1, NAME, 0);
6996             } else {
6997                 checkVersions(model, NAME, 1);
6998             }
6999         }
7000 
7001         @Override
readObjects(EntityStore store, boolean doUpdate)7002         void readObjects(EntityStore store, boolean doUpdate)
7003             throws DatabaseException {
7004 
7005             PrimaryIndex<Integer, RenameSecFieldDestroyOrder_2>
7006                 index = store.getPrimaryIndex
7007                     (Integer.class, RenameSecFieldDestroyOrder_2.class);
7008             RenameSecFieldDestroyOrder_2 obj = index.get(1);
7009             checkValues(obj);
7010             checkSecondaries(store, index);
7011 
7012             if (doUpdate) {
7013                 index.put(obj);
7014                 checkSecondaries(store, index);
7015             }
7016         }
7017 
7018         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)7019         void copyRawObjects(RawStore rawStore, EntityStore newStore)
7020             throws DatabaseException {
7021 
7022             PrimaryIndex<Integer, RenameSecFieldDestroyOrder_2>
7023                 index = newStore.getPrimaryIndex
7024                     (Integer.class, RenameSecFieldDestroyOrder_2.class);
7025             RawObject raw = rawStore.getPrimaryIndex(NAME).get(1);
7026             index.put((RenameSecFieldDestroyOrder_2)
7027                       newStore.getModel().convertRawObject(raw));
7028         }
7029 
checkSecondaries(EntityStore store, PrimaryIndex<Integer, RenameSecFieldDestroyOrder_2> index)7030         private void checkSecondaries(EntityStore store,
7031                 PrimaryIndex<Integer,
7032                              RenameSecFieldDestroyOrder_2>
7033                              index)
7034             throws DatabaseException {
7035 
7036             if (!newMetadataWritten) {
7037                 return;
7038             }
7039             checkValues(store.getSecondaryIndex
7040                 (index, String.class, "secKey").get("aa"));
7041             checkValues(store.getSecondaryIndex
7042                 (index, Integer.class, "new_secKey2").get(2));
7043             checkValues(store.getSecondaryIndex
7044                 (index, String.class, "new_secKey3").get("bb"));
7045         }
7046 
checkValues(RenameSecFieldDestroyOrder_2 obj)7047         private void checkValues(RenameSecFieldDestroyOrder_2 obj) {
7048             TestCase.assertNotNull(obj);
7049             TestCase.assertEquals(obj.key, 1);
7050             TestCase.assertEquals(obj.secKey, "aa");
7051             TestCase.assertEquals(obj.new_secKey2, 2);
7052             TestCase.assertEquals(obj.new_secKey3, "bb");
7053         }
7054 
7055         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)7056         void readRawObjects(RawStore store,
7057                             boolean expectEvolved,
7058                             boolean expectUpdated)
7059             throws DatabaseException {
7060 
7061             RawObject obj;
7062             if (expectEvolved) {
7063                 obj = readRaw(store, 1, NAME, 1, CASECLS, 0);
7064                 checkRawFields(obj, "key", 1,
7065                                "secKey", "aa",
7066                                "new_secKey2", 2,
7067                                "new_secKey3", "bb");
7068             } else {
7069                 obj = readRaw(store, 1, NAME, 0, CASECLS, 0);
7070                 checkRawFields(obj, "key", 1,
7071                                "secKey", "aa",
7072                                "secKey2", 2,
7073                                "secKey3", "bb");
7074             }
7075             Environment env = store.getEnvironment();
7076 
7077             assertDbExists(expectEvolved, env, NAME, "new_secKey2");
7078             assertDbExists(!expectEvolved, env, NAME, "secKey2");
7079             assertDbExists(expectEvolved, env, NAME, "new_secKey3");
7080             assertDbExists(!expectEvolved, env, NAME, "secKey3");
7081         }
7082     }
7083 
7084     /*
7085      * [18961]Rename secKey2 and secKey3, so the order of secondary keys' names
7086      * is changed from : secKey->seckey2->secKey3 to new_seckey3->pnew_secKey2
7087      * ->secKey1.
7088      */
7089     @Entity(version=1)
7090     static class RenameSecFieldDestroyOrder_3 extends EvolveCase{
7091 
7092         private static final String NAME =
7093             RenameSecFieldDestroyOrder_3.class.getName();
7094 
7095         @PrimaryKey
7096         int key;
7097 
7098         @SecondaryKey(relate=MANY_TO_ONE)
7099         String secKey;
7100 
7101         /* Rename secKey2 to pnew_secKey2. */
7102         @SecondaryKey(relate=MANY_TO_ONE)
7103         int pnew_secKey2;
7104 
7105         /* Rename secKey3 to new_secKey3. */
7106         @SecondaryKey(relate=MANY_TO_ONE)
7107         String new_secKey3;
7108 
7109         @Override
getMutations()7110         Mutations getMutations() {
7111             Mutations m = new Mutations();
7112             m.addRenamer(new Renamer(NAME, 0, "secKey2", "pnew_secKey2"));
7113             m.addRenamer(new Renamer(NAME, 0, "secKey3", "new_secKey3"));
7114             return m;
7115         }
7116 
7117         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)7118         void checkEvolvedModel(EntityModel model,
7119                                Environment env,
7120                                boolean oldTypesExist) {
7121             checkEntity(true, model, env, NAME, 1, null);
7122             if (oldTypesExist) {
7123                 checkVersions(model, NAME, 1, NAME, 0);
7124             } else {
7125                 checkVersions(model, NAME, 1);
7126             }
7127         }
7128 
7129         @Override
readObjects(EntityStore store, boolean doUpdate)7130         void readObjects(EntityStore store, boolean doUpdate)
7131             throws DatabaseException {
7132 
7133             PrimaryIndex<Integer, RenameSecFieldDestroyOrder_3>
7134                 index = store.getPrimaryIndex
7135                     (Integer.class, RenameSecFieldDestroyOrder_3.class);
7136             RenameSecFieldDestroyOrder_3 obj = index.get(1);
7137             checkValues(obj);
7138             checkSecondaries(store, index);
7139 
7140             if (doUpdate) {
7141                 index.put(obj);
7142                 checkSecondaries(store, index);
7143             }
7144         }
7145 
7146         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)7147         void copyRawObjects(RawStore rawStore, EntityStore newStore)
7148             throws DatabaseException {
7149 
7150             PrimaryIndex<Integer, RenameSecFieldDestroyOrder_3>
7151                 index = newStore.getPrimaryIndex
7152                     (Integer.class,
7153                             RenameSecFieldDestroyOrder_3.class);
7154             RawObject raw = rawStore.getPrimaryIndex(NAME).get(1);
7155             index.put((RenameSecFieldDestroyOrder_3)
7156                       newStore.getModel().convertRawObject(raw));
7157         }
7158 
checkSecondaries(EntityStore store, PrimaryIndex<Integer, RenameSecFieldDestroyOrder_3> index)7159         private void checkSecondaries(EntityStore store,
7160                 PrimaryIndex<Integer,
7161                              RenameSecFieldDestroyOrder_3>
7162                              index)
7163             throws DatabaseException {
7164 
7165             if (!newMetadataWritten) {
7166                 return;
7167             }
7168             checkValues(store.getSecondaryIndex
7169                 (index, String.class, "secKey").get("aa"));
7170             checkValues(store.getSecondaryIndex
7171                 (index, Integer.class, "pnew_secKey2").get(2));
7172             checkValues(store.getSecondaryIndex
7173                 (index, String.class, "new_secKey3").get("bb"));
7174         }
7175 
checkValues(RenameSecFieldDestroyOrder_3 obj)7176         private void checkValues(RenameSecFieldDestroyOrder_3 obj) {
7177             TestCase.assertNotNull(obj);
7178             TestCase.assertEquals(obj.key, 1);
7179             TestCase.assertEquals(obj.secKey, "aa");
7180             TestCase.assertEquals(obj.pnew_secKey2, 2);
7181             TestCase.assertEquals(obj.new_secKey3, "bb");
7182         }
7183 
7184         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)7185         void readRawObjects(RawStore store,
7186                             boolean expectEvolved,
7187                             boolean expectUpdated)
7188             throws DatabaseException {
7189 
7190             RawObject obj;
7191             if (expectEvolved) {
7192                 obj = readRaw(store, 1, NAME, 1, CASECLS, 0);
7193                 checkRawFields(obj, "key", 1,
7194                                "secKey", "aa",
7195                                "pnew_secKey2", 2,
7196                                "new_secKey3", "bb");
7197             } else {
7198                 obj = readRaw(store, 1, NAME, 0, CASECLS, 0);
7199                 checkRawFields(obj, "key", 1,
7200                                "secKey", "aa",
7201                                "secKey2", 2,
7202                                "secKey3", "bb");
7203             }
7204             Environment env = store.getEnvironment();
7205 
7206             assertDbExists(expectEvolved, env, NAME, "pnew_secKey2");
7207             assertDbExists(!expectEvolved, env, NAME, "secKey2");
7208             assertDbExists(expectEvolved, env, NAME, "new_secKey3");
7209             assertDbExists(!expectEvolved, env, NAME, "secKey3");
7210         }
7211     }
7212 
7213     /*
7214      * [#18961]Delete secKey2's SecondaryKey annotation. so the order of non
7215      * keys' names is changed from : anonKey->znonkey to anonKey->secKey2->
7216      * xnonKey.
7217      */
7218     @Entity(version=1)
7219     static class DeleteSecAnnotationDestroyOrder extends EvolveCase{
7220 
7221         private static final String NAME =
7222             DeleteSecAnnotationDestroyOrder.class.getName();
7223 
7224         @PrimaryKey
7225         int key;
7226 
7227         @SecondaryKey(relate=MANY_TO_ONE)
7228         String secKey;
7229 
7230         /* Delete secKey2's SecondaryKey annotation. */
7231         //@SecondaryKey(relate=MANY_TO_ONE)
7232         int secKey2;
7233 
7234         @SecondaryKey(relate=MANY_TO_ONE)
7235         String secKey3;
7236 
7237         int znonKey;
7238         String xnonKey = "cc";
7239 
7240         @Override
getMutations()7241         Mutations getMutations() {
7242             Mutations m = new Mutations();
7243             m.addRenamer(new Renamer(NAME, 0, "anonKey", "znonKey"));
7244             return m;
7245         }
7246 
7247         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)7248         void checkEvolvedModel(EntityModel model,
7249                                Environment env,
7250                                boolean oldTypesExist) {
7251             checkEntity(true, model, env, NAME, 1, null);
7252             if (oldTypesExist) {
7253                 checkVersions(model, NAME, 1, NAME, 0);
7254             } else {
7255                 checkVersions(model, NAME, 1);
7256             }
7257         }
7258 
7259         @Override
readObjects(EntityStore store, boolean doUpdate)7260         void readObjects(EntityStore store, boolean doUpdate)
7261             throws DatabaseException {
7262 
7263             PrimaryIndex<Integer, DeleteSecAnnotationDestroyOrder>
7264                 index = store.getPrimaryIndex
7265                     (Integer.class, DeleteSecAnnotationDestroyOrder.class);
7266             DeleteSecAnnotationDestroyOrder obj = index.get(1);
7267             checkValues(obj);
7268             checkSecondaries(store, index);
7269 
7270             if (doUpdate) {
7271                 index.put(obj);
7272                 checkSecondaries(store, index);
7273             }
7274         }
7275 
7276         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)7277         void copyRawObjects(RawStore rawStore, EntityStore newStore)
7278             throws DatabaseException {
7279 
7280             PrimaryIndex<Integer, DeleteSecAnnotationDestroyOrder>
7281                 index = newStore.getPrimaryIndex
7282                     (Integer.class,
7283                      DeleteSecAnnotationDestroyOrder.class);
7284             RawObject raw = rawStore.getPrimaryIndex(NAME).get(1);
7285             index.put((DeleteSecAnnotationDestroyOrder)
7286                       newStore.getModel().convertRawObject(raw));
7287         }
7288 
checkSecondaries(EntityStore store, PrimaryIndex<Integer, DeleteSecAnnotationDestroyOrder> index)7289         private void checkSecondaries(EntityStore store,
7290                 PrimaryIndex<Integer,
7291                              DeleteSecAnnotationDestroyOrder>
7292                              index)
7293             throws DatabaseException {
7294 
7295             if (!newMetadataWritten) {
7296                 return;
7297             }
7298             checkValues(store.getSecondaryIndex
7299                 (index, String.class, "secKey").get("aa"));
7300             checkValues(store.getSecondaryIndex
7301                 (index, String.class, "secKey3").get("bb"));
7302         }
7303 
checkValues(DeleteSecAnnotationDestroyOrder obj)7304         private void checkValues(DeleteSecAnnotationDestroyOrder obj) {
7305             TestCase.assertNotNull(obj);
7306             TestCase.assertEquals(obj.key, 1);
7307             TestCase.assertEquals(obj.secKey, "aa");
7308             TestCase.assertEquals(obj.secKey2, 2);
7309             TestCase.assertEquals(obj.secKey3, "bb");
7310             TestCase.assertEquals(obj.znonKey, 3);
7311             TestCase.assertEquals(obj.xnonKey, "cc");
7312         }
7313 
7314         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)7315         void readRawObjects(RawStore store,
7316                             boolean expectEvolved,
7317                             boolean expectUpdated)
7318             throws DatabaseException {
7319 
7320             RawObject obj;
7321             if (expectEvolved) {
7322                 obj = readRaw(store, 1, NAME, 1, CASECLS, 0);
7323                 checkRawFields(obj, "key", 1,
7324                                "secKey", "aa",
7325                                "secKey2", 2,
7326                                "secKey3", "bb",
7327                                "znonKey", 3,
7328                                "xnonKey", "cc");
7329             } else {
7330                 obj = readRaw(store, 1, NAME, 0, CASECLS, 0);
7331                 checkRawFields(obj, "key", 1,
7332                                "secKey", "aa",
7333                                "secKey2", 2,
7334                                "secKey3", "bb",
7335                                "anonKey", 3,
7336                                "xnonKey", "cc");
7337             }
7338             Environment env = store.getEnvironment();
7339 
7340             assertDbExists(!expectEvolved, env, NAME, "secKey2");
7341         }
7342     }
7343 
7344     /*
7345      *  [#19377]Change one field of the proxy class from Map<String, String> to
7346      *  Map<MyEnum, String>.
7347      */
7348     @Entity
7349     static class ProxyClassFieldChanged extends EvolveCase {
7350         private static final String NAME =
7351             ProxyClassFieldChanged.class.getName();
7352         private static final String NAME2 =
7353             ProxiedClass_Proxy2.class.getName();
7354 
7355         @PrimaryKey
7356         int key;
7357 
7358         private ProxiedClass embed;
7359 
7360         @Override
configure(EntityModel model, StoreConfig config)7361         void configure(EntityModel model, StoreConfig config) {
7362             model.registerClass(ProxiedClass_Proxy2.class);
7363         }
7364 
7365         @Override
getMutations()7366         Mutations getMutations() {
7367             Mutations m = new Mutations();
7368             Converter converter =
7369                 new Converter(ProxiedClass_Proxy2.class.getName(), 0, "data",
7370                               new MyConversion());
7371             m.addConverter(converter);
7372             return m;
7373         }
7374 
7375         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)7376         void checkEvolvedModel(EntityModel model,
7377                                Environment env,
7378                                boolean oldTypesExist) {
7379             checkEntity(true, model, env, NAME, 0, null);
7380             checkVersions(model, NAME, 0);
7381             if (oldTypesExist) {
7382                 checkVersions(model, NAME2, 1, NAME2, 0);
7383             } else {
7384                 checkVersions(model, NAME2, 1);
7385             }
7386         }
7387 
7388         @Override
readObjects(EntityStore store, boolean doUpdate)7389         void readObjects(EntityStore store, boolean doUpdate)
7390             throws DatabaseException {
7391 
7392             PrimaryIndex<Integer, ProxyClassFieldChanged>
7393                 index = store.getPrimaryIndex
7394                     (Integer.class, ProxyClassFieldChanged.class);
7395             ProxyClassFieldChanged obj = index.get(1);
7396             TestCase.assertNotNull(obj);
7397             TestCase.assertEquals(1, obj.key);
7398             TestCase.assertNotNull(obj.embed);
7399             TestCase.assertEquals(2, obj.embed.data);
7400             if (doUpdate) {
7401                 index.put(obj);
7402             }
7403         }
7404 
7405         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)7406         void copyRawObjects(RawStore rawStore, EntityStore newStore)
7407             throws DatabaseException {
7408 
7409             PrimaryIndex<Integer, ProxyClassFieldChanged>
7410                 index = newStore.getPrimaryIndex
7411                     (Integer.class, ProxyClassFieldChanged.class);
7412             RawObject raw = rawStore.getPrimaryIndex(NAME).get(1);
7413             index.put((ProxyClassFieldChanged)
7414                       newStore.getModel().convertRawObject(raw));
7415         }
7416 
7417         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)7418         void readRawObjects(RawStore store,
7419                             boolean expectEvolved,
7420                             boolean expectUpdated)
7421             throws DatabaseException {
7422 
7423             RawType embedType = store.getModel().getRawType(NAME2);
7424             RawObject data = makeRawObject(store, expectEvolved);
7425             RawObject embed = new RawObject
7426                 (embedType, makeValues("data", data), null);
7427             RawObject obj = readRaw(store, 1, NAME, 0, CASECLS, 0);
7428             checkRawFields(obj, "key", 1, "embed", embed);
7429         }
7430 
makeRawObject(RawStore store, boolean expectEvolved)7431         static RawObject makeRawObject(RawStore store,
7432                                         boolean expectEvolved) {
7433             RawType dataType = store.getModel().getRawType
7434                 ("com.sleepycat.persist.impl.MapProxy$HashMapProxy");
7435             RawType dataSuperType = store.getModel().getRawType
7436                 ("com.sleepycat.persist.impl.MapProxy");
7437             RawType listRawType =
7438                 store.getModel().getRawType(Object[].class.getName());
7439             RawType myEnumType =
7440                 store.getModel().getRawType(MyEnum.class.getName());
7441             RawObject keyRawObject = null;
7442             if (expectEvolved) {
7443                 ArrayList<RawObject> dataKeyValue =
7444                     new ArrayList<RawObject>();
7445                 RawObject myEnumRawObject = new RawObject(myEnumType, "DATA");
7446                 dataKeyValue.add(myEnumRawObject);
7447                 keyRawObject = new RawObject
7448                     (listRawType, dataKeyValue.toArray());
7449             } else {
7450                 ArrayList<String> dataKeyValue = new ArrayList<String>();
7451                 dataKeyValue.add("data");
7452                 keyRawObject = new RawObject
7453                     (listRawType, dataKeyValue.toArray());
7454             }
7455 
7456             ArrayList<Integer> dataValueValue = new ArrayList<Integer>();
7457             dataValueValue.add(2);
7458 
7459             RawObject valueRawObject = new RawObject
7460                 (listRawType, dataValueValue.toArray());
7461 
7462             Map<String, Object>
7463                 dataSuperValue = new HashMap<String, Object>();
7464             dataSuperValue.put("keys", keyRawObject);
7465             dataSuperValue.put("values", valueRawObject);
7466             RawObject dataSuperRawObject =
7467                 new RawObject(dataSuperType, dataSuperValue, null);
7468             Map<String, Object> dataValue =
7469                 new HashMap<String, Object>();
7470             RawObject dataRawObject = new RawObject(dataType,
7471                     dataValue, dataSuperRawObject);
7472             return dataRawObject;
7473         }
7474 
7475         static class MyConversion implements Conversion {
7476             private static final long serialVersionUID = 1L;
7477             private transient RawType newDataType;
7478             private transient RawType newDataSuperType;
7479             private transient RawType myEnumType;
7480 
initialize(EntityModel model)7481             public void initialize(EntityModel model) {
7482                 newDataType = model.getRawType
7483                     ("com.sleepycat.persist.impl.MapProxy$HashMapProxy");
7484                 newDataSuperType =
7485                     model.getRawType("com.sleepycat.persist.impl.MapProxy");
7486                 myEnumType = model.getRawType(MyEnum.class.getName());
7487             }
7488 
convert(Object fromValue)7489             public Object convert(Object fromValue) {
7490 
7491                 // Get field value maps for old and new objects.
7492                 RawObject oldDataRawObject = (RawObject) fromValue;
7493                 RawObject oldKeyRawObject = (RawObject)oldDataRawObject.
7494                     getSuper().getValues().get("keys");
7495                 Object[] oldDataKeyValue =
7496                     (Object[])oldKeyRawObject.getElements();
7497                 RawObject oldValueRawObject = (RawObject)oldDataRawObject.
7498                     getSuper().getValues().get("values");
7499 
7500                 ArrayList<RawObject> newDataKeyValue =
7501                     new ArrayList<RawObject>();
7502                 RawObject myEnumRawObject = new RawObject(myEnumType, "DATA");
7503                 newDataKeyValue.add(myEnumRawObject);
7504 
7505                 RawObject newKeyRawObject = new RawObject
7506                     (oldKeyRawObject.getType(), newDataKeyValue.toArray());
7507                 Map<String, Object>
7508                     newDataSuperValue = new HashMap<String, Object>();
7509                 newDataSuperValue.put("keys", newKeyRawObject);
7510                 newDataSuperValue.put("values", oldValueRawObject);
7511                 RawObject newDataSuperRawObject =
7512                     new RawObject(newDataSuperType, newDataSuperValue, null);
7513                 Map<String, Object> newDataValue =
7514                     new HashMap<String, Object>();
7515                 RawObject newDataRawObject =
7516                     new RawObject(newDataType, newDataValue,
7517                                   newDataSuperRawObject);
7518                 return newDataRawObject;
7519             }
7520 
7521             @Override
equals(Object o)7522             public boolean equals(Object o) {
7523                 return o instanceof MyConversion;
7524             }
7525         }
7526     }
7527 
7528     @Persistent(proxyFor=ProxiedClass.class, version=1)
7529     static class ProxiedClass_Proxy2 implements PersistentProxy<ProxiedClass> {
7530         Map<MyEnum, Integer> data;
7531 
initializeProxy(ProxiedClass o)7532         public void initializeProxy(ProxiedClass o) {
7533             data = new HashMap<MyEnum, Integer>();
7534             data.put(MyEnum.DATA, o.data);
7535         }
7536 
convertProxy()7537         public ProxiedClass convertProxy() {
7538             return new ProxiedClass(data.get(MyEnum.DATA));
7539         }
7540     }
7541 
7542     enum MyEnum { DATA };
7543 
7544     /*
7545      *  [#19377]Change one field of the proxy class from Map<String, String> to
7546      *  Map<Object, String>, and the Object component then will be assigned a
7547      *  MyEnum object, which is not known for DPL when open a store.
7548      */
7549     @Entity
7550     static class ProxyClassObjectFieldChanged extends EvolveCase {
7551         private static final String NAME =
7552             ProxyClassObjectFieldChanged.class.getName();
7553         private static final String NAME2 =
7554             ProxiedClass_Proxy3.class.getName();
7555 
7556         @PrimaryKey
7557         int key;
7558 
7559         private ProxiedClass embed;
7560 
7561         @Override
configure(EntityModel model, StoreConfig config)7562         void configure(EntityModel model, StoreConfig config) {
7563             model.registerClass(ProxiedClass_Proxy3.class);
7564 
7565             /*
7566              * Because the DPL does not know MyEnum class, we have to register
7567              * it in advance of using it.
7568              */
7569             model.registerClass(MyEnum.class);
7570         }
7571 
7572         @Override
getMutations()7573         Mutations getMutations() {
7574             Mutations m = new Mutations();
7575             Converter converter =
7576                 new Converter(ProxiedClass_Proxy3.class.getName(), 0, "data",
7577                               new ProxyClassFieldChanged.MyConversion());
7578             m.addConverter(converter);
7579             return m;
7580         }
7581 
7582         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)7583         void checkEvolvedModel(EntityModel model,
7584                                Environment env,
7585                                boolean oldTypesExist) {
7586             checkEntity(true, model, env, NAME, 0, null);
7587             checkVersions(model, NAME, 0);
7588             if (oldTypesExist) {
7589                 checkVersions(model, NAME2, 1, NAME2, 0);
7590             } else {
7591                 checkVersions(model, NAME2, 1);
7592             }
7593         }
7594 
7595         @Override
readObjects(EntityStore store, boolean doUpdate)7596         void readObjects(EntityStore store, boolean doUpdate)
7597             throws DatabaseException {
7598 
7599             PrimaryIndex<Integer, ProxyClassObjectFieldChanged>
7600                 index = store.getPrimaryIndex
7601                     (Integer.class, ProxyClassObjectFieldChanged.class);
7602             ProxyClassObjectFieldChanged obj = index.get(1);
7603             TestCase.assertNotNull(obj);
7604             TestCase.assertEquals(1, obj.key);
7605             TestCase.assertNotNull(obj.embed);
7606             TestCase.assertEquals(2, obj.embed.data);
7607             if (doUpdate) {
7608                 index.put(obj);
7609             }
7610         }
7611 
7612         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)7613         void copyRawObjects(RawStore rawStore, EntityStore newStore)
7614             throws DatabaseException {
7615 
7616             PrimaryIndex<Integer, ProxyClassObjectFieldChanged>
7617                 index = newStore.getPrimaryIndex
7618                     (Integer.class, ProxyClassObjectFieldChanged.class);
7619             RawObject raw = rawStore.getPrimaryIndex(NAME).get(1);
7620             index.put((ProxyClassObjectFieldChanged)
7621                       newStore.getModel().convertRawObject(raw));
7622         }
7623 
7624         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)7625         void readRawObjects(RawStore store,
7626                             boolean expectEvolved,
7627                             boolean expectUpdated)
7628             throws DatabaseException {
7629 
7630             RawType embedType = store.getModel().getRawType(NAME2);
7631             RawObject data =
7632                 ProxyClassFieldChanged.makeRawObject(store, expectEvolved);
7633             RawObject embed =
7634                 new RawObject(embedType, makeValues("data", data), null);
7635             RawObject obj = readRaw(store, 1, NAME, 0, CASECLS, 0);
7636             checkRawFields(obj, "key", 1, "embed", embed);
7637 
7638         }
7639     }
7640 
7641     @Persistent(proxyFor=ProxiedClass.class, version=1)
7642     static class ProxiedClass_Proxy3 implements PersistentProxy<ProxiedClass> {
7643         /* Changed from Map<String, String> to Map<Object, String>. */
7644         Map<Object, Integer> data;
7645 
initializeProxy(ProxiedClass o)7646         public void initializeProxy(ProxiedClass o) {
7647             data = new HashMap<Object, Integer>();
7648             data.put(MyEnum.DATA, o.data);
7649         }
7650 
convertProxy()7651         public ProxiedClass convertProxy() {
7652             return new ProxiedClass(data.get(MyEnum.DATA));
7653         }
7654     }
7655 
7656     /*
7657      *  [#19377]Change one field of the proxy class from Integer[] to
7658      *  IntegerClass[].
7659      */
7660     @Entity
7661     static class ProxyClassArrayFieldChanged extends EvolveCase {
7662         private static final String NAME =
7663             ProxyClassArrayFieldChanged.class.getName();
7664         private static final String NAME2 =
7665             ProxiedClass_Proxy4.class.getName();
7666 
7667         @PrimaryKey
7668         int key;
7669 
7670         private ProxiedClass embed;
7671 
7672         @Override
configure(EntityModel model, StoreConfig config)7673         void configure(EntityModel model, StoreConfig config) {
7674             model.registerClass(ProxiedClass_Proxy4.class);
7675         }
7676 
7677         @Override
getMutations()7678         Mutations getMutations() {
7679             Mutations m = new Mutations();
7680             Converter converter =
7681                 new Converter(ProxiedClass_Proxy4.class.getName(), 0, "data",
7682                               new MyConversion());
7683             m.addConverter(converter);
7684             return m;
7685         }
7686 
7687         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)7688         void checkEvolvedModel(EntityModel model,
7689                                Environment env,
7690                                boolean oldTypesExist) {
7691             checkEntity(true, model, env, NAME, 0, null);
7692             checkVersions(model, NAME, 0);
7693             if (oldTypesExist) {
7694                 checkVersions(model, NAME2, 1, NAME2, 0);
7695             } else {
7696                 checkVersions(model, NAME2, 1);
7697             }
7698         }
7699 
7700         @Override
readObjects(EntityStore store, boolean doUpdate)7701         void readObjects(EntityStore store, boolean doUpdate)
7702             throws DatabaseException {
7703 
7704             PrimaryIndex<Integer, ProxyClassArrayFieldChanged>
7705                 index = store.getPrimaryIndex
7706                     (Integer.class, ProxyClassArrayFieldChanged.class);
7707             ProxyClassArrayFieldChanged obj = index.get(1);
7708             TestCase.assertNotNull(obj);
7709             TestCase.assertEquals(1, obj.key);
7710             TestCase.assertNotNull(obj.embed);
7711             TestCase.assertEquals(2, obj.embed.data);
7712             if (doUpdate) {
7713                 index.put(obj);
7714             }
7715         }
7716 
7717         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)7718         void copyRawObjects(RawStore rawStore, EntityStore newStore)
7719             throws DatabaseException {
7720 
7721             PrimaryIndex<Integer, ProxyClassArrayFieldChanged>
7722                 index = newStore.getPrimaryIndex
7723                     (Integer.class, ProxyClassArrayFieldChanged.class);
7724             RawObject raw = rawStore.getPrimaryIndex(NAME).get(1);
7725             index.put((ProxyClassArrayFieldChanged)
7726                       newStore.getModel().convertRawObject(raw));
7727         }
7728 
7729         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)7730         void readRawObjects(RawStore store,
7731                             boolean expectEvolved,
7732                             boolean expectUpdated)
7733             throws DatabaseException {
7734 
7735             RawType embedType = store.getModel().getRawType(NAME2);
7736             RawObject data = makeRawObject(store, expectEvolved);
7737             RawObject embed = new RawObject
7738                 (embedType, makeValues("data", data), null);
7739             RawObject obj = readRaw(store, 1, NAME, 0, CASECLS, 0);
7740             checkRawFields(obj, "key", 1, "embed", embed);
7741 
7742         }
7743 
makeRawObject(RawStore store, boolean expectEvolved)7744         static RawObject makeRawObject(RawStore store,
7745                                        boolean expectEvolved) {
7746             RawType integerClassType =
7747                 store.getModel().getRawType(IntegerClass.class.getName());
7748             RawObject dataRawObject = null;
7749             if (expectEvolved) {
7750                 RawType dataType = store.getModel().getRawType
7751                                        (IntegerClass[].class.getName());
7752                 Map<String, Object> integerClassValues =
7753                     new HashMap<String, Object>();
7754                 integerClassValues.put("data", 2);
7755                 RawObject integerClassObject =
7756                     new RawObject(integerClassType, integerClassValues, null);
7757                 RawObject[] elements = new RawObject[1];
7758                 elements[0] = integerClassObject;
7759                 dataRawObject = new RawObject(dataType, elements);
7760             } else {
7761                 RawType dataType =
7762                     store.getModel().getRawType(Integer[].class.getName());
7763                 Integer[] elements = new Integer[1];
7764                 elements[0] = 2;
7765                 dataRawObject = new RawObject(dataType, elements);
7766             }
7767             return dataRawObject;
7768         }
7769 
7770         static class MyConversion implements Conversion {
7771             private static final long serialVersionUID = 1L;
7772             private transient RawType newDataType;
7773             private transient RawType integerClassType;
7774 
initialize(EntityModel model)7775             public void initialize(EntityModel model) {
7776                 newDataType = model.getRawType(IntegerClass[].class.getName());
7777                 integerClassType =
7778                     model.getRawType(IntegerClass.class.getName());
7779             }
7780 
convert(Object fromValue)7781             public Object convert(Object fromValue) {
7782 
7783                 // Get field value maps for old and new objects.
7784                 RawObject oldDataRawObject = (RawObject) fromValue;
7785                 Object[] oldElements = oldDataRawObject.getElements();
7786                 Map<String, Object> integerClassValues =
7787                     new HashMap<String, Object>();
7788                 integerClassValues.put("data", oldElements[0]);
7789                 RawObject integerClassObject =
7790                     new RawObject(integerClassType, integerClassValues, null);
7791                 RawObject[] newElements = new RawObject[1];
7792                 newElements[0] = integerClassObject;
7793                 RawObject newDataRawObject =
7794                     new RawObject(newDataType, newElements);
7795                 return newDataRawObject;
7796             }
7797 
7798             @Override
equals(Object o)7799             public boolean equals(Object o) {
7800                 return o instanceof MyConversion;
7801             }
7802         }
7803     }
7804 
7805     @Persistent(proxyFor=ProxiedClass.class, version=1)
7806     static class ProxiedClass_Proxy4 implements PersistentProxy<ProxiedClass> {
7807         IntegerClass[] data;
7808 
initializeProxy(ProxiedClass o)7809         public void initializeProxy(ProxiedClass o) {
7810             data = new IntegerClass[1];
7811             data[0] = new IntegerClass(o.data);
7812         }
7813 
convertProxy()7814         public ProxiedClass convertProxy() {
7815             return new ProxiedClass(data[0].data);
7816         }
7817     }
7818 
7819     @Persistent
7820     static class IntegerClass {
7821         int data;
7822 
IntegerClass()7823         IntegerClass(){}
7824 
IntegerClass(int data)7825         IntegerClass(int data) {
7826             this.data = data;
7827         }
7828     }
7829 
7830     /*
7831      *  [#19377]Change one field of the proxy class from Integer[] to Object[],
7832      *  and the Object component then will be assigned a IntegerClass object,
7833      *  which is not known for DPL when open a store.
7834      */
7835     @Entity
7836     static class ProxyClassObjectArrayFieldChanged extends EvolveCase {
7837         private static final String NAME =
7838             ProxyClassObjectArrayFieldChanged.class.getName();
7839         private static final String NAME2 =
7840             ProxiedClass_Proxy5.class.getName();
7841 
7842         @PrimaryKey
7843         int key;
7844 
7845         private ProxiedClass embed;
7846 
7847         @Override
configure(EntityModel model, StoreConfig config)7848         void configure(EntityModel model, StoreConfig config) {
7849             model.registerClass(ProxiedClass_Proxy5.class);
7850             model.registerClass(IntegerClass[].class);
7851         }
7852 
7853         @Override
getMutations()7854         Mutations getMutations() {
7855             Mutations m = new Mutations();
7856             Converter converter =
7857                 new Converter(ProxiedClass_Proxy5.class.getName(), 0, "data",
7858                               new ProxyClassArrayFieldChanged.MyConversion());
7859             m.addConverter(converter);
7860             return m;
7861         }
7862 
7863         @Override
checkEvolvedModel(EntityModel model, Environment env, boolean oldTypesExist)7864         void checkEvolvedModel(EntityModel model,
7865                                Environment env,
7866                                boolean oldTypesExist) {
7867             checkEntity(true, model, env, NAME, 0, null);
7868             checkVersions(model, NAME, 0);
7869             if (oldTypesExist) {
7870                 checkVersions(model, NAME2, 1, NAME2, 0);
7871             } else {
7872                 checkVersions(model, NAME2, 1);
7873             }
7874         }
7875 
7876         @Override
readObjects(EntityStore store, boolean doUpdate)7877         void readObjects(EntityStore store, boolean doUpdate)
7878             throws DatabaseException {
7879 
7880             PrimaryIndex<Integer, ProxyClassObjectArrayFieldChanged>
7881                 index = store.getPrimaryIndex
7882                     (Integer.class, ProxyClassObjectArrayFieldChanged.class);
7883             ProxyClassObjectArrayFieldChanged obj = index.get(1);
7884             TestCase.assertNotNull(obj);
7885             TestCase.assertEquals(1, obj.key);
7886             TestCase.assertNotNull(obj.embed);
7887             TestCase.assertEquals(2, obj.embed.data);
7888             if (doUpdate) {
7889                 index.put(obj);
7890             }
7891         }
7892 
7893         @Override
copyRawObjects(RawStore rawStore, EntityStore newStore)7894         void copyRawObjects(RawStore rawStore, EntityStore newStore)
7895             throws DatabaseException {
7896 
7897             PrimaryIndex<Integer, ProxyClassObjectArrayFieldChanged>
7898                 index = newStore.getPrimaryIndex
7899                     (Integer.class, ProxyClassObjectArrayFieldChanged.class);
7900             RawObject raw = rawStore.getPrimaryIndex(NAME).get(1);
7901             index.put((ProxyClassObjectArrayFieldChanged)
7902                       newStore.getModel().convertRawObject(raw));
7903         }
7904 
7905         @Override
readRawObjects(RawStore store, boolean expectEvolved, boolean expectUpdated)7906         void readRawObjects(RawStore store,
7907                             boolean expectEvolved,
7908                             boolean expectUpdated)
7909             throws DatabaseException {
7910 
7911             RawType embedType = store.getModel().getRawType(NAME2);
7912             RawObject data =
7913                 makeRawObject(store, expectEvolved, expectUpdated);
7914             RawObject embed = new RawObject
7915                 (embedType, makeValues("data", data), null);
7916             RawObject obj = readRaw(store, 1, NAME, 0, CASECLS, 0);
7917             checkRawFields(obj, "key", 1, "embed", embed);
7918 
7919         }
7920 
makeRawObject(RawStore store, boolean expectEvolved, boolean expectUpdated)7921         static RawObject makeRawObject(RawStore store,
7922                                        boolean expectEvolved,
7923                                        boolean expectUpdated) {
7924             RawType integerClassType =
7925                 store.getModel().getRawType(IntegerClass.class.getName());
7926             RawObject dataRawObject = null;
7927             if (expectEvolved) {
7928                 RawType dataType = null;
7929                 if (expectUpdated) {
7930                     dataType = store.getModel().getRawType
7931                         (Object[].class.getName());
7932                 } else {
7933                     dataType = store.getModel().getRawType
7934                         (IntegerClass[].class.getName());
7935                 }
7936                 Map<String, Object> integerClassValues =
7937                     new HashMap<String, Object>();
7938                 integerClassValues.put("data", 2);
7939                 RawObject integerClassObject =
7940                     new RawObject(integerClassType, integerClassValues, null);
7941                 RawObject[] elements = new RawObject[1];
7942                 elements[0] = integerClassObject;
7943                 dataRawObject = new RawObject(dataType, elements);
7944             } else {
7945                 RawType dataType =
7946                     store.getModel().getRawType(Integer[].class.getName());
7947                 Integer[] elements = new Integer[1];
7948                 elements[0] = 2;
7949                 dataRawObject = new RawObject(dataType, elements);
7950             }
7951             return dataRawObject;
7952         }
7953     }
7954 
7955     @Persistent(proxyFor=ProxiedClass.class, version=1)
7956     static class ProxiedClass_Proxy5 implements PersistentProxy<ProxiedClass> {
7957         Object[] data;
7958 
initializeProxy(ProxiedClass o)7959         public void initializeProxy(ProxiedClass o) {
7960             data = new Object[1];
7961             data[0] = new IntegerClass(o.data);
7962         }
7963 
convertProxy()7964         public ProxiedClass convertProxy() {
7965             return new ProxiedClass(((IntegerClass)data[0]).data);
7966         }
7967     }
7968 }
7969