Imported Upstream version 5.3.21
[platform/upstream/libdb.git] / test / java / compat / src / com / sleepycat / persist / test / EvolveClasses.java
1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2000, 2012 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
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      */
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      */
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      */
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
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
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
163         void checkUnevolvedModel(EntityModel model, Environment env) {
164             checkEntity(true, model, env, NAME, 0, "skey");
165             checkVersions(model, NAME, 0);
166         }
167
168         @Override
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
191         int getNRecordsExpected() {
192             return 0;
193         }
194
195         @Override
196         Mutations getMutations() {
197             Mutations m = new Mutations();
198             m.addDeleter(new Deleter(NAME, 0));
199             return m;
200         }
201
202         @Override
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
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
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
241         void checkUnevolvedModel(EntityModel model, Environment env) {
242             checkEntity(true, model, env, NAME, 0, "skey");
243             checkVersions(model, NAME, 0);
244         }
245
246         @Override
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
270         int getNRecordsExpected() {
271             return 0;
272         }
273
274         @Override
275         Mutations getMutations() {
276             Mutations m = new Mutations();
277             m.addDeleter(new Deleter(NAME, 0));
278             return m;
279         }
280
281         @Override
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
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
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
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
335         void checkUnevolvedModel(EntityModel model, Environment env) {
336             checkEntity(true, model, env, NAME, 0, "skey");
337             checkVersions(model, NAME, 0);
338         }
339
340         @Override
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
367         int getNRecordsExpected() {
368             return 0;
369         }
370
371         @Override
372         Mutations getMutations() {
373             Mutations m = new Mutations();
374             m.addDeleter(new Deleter(NAME, 0));
375             return m;
376         }
377
378         @Override
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
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
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
466         Mutations getMutations() {
467             Mutations m = new Mutations();
468             m.addDeleter(new Deleter(NAME2, 0));
469             return m;
470         }
471
472         @Override
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
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
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
520         int getNRecordsExpected() {
521             return 0;
522         }
523
524         @Override
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
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
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
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
597         Mutations getMutations() {
598             Mutations m = new Mutations();
599             m.addDeleter(new Deleter(NAME2, 0));
600             return m;
601         }
602
603         @Override
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
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
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
656         int getNRecordsExpected() {
657             return 0;
658         }
659
660         @Override
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
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
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
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
739         Mutations getMutations() {
740             Mutations m = new Mutations();
741             m.addDeleter(new Deleter(NAME2, 0));
742             return m;
743         }
744
745         @Override
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
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
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
803         int getNRecordsExpected() {
804             return 0;
805         }
806
807         @Override
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
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
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
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
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
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
924         void checkUnevolvedModel(EntityModel model, Environment env) {
925             checkEntity(true, model, env, NAME, 0, "skey");
926             checkVersions(model, NAME, 0);
927         }
928
929         @Override
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
962         Mutations getMutations() {
963             Mutations m = new Mutations();
964             m.addRenamer(new Renamer(NAME, 0, NAME2));
965             return m;
966         }
967
968         @Override
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
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
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
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
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
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
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
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
1138             public void initialize(EntityModel model) {
1139                 newType = model.getRawType(NAME2);
1140                 TestCase.assertNotNull(newType);
1141             }
1142
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
1151             public boolean equals(Object other) {
1152                 return other instanceof MyConversion;
1153             }
1154         }
1155
1156         @Override
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
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
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
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
1258         Mutations getMutations() {
1259             Mutations m = new Mutations();
1260             m.addDeleter(new Deleter(NAME, 0));
1261             return m;
1262         }
1263
1264         @Override
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
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
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
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
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
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
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
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
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
1459         Mutations getMutations() {
1460             Mutations m = new Mutations();
1461             m.addDeleter(new Deleter(NAME3, 0));
1462             return m;
1463         }
1464
1465         @Override
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
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
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
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
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
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
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
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
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
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
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
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
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
1761         void checkUnevolvedModel(EntityModel model, Environment env) {
1762             checkEntity(true, model, env, NAME, 0, null);
1763             checkVersions(model, NAME, 0);
1764         }
1765
1766         @Override
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
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
1798         void checkUnevolvedModel(EntityModel model, Environment env) {
1799             checkEntity(true, model, env, NAME, 0, null);
1800             checkVersions(model, NAME, 0);
1801         }
1802
1803         @Override
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
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
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
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
1853         void checkUnevolvedModel(EntityModel model, Environment env) {
1854             checkEntity(true, model, env, NAME, 0, null);
1855             checkVersions(model, NAME, 0);
1856         }
1857
1858         @Override
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
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
1894         void checkUnevolvedModel(EntityModel model, Environment env) {
1895             checkEntity(true, model, env, NAME, 0, null);
1896             checkVersions(model, NAME, 0);
1897         }
1898
1899         @Override
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
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
1931         void checkUnevolvedModel(EntityModel model, Environment env) {
1932             checkEntity(true, model, env, NAME, 0, null);
1933             checkVersions(model, NAME, 0);
1934         }
1935
1936         @Override
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
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
1968         void checkUnevolvedModel(EntityModel model, Environment env) {
1969             checkEntity(true, model, env, NAME, 0, null);
1970             checkVersions(model, NAME, 0);
1971         }
1972
1973         @Override
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
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
2005         void checkUnevolvedModel(EntityModel model, Environment env) {
2006             checkEntity(true, model, env, NAME, 0, null);
2007             checkVersions(model, NAME, 0);
2008         }
2009
2010         @Override
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
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
2042         void checkUnevolvedModel(EntityModel model, Environment env) {
2043             checkEntity(true, model, env, NAME, 0, null);
2044             checkVersions(model, NAME, 0);
2045         }
2046
2047         @Override
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
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
2079         void checkUnevolvedModel(EntityModel model, Environment env) {
2080             checkEntity(true, model, env, NAME, 0, null);
2081             checkVersions(model, NAME, 0);
2082         }
2083
2084         @Override
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
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
2116         void checkUnevolvedModel(EntityModel model, Environment env) {
2117             checkEntity(true, model, env, NAME, 0, null);
2118             checkVersions(model, NAME, 0);
2119         }
2120
2121         @Override
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
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
2153         void checkUnevolvedModel(EntityModel model, Environment env) {
2154             checkEntity(true, model, env, NAME, 0, null);
2155             checkVersions(model, NAME, 0);
2156         }
2157
2158         @Override
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
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
2190         void checkUnevolvedModel(EntityModel model, Environment env) {
2191             checkEntity(true, model, env, NAME, 0, null);
2192             checkVersions(model, NAME, 0);
2193         }
2194
2195         @Override
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
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
2227         void checkUnevolvedModel(EntityModel model, Environment env) {
2228             checkEntity(true, model, env, NAME, 0, null);
2229             checkVersions(model, NAME, 0);
2230         }
2231
2232         @Override
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
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
2264         void checkUnevolvedModel(EntityModel model, Environment env) {
2265             checkEntity(true, model, env, NAME, 0, null);
2266             checkVersions(model, NAME, 0);
2267         }
2268
2269         @Override
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
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
2301         void checkUnevolvedModel(EntityModel model, Environment env) {
2302             checkEntity(true, model, env, NAME, 0, null);
2303             checkVersions(model, NAME, 0);
2304         }
2305
2306         @Override
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
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
2338         void checkUnevolvedModel(EntityModel model, Environment env) {
2339             checkEntity(true, model, env, NAME, 0, null);
2340             checkVersions(model, NAME, 0);
2341         }
2342
2343         @Override
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
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
2375         void checkUnevolvedModel(EntityModel model, Environment env) {
2376             checkEntity(true, model, env, NAME, 0, null);
2377             checkVersions(model, NAME, 0);
2378         }
2379
2380         @Override
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
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
2412         void checkUnevolvedModel(EntityModel model, Environment env) {
2413             checkEntity(true, model, env, NAME, 0, null);
2414             checkVersions(model, NAME, 0);
2415         }
2416
2417         @Override
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
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
2449         void checkUnevolvedModel(EntityModel model, Environment env) {
2450             checkEntity(true, model, env, NAME, 0, null);
2451             checkVersions(model, NAME, 0);
2452         }
2453
2454         @Override
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
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
2486         void checkUnevolvedModel(EntityModel model, Environment env) {
2487             checkEntity(true, model, env, NAME, 0, null);
2488             checkVersions(model, NAME, 0);
2489         }
2490
2491         @Override
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
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
2524         void checkUnevolvedModel(EntityModel model, Environment env) {
2525             checkEntity(true, model, env, NAME, 0, "ff");
2526             checkVersions(model, NAME, 0);
2527         }
2528
2529         @Override
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
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
2562         void checkUnevolvedModel(EntityModel model, Environment env) {
2563             checkEntity(true, model, env, NAME, 0, "ff");
2564             checkVersions(model, NAME, 0);
2565         }
2566
2567         @Override
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
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
2600         void checkUnevolvedModel(EntityModel model, Environment env) {
2601             checkEntity(true, model, env, NAME, 0, "ff");
2602             checkVersions(model, NAME, 0);
2603         }
2604
2605         @Override
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
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
2638         void checkUnevolvedModel(EntityModel model, Environment env) {
2639             checkEntity(true, model, env, NAME, 0, "ff");
2640             checkVersions(model, NAME, 0);
2641         }
2642
2643         @Override
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
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
2676         void checkUnevolvedModel(EntityModel model, Environment env) {
2677             checkEntity(true, model, env, NAME, 0, "ff");
2678             checkVersions(model, NAME, 0);
2679         }
2680
2681         @Override
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
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
2714         void checkUnevolvedModel(EntityModel model, Environment env) {
2715             checkEntity(true, model, env, NAME, 0, "ff");
2716             checkVersions(model, NAME, 0);
2717         }
2718
2719         @Override
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
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
2752         void checkUnevolvedModel(EntityModel model, Environment env) {
2753             checkEntity(true, model, env, NAME, 0, "ff");
2754             checkVersions(model, NAME, 0);
2755         }
2756
2757         @Override
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
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
2790         void checkUnevolvedModel(EntityModel model, Environment env) {
2791             checkEntity(true, model, env, NAME, 0, "ff");
2792             checkVersions(model, NAME, 0);
2793         }
2794
2795         @Override
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
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
2828         void checkUnevolvedModel(EntityModel model, Environment env) {
2829             checkEntity(true, model, env, NAME, 0, "ff");
2830             checkVersions(model, NAME, 0);
2831         }
2832
2833         @Override
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
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
2866         void checkUnevolvedModel(EntityModel model, Environment env) {
2867             checkEntity(true, model, env, NAME, 0, "ff");
2868             checkVersions(model, NAME, 0);
2869         }
2870
2871         @Override
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
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
2904         void checkUnevolvedModel(EntityModel model, Environment env) {
2905             checkEntity(true, model, env, NAME, 0, "ff");
2906             checkVersions(model, NAME, 0);
2907         }
2908
2909         @Override
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
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
2942         void checkUnevolvedModel(EntityModel model, Environment env) {
2943             checkEntity(true, model, env, NAME, 0, "ff");
2944             checkVersions(model, NAME, 0);
2945         }
2946
2947         @Override
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
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
2980         void checkUnevolvedModel(EntityModel model, Environment env) {
2981             checkEntity(true, model, env, NAME, 0, "ff");
2982             checkVersions(model, NAME, 0);
2983         }
2984
2985         @Override
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
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
3017         void checkUnevolvedModel(EntityModel model, Environment env) {
3018             checkEntity(true, model, env, NAME, 0, null);
3019             checkVersions(model, NAME, 0);
3020         }
3021
3022         @Override
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
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
3052         void checkUnevolvedModel(EntityModel model, Environment env) {
3053             checkEntity(true, model, env, NAME, 0, null);
3054             checkVersions(model, NAME, 0);
3055         }
3056
3057         @Override
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
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
3087         void checkUnevolvedModel(EntityModel model, Environment env) {
3088             checkEntity(true, model, env, NAME, 0, null);
3089             checkVersions(model, NAME, 0);
3090         }
3091
3092         @Override
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
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
3122         void checkUnevolvedModel(EntityModel model, Environment env) {
3123             checkEntity(true, model, env, NAME, 0, null);
3124             checkVersions(model, NAME, 0);
3125         }
3126
3127         @Override
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
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
3157         void checkUnevolvedModel(EntityModel model, Environment env) {
3158             checkEntity(true, model, env, NAME, 0, null);
3159             checkVersions(model, NAME, 0);
3160         }
3161
3162         @Override
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
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
3192         void checkUnevolvedModel(EntityModel model, Environment env) {
3193             checkEntity(true, model, env, NAME, 0, null);
3194             checkVersions(model, NAME, 0);
3195         }
3196
3197         @Override
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
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
3227         void checkUnevolvedModel(EntityModel model, Environment env) {
3228             checkEntity(true, model, env, NAME, 0, null);
3229             checkVersions(model, NAME, 0);
3230         }
3231
3232         @Override
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
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
3262         void checkUnevolvedModel(EntityModel model, Environment env) {
3263             checkEntity(true, model, env, NAME, 0, null);
3264             checkVersions(model, NAME, 0);
3265         }
3266
3267         @Override
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
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
3297         void checkUnevolvedModel(EntityModel model, Environment env) {
3298             checkEntity(true, model, env, NAME, 0, null);
3299             checkVersions(model, NAME, 0);
3300         }
3301
3302         @Override
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
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
3332         void checkUnevolvedModel(EntityModel model, Environment env) {
3333             checkEntity(true, model, env, NAME, 0, null);
3334             checkVersions(model, NAME, 0);
3335         }
3336
3337         @Override
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
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
3367         void checkUnevolvedModel(EntityModel model, Environment env) {
3368             checkEntity(true, model, env, NAME, 0, null);
3369             checkVersions(model, NAME, 0);
3370         }
3371
3372         @Override
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
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
3402         void checkUnevolvedModel(EntityModel model, Environment env) {
3403             checkEntity(true, model, env, NAME, 0, null);
3404             checkVersions(model, NAME, 0);
3405         }
3406
3407         @Override
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
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
3437         void checkUnevolvedModel(EntityModel model, Environment env) {
3438             checkEntity(true, model, env, NAME, 0, null);
3439             checkVersions(model, NAME, 0);
3440         }
3441
3442         @Override
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
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
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
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
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
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
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
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
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
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
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
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
3653         AllowFieldTypeChanges_Key() {
3654             this(false);
3655         }
3656
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
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
3882             public void initialize(EntityModel model) {}
3883
3884             public Object convert(Object o) {
3885                 return ((Long) o).intValue();
3886             }
3887
3888             @Override
3889             public boolean equals(Object other) { return true; }
3890         }
3891
3892         @SuppressWarnings("serial")
3893         static class MyConversion2 implements Conversion {
3894
3895             public void initialize(EntityModel model) {}
3896
3897             public Object convert(Object o) {
3898                 return Long.valueOf((String) o);
3899             }
3900
3901             @Override
3902             public boolean equals(Object other) { return true; }
3903         }
3904
3905         @Override
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
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
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
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
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
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
4326         public void initialize(EntityModel model) {
4327         }
4328
4329         public Object convert(Object fromValue) {
4330             String s1 = (String) fromValue;
4331             return (new StringBuilder(s1)).reverse().toString();
4332         }
4333
4334         @Override
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
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
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
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
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
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
4442         public void initialize(EntityModel model) {
4443         }
4444
4445         public Object convert(Object fromValue) {
4446             return Integer.valueOf((String) fromValue);
4447         }
4448
4449         @Override
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
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
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
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
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
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
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
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
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
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
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
4666         public void initialize(EntityModel model) {
4667             addressType = model.getRawType
4668                 (ConvertExample2_Address.class.getName());
4669         }
4670
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
4685         public boolean equals(Object o) {
4686             return o instanceof ConvertExample2_Conversion;
4687         }
4688
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
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
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
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
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
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
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
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
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
4847         public void initialize(EntityModel model) {
4848             newPersonType = model.getRawType
4849                 (ConvertExample3Reverse_Person.class.getName());
4850         }
4851
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
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
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
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
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
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
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
4991         public void initialize(EntityModel model) {
4992             newAType = model.getRawType(ConvertExample4_A.class.getName());
4993             newBType = model.getRawType(ConvertExample4_B.class.getName());
4994         }
4995
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
5497         public void initializeProxy(ProxiedClass o) {
5498             data = o.data;
5499         }
5500
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
5521         void configure(EntityModel model, StoreConfig config) {
5522             model.registerClass(ProxiedClass_Proxy.class);
5523         }
5524
5525         @Override
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
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
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
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
5596         public void initializeProxy(StringBuilder o) {
5597             data = o.toString();
5598         }
5599
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
5611         public void initializeProxy(StringBuilder o) {
5612             data = o.toString();
5613         }
5614
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
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
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
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
5681         Mutations getMutations() {
5682             Mutations m = new Mutations();
5683             m.addRenamer(new Renamer(NAME3, 0, NAME2));
5684             return m;
5685         }
5686
5687         @Override
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
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
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
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
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
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
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
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
5859         private InsertEnumConstant_KeyClass() {}
5860
5861         InsertEnumConstant_KeyClass(InsertEnumConstant_Enum key) {
5862             this.key = key;
5863         }
5864
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
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
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
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
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
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
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
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
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
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
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
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
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
6453         void configure(EntityModel model, StoreConfig config) {
6454             model.registerClass(AllowChangeKeyMetadataInSubclass.class);
6455         }
6456
6457         @Override
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
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
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
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
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
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
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
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
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
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
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
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
6743             public void initialize(EntityModel model) {
6744             }
6745
6746             public Object convert(Object fromValue) {
6747                 return fromValue.toString();
6748             }
6749
6750             @Override
6751             public boolean equals(Object other) {
6752                 return other instanceof IntToString;
6753             }
6754         }
6755
6756         @Override
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
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
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
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
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
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
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
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         
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         
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
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
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
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
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
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         
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         
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
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
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
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
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
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         
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         
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
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
7241         Mutations getMutations() {
7242             Mutations m = new Mutations();
7243             m.addRenamer(new Renamer(NAME, 0, "anonKey", "znonKey"));
7244             return m;
7245         }
7246         
7247         @Override
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
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
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         
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         
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
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
7361         void configure(EntityModel model, StoreConfig config) {
7362             model.registerClass(ProxiedClass_Proxy2.class);
7363         }
7364         
7365         @Override
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
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
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
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
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         
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
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
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
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
7532         public void initializeProxy(ProxiedClass o) {
7533             data = new HashMap<MyEnum, Integer>();
7534             data.put(MyEnum.DATA, o.data);
7535         }
7536
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
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
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
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
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
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
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
7646         public void initializeProxy(ProxiedClass o) {
7647             data = new HashMap<Object, Integer>();
7648             data.put(MyEnum.DATA, o.data);
7649         }
7650
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
7673         void configure(EntityModel model, StoreConfig config) {
7674             model.registerClass(ProxiedClass_Proxy4.class);
7675         }
7676         
7677         @Override
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
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
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
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
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          
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
7775             public void initialize(EntityModel model) {
7776                 newDataType = model.getRawType(IntegerClass[].class.getName());
7777                 integerClassType = 
7778                     model.getRawType(IntegerClass.class.getName());
7779             }
7780
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
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
7809         public void initializeProxy(ProxiedClass o) {
7810             data = new IntegerClass[1];
7811             data[0] = new IntegerClass(o.data);
7812         }
7813
7814         public ProxiedClass convertProxy() {
7815             return new ProxiedClass(data[0].data);
7816         }
7817     }
7818     
7819     @Persistent 
7820     static class IntegerClass {
7821         int data;
7822         
7823         IntegerClass(){}
7824         
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
7848         void configure(EntityModel model, StoreConfig config) {
7849             model.registerClass(ProxiedClass_Proxy5.class);
7850             model.registerClass(IntegerClass[].class);
7851         }
7852         
7853         @Override
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
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
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
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
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         
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
7959         public void initializeProxy(ProxiedClass o) {
7960             data = new Object[1];
7961             data[0] = new IntegerClass(o.data);
7962         }
7963
7964         public ProxiedClass convertProxy() {
7965             return new ProxiedClass(((IntegerClass)data[0]).data);
7966         }
7967     }
7968 }