1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2000,2008 Oracle.  All rights reserved.
5 *
6 * $Id: EvolveClasses.java,v 1.1 2008/02/07 17:12:32 mark Exp $
7 */
8package com.sleepycat.persist.test;
9
10import static com.sleepycat.persist.model.Relationship.ONE_TO_ONE;
11import static com.sleepycat.persist.model.Relationship.MANY_TO_ONE;
12
13import java.math.BigInteger;
14import java.util.Collections;
15import java.util.HashMap;
16import java.util.Map;
17import java.util.StringTokenizer;
18
19import junit.framework.TestCase;
20
21import com.sleepycat.db.DatabaseException;
22import com.sleepycat.db.Environment;
23import com.sleepycat.persist.EntityStore;
24import com.sleepycat.persist.PrimaryIndex;
25import com.sleepycat.persist.SecondaryIndex;
26import com.sleepycat.persist.StoreConfig;
27import com.sleepycat.persist.evolve.Conversion;
28import com.sleepycat.persist.evolve.Converter;
29import com.sleepycat.persist.evolve.Deleter;
30import com.sleepycat.persist.evolve.EntityConverter;
31import com.sleepycat.persist.evolve.Mutations;
32import com.sleepycat.persist.evolve.Renamer;
33import com.sleepycat.persist.model.Entity;
34import com.sleepycat.persist.model.EntityModel;
35import com.sleepycat.persist.model.KeyField;
36import com.sleepycat.persist.model.Persistent;
37import com.sleepycat.persist.model.PersistentProxy;
38import com.sleepycat.persist.model.PrimaryKey;
39import com.sleepycat.persist.model.SecondaryKey;
40import com.sleepycat.persist.raw.RawObject;
41import com.sleepycat.persist.raw.RawStore;
42import 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 */
51class EvolveClasses {
52
53    private static final String PREFIX = EvolveClasses.class.getName() + '$';
54    private static final String CASECLS = EvolveCase.class.getName();
55
56    /**
57     * Reads a raw object and checks its superclass names and versions.
58     */
59    private static RawObject readRaw(RawStore store,
60                                     Object key,
61                                     Object... classVersionPairs)
62        throws DatabaseException {
63
64        TestCase.assertNotNull(store);
65        TestCase.assertNotNull(key);
66
67        String entityClsName = (String) classVersionPairs[0];
68        PrimaryIndex<Object,RawObject> index =
69            store.getPrimaryIndex(entityClsName);
70        TestCase.assertNotNull(index);
71
72        RawObject obj = index.get(key);
73        TestCase.assertNotNull(obj);
74
75        checkRawType(obj.getType(), classVersionPairs);
76
77        RawObject superObj = obj.getSuper();
78        for (int i = 2; i < classVersionPairs.length; i += 2) {
79            Object[] a = new Object[classVersionPairs.length - i];
80            System.arraycopy(classVersionPairs, i, a, 0, a.length);
81            TestCase.assertNotNull(superObj);
82            checkRawType(superObj.getType(), a);
83            superObj = superObj.getSuper();
84        }
85
86        return obj;
87    }
88
89    /**
90     * Reads a raw object and checks its superclass names and versions.
91     */
92    private static void checkRawType(RawType type,
93                                     Object... classVersionPairs) {
94        TestCase.assertNotNull(type);
95        TestCase.assertNotNull(classVersionPairs);
96        TestCase.assertTrue(classVersionPairs.length % 2 == 0);
97
98        for (int i = 0; i < classVersionPairs.length; i += 2) {
99            String clsName = (String) classVersionPairs[i];
100            int clsVersion = (Integer) classVersionPairs[i + 1];
101            TestCase.assertEquals(clsName, type.getClassName());
102            TestCase.assertEquals(clsVersion, type.getVersion());
103            type = type.getSuperType();
104        }
105        TestCase.assertNull(type);
106    }
107
108    /**
109     * Checks that a raw object contains the specified field values.  Does not
110     * check superclass fields.
111     */
112    private static void checkRawFields(RawObject obj,
113                                       Object... nameValuePairs) {
114        TestCase.assertNotNull(obj);
115        TestCase.assertNotNull(obj.getValues());
116        TestCase.assertNotNull(nameValuePairs);
117        TestCase.assertTrue(nameValuePairs.length % 2 == 0);
118
119        Map<String,Object> values = obj.getValues();
120        TestCase.assertEquals(nameValuePairs.length / 2, values.size());
121
122        for (int i = 0; i < nameValuePairs.length; i += 2) {
123            String name = (String) nameValuePairs[i];
124            Object value = nameValuePairs[i + 1];
125            TestCase.assertEquals(name, value, values.get(name));
126        }
127    }
128
129    private static Map<String,Object> makeValues(Object... nameValuePairs) {
130        TestCase.assertTrue(nameValuePairs.length % 2 == 0);
131        Map<String,Object> values = new HashMap<String,Object>();
132        for (int i = 0; i < nameValuePairs.length; i += 2) {
133            values.put((String) nameValuePairs[i], nameValuePairs[i + 1]);
134        }
135        return values;
136    }
137
138    /**
139     * Disallow removing an entity class when no Deleter mutation is specified.
140     */
141    static class DeletedEntity1_ClassRemoved_NoMutation extends EvolveCase {
142
143        private static final String NAME =
144            PREFIX + "DeletedEntity1_ClassRemoved";
145
146        @Override
147        public String getStoreOpenException() {
148            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";
149        }
150
151        @Override
152        void checkUnevolvedModel(EntityModel model, Environment env) {
153            checkEntity(true, model, env, NAME, 0, "skey");
154            checkVersions(model, NAME, 0);
155        }
156
157        @Override
158        void readRawObjects(RawStore store,
159                            boolean expectEvolved,
160                            boolean expectUpdated)
161            throws DatabaseException {
162
163            if (expectEvolved) {
164                TestCase.fail();
165            }
166            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
167            checkRawFields(obj, "key", 99, "skey", 88);
168        }
169    }
170
171    /**
172     * Allow removing an entity class when a Deleter mutation is specified.
173     */
174    static class DeletedEntity2_ClassRemoved_WithDeleter extends EvolveCase {
175
176        private static final String NAME =
177            PREFIX + "DeletedEntity2_ClassRemoved";
178
179        @Override
180        int getNRecordsExpected() {
181            return 0;
182        }
183
184        @Override
185        Mutations getMutations() {
186            Mutations m = new Mutations();
187            m.addDeleter(new Deleter(NAME, 0));
188            return m;
189        }
190
191        @Override
192        void checkEvolvedModel(EntityModel model,
193                               Environment env,
194                               boolean oldTypesExist) {
195            checkEntity(false, model, env, NAME, 0, "skey");
196            if (oldTypesExist) {
197                checkVersions(model, NAME, 0);
198            }
199        }
200
201        @Override
202        void readRawObjects(RawStore store,
203                            boolean expectEvolved,
204                            boolean expectUpdated)
205            throws DatabaseException {
206
207            if (expectEvolved) {
208                return;
209            }
210            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
211            checkRawFields(obj, "key", 99, "skey", 88);
212        }
213    }
214
215    /**
216     * Disallow removing the Entity annotation when no Deleter mutation is
217     * specified.
218     */
219    static class DeletedEntity3_AnnotRemoved_NoMutation extends EvolveCase {
220
221        private static final String NAME =
222            DeletedEntity3_AnnotRemoved_NoMutation.class.getName();
223
224        @Override
225        public String getStoreOpenException() {
226            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";
227        }
228
229        @Override
230        void checkUnevolvedModel(EntityModel model, Environment env) {
231            checkEntity(true, model, env, NAME, 0, "skey");
232            checkVersions(model, NAME, 0);
233        }
234
235        @Override
236        void readRawObjects(RawStore store,
237                            boolean expectEvolved,
238                            boolean expectUpdated)
239            throws DatabaseException {
240
241            if (expectEvolved) {
242                TestCase.fail();
243            }
244            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
245            checkRawFields(obj, "key", 99, "skey", 88);
246        }
247    }
248
249    /**
250     * Allow removing the Entity annotation when a Deleter mutation is
251     * specified.
252     */
253    static class DeletedEntity4_AnnotRemoved_WithDeleter extends EvolveCase {
254
255        private static final String NAME =
256            DeletedEntity4_AnnotRemoved_WithDeleter.class.getName();
257
258        @Override
259        int getNRecordsExpected() {
260            return 0;
261        }
262
263        @Override
264        Mutations getMutations() {
265            Mutations m = new Mutations();
266            m.addDeleter(new Deleter(NAME, 0));
267            return m;
268        }
269
270        @Override
271        void checkEvolvedModel(EntityModel model,
272                               Environment env,
273                               boolean oldTypesExist) {
274            checkEntity(false, model, env, NAME, 0, "skey");
275            if (oldTypesExist) {
276                checkVersions(model, NAME, 0);
277            }
278        }
279
280        @Override
281        void readObjects(EntityStore store, boolean doUpdate)
282            throws DatabaseException {
283
284            try {
285                store.getPrimaryIndex
286                    (Integer.class,
287                     DeletedEntity4_AnnotRemoved_WithDeleter.class);
288                TestCase.fail();
289            } catch (Exception e) {
290                checkEquals
291                    ("java.lang.IllegalArgumentException: Class could not be loaded or is not an entity class: com.sleepycat.persist.test.EvolveClasses$DeletedEntity4_AnnotRemoved_WithDeleter",
292                     e.toString());
293            }
294        }
295
296        @Override
297        void readRawObjects(RawStore store,
298                            boolean expectEvolved,
299                            boolean expectUpdated)
300            throws DatabaseException {
301
302            if (expectEvolved) {
303                return;
304            }
305            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
306            checkRawFields(obj, "key", 99, "skey", 88);
307        }
308    }
309
310    /**
311     * Disallow changing the Entity annotation to Persistent when no Deleter
312     * mutation is specified.
313     */
314    @Persistent(version=1)
315    static class DeletedEntity5_EntityToPersist_NoMutation extends EvolveCase {
316
317        private static final String NAME =
318            DeletedEntity5_EntityToPersist_NoMutation.class.getName();
319
320        @Override
321        public String getStoreOpenException() {
322            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";
323        }
324
325        @Override
326        void checkUnevolvedModel(EntityModel model, Environment env) {
327            checkEntity(true, model, env, NAME, 0, "skey");
328            checkVersions(model, NAME, 0);
329        }
330
331        @Override
332        void readRawObjects(RawStore store,
333                            boolean expectEvolved,
334                            boolean expectUpdated)
335            throws DatabaseException {
336
337            if (expectEvolved) {
338                TestCase.fail();
339            }
340            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
341            checkRawFields(obj, "key", 99, "skey", 88);
342        }
343    }
344
345    /**
346     * Allow changing the Entity annotation to Persistent when a Deleter
347     * mutation is specified.
348     */
349    @Persistent(version=1)
350    static class DeletedEntity6_EntityToPersist_WithDeleter extends EvolveCase {
351
352        private static final String NAME =
353            DeletedEntity6_EntityToPersist_WithDeleter.class.getName();
354        private static final String NAME2 =
355            Embed_DeletedEntity6_EntityToPersist_WithDeleter.class.getName();
356
357        @Override
358        int getNRecordsExpected() {
359            return 0;
360        }
361
362        @Override
363        Mutations getMutations() {
364            Mutations m = new Mutations();
365            m.addDeleter(new Deleter(NAME, 0));
366            return m;
367        }
368
369        @Override
370        void checkEvolvedModel(EntityModel model,
371                               Environment env,
372                               boolean oldTypesExist) {
373            checkNonEntity(true, model, env, NAME, 1);
374            if (oldTypesExist) {
375                checkVersions(model, NAME, 1, NAME, 0);
376            } else {
377                checkVersions(model, NAME, 1);
378            }
379        }
380
381        @Override
382        void readObjects(EntityStore store, boolean doUpdate)
383            throws DatabaseException {
384
385            /* Cannot get the primary index for the former entity class. */
386            try {
387                store.getPrimaryIndex
388                    (Integer.class,
389                     DeletedEntity6_EntityToPersist_WithDeleter.class);
390                TestCase.fail();
391            } catch (Exception e) {
392                checkEquals
393                    ("java.lang.IllegalArgumentException: Class could not be loaded or is not an entity class: com.sleepycat.persist.test.EvolveClasses$DeletedEntity6_EntityToPersist_WithDeleter",
394                     e.toString());
395            }
396
397            /* Can embed the now persistent class in another entity class. */
398            PrimaryIndex<Long,
399                         Embed_DeletedEntity6_EntityToPersist_WithDeleter>
400                index = store.getPrimaryIndex
401                    (Long.class,
402                     Embed_DeletedEntity6_EntityToPersist_WithDeleter.class);
403
404            if (doUpdate) {
405                Embed_DeletedEntity6_EntityToPersist_WithDeleter embed =
406                    new Embed_DeletedEntity6_EntityToPersist_WithDeleter();
407                index.put(embed);
408                embed = index.get(embed.key);
409                /* This new type should exist only after update. */
410                Environment env = store.getEnvironment();
411                EntityModel model = store.getModel();
412                checkEntity(true, model, env, NAME2, 0, null);
413                checkVersions(model, NAME2, 0);
414            }
415        }
416
417        @Override
418        void readRawObjects(RawStore store,
419                            boolean expectEvolved,
420                            boolean expectUpdated)
421            throws DatabaseException {
422
423            if (expectEvolved) {
424                return;
425            }
426            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
427            checkRawFields(obj, "key", 99, "skey", 88);
428        }
429    }
430
431    @Entity
432    static class Embed_DeletedEntity6_EntityToPersist_WithDeleter {
433
434        @PrimaryKey
435        long key = 99;
436
437        DeletedEntity6_EntityToPersist_WithDeleter embedded =
438            new DeletedEntity6_EntityToPersist_WithDeleter();
439    }
440
441    /**
442     * Disallow removing a Persistent class when no Deleter mutation is
443     * specified, even when the Entity class that embedded the Persistent class
444     * is deleted properly (by removing the Entity annotation in this case).
445     */
446    static class DeletedPersist1_ClassRemoved_NoMutation extends EvolveCase {
447
448        private static final String NAME =
449            PREFIX + "DeletedPersist1_ClassRemoved";
450
451        private static final String NAME2 =
452            DeletedPersist1_ClassRemoved_NoMutation.class.getName();
453
454        @Override
455        Mutations getMutations() {
456            Mutations m = new Mutations();
457            m.addDeleter(new Deleter(NAME2, 0));
458            return m;
459        }
460
461        @Override
462        public String getStoreOpenException() {
463            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";
464        }
465
466        @Override
467        void checkUnevolvedModel(EntityModel model, Environment env) {
468            checkNonEntity(true, model, env, NAME, 0);
469            checkEntity(true, model, env, NAME2, 0, null);
470            checkVersions(model, NAME, 0);
471            checkVersions(model, NAME2, 0);
472        }
473
474        @Override
475        void readRawObjects(RawStore store,
476                            boolean expectEvolved,
477                            boolean expectUpdated)
478            throws DatabaseException {
479
480            if (expectEvolved) {
481                TestCase.fail();
482            }
483
484            RawType embedType = store.getModel().getRawType(NAME);
485            checkRawType(embedType, NAME, 0);
486
487            RawObject embed =
488                new RawObject(embedType, makeValues("f", 123), null);
489
490            RawObject obj = readRaw(store, 99, NAME2, 0, CASECLS, 0);
491            checkRawFields(obj, "key", 99, "embed", embed);
492        }
493    }
494
495    /**
496     * Allow removing a Persistent class when a Deleter mutation is
497     * specified, and the Entity class that embedded the Persistent class
498     * is also be deleted properly (by removing the Entity annotation in this
499     * case).
500     */
501    static class DeletedPersist2_ClassRemoved_WithDeleter extends EvolveCase {
502
503        private static final String NAME =
504            PREFIX + "DeletedPersist2_ClassRemoved";
505        private static final String NAME2 =
506            DeletedPersist2_ClassRemoved_WithDeleter.class.getName();
507
508        @Override
509        int getNRecordsExpected() {
510            return 0;
511        }
512
513        @Override
514        Mutations getMutations() {
515            Mutations m = new Mutations();
516            m.addDeleter(new Deleter(NAME, 0));
517            m.addDeleter(new Deleter(NAME2, 0));
518            return m;
519        }
520
521        @Override
522        void checkEvolvedModel(EntityModel model,
523                               Environment env,
524                               boolean oldTypesExist) {
525            checkNonEntity(false, model, env, NAME, 0);
526            checkEntity(false, model, env, NAME2, 0, null);
527            if (oldTypesExist) {
528                checkVersions(model, NAME, 0);
529                checkVersions(model, NAME2, 0);
530            }
531        }
532
533        @Override
534        void readObjects(EntityStore store, boolean doUpdate)
535            throws DatabaseException {
536
537            try {
538                store.getPrimaryIndex
539                    (Integer.class,
540                     DeletedPersist2_ClassRemoved_WithDeleter.class);
541                TestCase.fail();
542            } catch (Exception e) {
543                checkEquals
544                    ("java.lang.IllegalArgumentException: Class could not be loaded or is not an entity class: com.sleepycat.persist.test.EvolveClasses$DeletedPersist2_ClassRemoved_WithDeleter",
545                     e.toString());
546            }
547        }
548
549        @Override
550        void readRawObjects(RawStore store,
551                            boolean expectEvolved,
552                            boolean expectUpdated)
553            throws DatabaseException {
554
555            if (expectEvolved) {
556                return;
557            }
558
559            RawType embedType = store.getModel().getRawType(NAME);
560            checkRawType(embedType, NAME, 0);
561
562            RawObject embed =
563                new RawObject(embedType, makeValues("f", 123), null);
564
565            RawObject obj = readRaw(store, 99, NAME2, 0, CASECLS, 0);
566            checkRawFields(obj, "key", 99, "embed", embed);
567        }
568    }
569
570    static class DeletedPersist3_AnnotRemoved {
571
572        int f = 123;
573    }
574
575    /**
576     * Disallow removing the Persistent annotation when no Deleter mutation is
577     * specified, even when the Entity class that embedded the Persistent class
578     * is deleted properly (by removing the Entity annotation in this case).
579     */
580    static class DeletedPersist3_AnnotRemoved_NoMutation extends EvolveCase {
581
582        private static final String NAME =
583            DeletedPersist3_AnnotRemoved.class.getName();
584        private static final String NAME2 =
585            DeletedPersist3_AnnotRemoved_NoMutation.class.getName();
586
587        @Override
588        Mutations getMutations() {
589            Mutations m = new Mutations();
590            m.addDeleter(new Deleter(NAME2, 0));
591            return m;
592        }
593
594        @Override
595        public String getStoreOpenException() {
596            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";
597        }
598
599        @Override
600        void checkUnevolvedModel(EntityModel model, Environment env) {
601            checkNonEntity(true, model, env, NAME, 0);
602            checkEntity(true, model, env, NAME2, 0, null);
603            checkVersions(model, NAME, 0);
604            checkVersions(model, NAME2, 0);
605        }
606
607        @Override
608        void readRawObjects(RawStore store,
609                            boolean expectEvolved,
610                            boolean expectUpdated)
611            throws DatabaseException {
612
613            if (expectEvolved) {
614                TestCase.fail();
615            }
616
617            RawType embedType = store.getModel().getRawType(NAME);
618            checkRawType(embedType, NAME, 0);
619
620            RawObject embed =
621                new RawObject(embedType, makeValues("f", 123), null);
622
623            RawObject obj = readRaw(store, 99, NAME2, 0, CASECLS, 0);
624            checkRawFields(obj, "key", 99, "embed", embed);
625        }
626    }
627
628    static class DeletedPersist4_AnnotRemoved {
629
630        int f = 123;
631    }
632
633    /**
634     * Allow removing the Persistent annotation when a Deleter mutation is
635     * specified, and the Entity class that embedded the Persistent class
636     * is also be deleted properly (by removing the Entity annotation in this
637     * case).
638     */
639    static class DeletedPersist4_AnnotRemoved_WithDeleter extends EvolveCase {
640
641        private static final String NAME =
642            DeletedPersist4_AnnotRemoved.class.getName();
643        private static final String NAME2 =
644            DeletedPersist4_AnnotRemoved_WithDeleter.class.getName();
645
646        @Override
647        int getNRecordsExpected() {
648            return 0;
649        }
650
651        @Override
652        Mutations getMutations() {
653            Mutations m = new Mutations();
654            m.addDeleter(new Deleter(NAME, 0));
655            m.addDeleter(new Deleter(NAME2, 0));
656            return m;
657        }
658
659        @Override
660        void checkEvolvedModel(EntityModel model,
661                               Environment env,
662                               boolean oldTypesExist) {
663            checkNonEntity(false, model, env, NAME, 0);
664            checkEntity(false, model, env, NAME2, 0, null);
665            if (oldTypesExist) {
666                checkVersions(model, NAME, 0);
667                checkVersions(model, NAME2, 0);
668            }
669        }
670
671        @Override
672        void readObjects(EntityStore store, boolean doUpdate)
673            throws DatabaseException {
674
675            try {
676                store.getPrimaryIndex
677                    (Integer.class,
678                     DeletedPersist4_AnnotRemoved_WithDeleter.class);
679                TestCase.fail();
680            } catch (Exception e) {
681                checkEquals
682                    ("java.lang.IllegalArgumentException: Class could not be loaded or is not an entity class: com.sleepycat.persist.test.EvolveClasses$DeletedPersist4_AnnotRemoved_WithDeleter",
683                     e.toString());
684            }
685        }
686
687        @Override
688        void readRawObjects(RawStore store,
689                            boolean expectEvolved,
690                            boolean expectUpdated)
691            throws DatabaseException {
692
693            if (expectEvolved) {
694                return;
695            }
696
697            RawType embedType = store.getModel().getRawType(NAME);
698            checkRawType(embedType, NAME, 0);
699
700            RawObject embed =
701                new RawObject(embedType, makeValues("f", 123), null);
702
703            RawObject obj = readRaw(store, 99, NAME2, 0, CASECLS, 0);
704            checkRawFields(obj, "key", 99, "embed", embed);
705        }
706    }
707
708    @Entity(version=1)
709    static class DeletedPersist5_PersistToEntity {
710
711        @PrimaryKey
712        int key = 99;
713
714        int f = 123;
715    }
716
717    /**
718     * Disallow changing the Entity annotation to Persistent when no Deleter
719     * mutation is specified, even when the Entity class that embedded the
720     * Persistent class is deleted properly (by removing the Entity annotation
721     * in this case).
722     */
723    static class DeletedPersist5_PersistToEntity_NoMutation
724        extends EvolveCase {
725
726        private static final String NAME =
727            DeletedPersist5_PersistToEntity.class.getName();
728        private static final String NAME2 =
729            DeletedPersist5_PersistToEntity_NoMutation.class.getName();
730
731        @Override
732        Mutations getMutations() {
733            Mutations m = new Mutations();
734            m.addDeleter(new Deleter(NAME2, 0));
735            return m;
736        }
737
738        @Override
739        public String getStoreOpenException() {
740            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";
741        }
742
743        @Override
744        void checkUnevolvedModel(EntityModel model, Environment env) {
745            checkNonEntity(true, model, env, NAME, 0);
746            checkEntity(true, model, env, NAME2, 0, null);
747            checkVersions(model, NAME, 0);
748            checkVersions(model, NAME2, 0);
749        }
750
751        @Override
752        void readRawObjects(RawStore store,
753                            boolean expectEvolved,
754                            boolean expectUpdated)
755            throws DatabaseException {
756
757            if (expectEvolved) {
758                TestCase.fail();
759            }
760
761            RawType embedType = store.getModel().getRawType(NAME);
762            checkRawType(embedType, NAME, 0);
763
764            RawObject embed =
765                new RawObject(embedType, makeValues("f", 123), null);
766
767            RawObject obj = readRaw(store, 99, NAME2, 0, CASECLS, 0);
768            checkRawFields(obj, "key", 99, "embed", embed);
769        }
770    }
771
772    @Entity(version=1)
773    static class DeletedPersist6_PersistToEntity {
774
775        @PrimaryKey
776        int key = 99;
777
778        int f = 123;
779    }
780
781    /**
782     * Allow changing the Entity annotation to Persistent when a Deleter
783     * mutation is specified, and the Entity class that embedded the Persistent
784     * class is also be deleted properly (by removing the Entity annotation in
785     * this case).
786     */
787    static class DeletedPersist6_PersistToEntity_WithDeleter
788        extends EvolveCase {
789
790        private static final String NAME =
791            DeletedPersist6_PersistToEntity.class.getName();
792        private static final String NAME2 =
793            DeletedPersist6_PersistToEntity_WithDeleter.class.getName();
794
795        @Override
796        int getNRecordsExpected() {
797            return 0;
798        }
799
800        @Override
801        Mutations getMutations() {
802            Mutations m = new Mutations();
803            m.addDeleter(new Deleter(NAME, 0));
804            m.addDeleter(new Deleter(NAME2, 0));
805            return m;
806        }
807
808        @Override
809        void checkEvolvedModel(EntityModel model,
810                               Environment env,
811                               boolean oldTypesExist) {
812            checkEntity(false, model, env, NAME2, 0, null);
813            if (oldTypesExist) {
814                checkVersions(model, NAME, 1, NAME, 0);
815                checkVersions(model, NAME2, 0);
816            } else {
817                checkVersions(model, NAME, 1);
818            }
819        }
820
821        @Override
822        void readObjects(EntityStore store, boolean doUpdate)
823            throws DatabaseException {
824
825            /* Cannot get the primary index for the former entity class. */
826            try {
827                store.getPrimaryIndex
828                    (Integer.class,
829                     DeletedPersist6_PersistToEntity_WithDeleter.class);
830                TestCase.fail();
831            } catch (Exception e) {
832                checkEquals
833                    ("java.lang.IllegalArgumentException: Class could not be loaded or is not an entity class: com.sleepycat.persist.test.EvolveClasses$DeletedPersist6_PersistToEntity_WithDeleter",
834                     e.toString());
835            }
836
837            /* Can use the primary index of the now entity class. */
838            PrimaryIndex<Integer,
839                         DeletedPersist6_PersistToEntity>
840                index = store.getPrimaryIndex
841                    (Integer.class,
842                     DeletedPersist6_PersistToEntity.class);
843
844            if (doUpdate) {
845                DeletedPersist6_PersistToEntity obj =
846                    new DeletedPersist6_PersistToEntity();
847                index.put(obj);
848                obj = index.get(obj.key);
849                /* This new type should exist only after update. */
850                Environment env = store.getEnvironment();
851                EntityModel model = store.getModel();
852                checkEntity(true, model, env, NAME, 1, null);
853            }
854        }
855
856        @Override
857        void copyRawObjects(RawStore rawStore, EntityStore newStore)
858            throws DatabaseException {
859
860            PrimaryIndex<Integer,
861                         DeletedPersist6_PersistToEntity>
862                index = newStore.getPrimaryIndex
863                    (Integer.class,
864                     DeletedPersist6_PersistToEntity.class);
865            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
866            index.put((DeletedPersist6_PersistToEntity)
867                      newStore.getModel().convertRawObject(raw));
868        }
869
870        @Override
871        void readRawObjects(RawStore store,
872                            boolean expectEvolved,
873                            boolean expectUpdated)
874            throws DatabaseException {
875
876            if (expectEvolved) {
877                return;
878            }
879
880            RawType embedType = store.getModel().getRawType(NAME);
881            checkRawType(embedType, NAME, 0);
882
883            RawObject embed =
884                new RawObject(embedType, makeValues("f", 123), null);
885
886            RawObject obj = readRaw(store, 99, NAME2, 0, CASECLS, 0);
887            checkRawFields(obj, "key", 99, "embed", embed);
888        }
889    }
890
891    /**
892     * Disallow renaming an entity class without a Renamer mutation.
893     */
894    @Entity(version=1)
895    static class RenamedEntity1_NewEntityName_NoMutation
896        extends EvolveCase {
897
898        private static final String NAME =
899            PREFIX + "RenamedEntity1_NewEntityName";
900        private static final String NAME2 =
901            RenamedEntity1_NewEntityName_NoMutation.class.getName();
902
903        @PrimaryKey
904        int key = 99;
905
906        @SecondaryKey(relate=ONE_TO_ONE)
907        int skey = 88;
908
909        @Override
910        public String getStoreOpenException() {
911            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";
912        }
913
914        @Override
915        void checkUnevolvedModel(EntityModel model, Environment env) {
916            checkEntity(true, model, env, NAME, 0, "skey");
917            checkVersions(model, NAME, 0);
918        }
919
920        @Override
921        void readRawObjects(RawStore store,
922                            boolean expectEvolved,
923                            boolean expectUpdated)
924            throws DatabaseException {
925
926            if (expectEvolved) {
927                TestCase.fail();
928            }
929            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
930            checkRawFields(obj, "key", 99, "skey", 88);
931        }
932    }
933
934    /**
935     * Allow renaming an entity class with a Renamer mutation.
936     */
937    @Entity(version=1)
938    static class RenamedEntity2_NewEntityName_WithRenamer
939        extends EvolveCase {
940
941        private static final String NAME =
942            PREFIX + "RenamedEntity2_NewEntityName";
943        private static final String NAME2 =
944            RenamedEntity2_NewEntityName_WithRenamer.class.getName();
945
946        @PrimaryKey
947        int key = 99;
948
949        @SecondaryKey(relate=ONE_TO_ONE)
950        int skey = 88;
951
952        @Override
953        Mutations getMutations() {
954            Mutations m = new Mutations();
955            m.addRenamer(new Renamer(NAME, 0, NAME2));
956            return m;
957        }
958
959        @Override
960        void checkEvolvedModel(EntityModel model,
961                               Environment env,
962                               boolean oldTypesExist) {
963            checkEntity(false, model, env, NAME, 0, null);
964            checkEntity(true, model, env, NAME2, 1, null);
965            if (oldTypesExist) {
966                checkVersions(model, NAME2, 1, NAME, 0);
967            } else {
968                checkVersions(model, NAME2, 1);
969            }
970        }
971
972        @Override
973        void readObjects(EntityStore store, boolean doUpdate)
974            throws DatabaseException {
975
976            PrimaryIndex<Integer,RenamedEntity2_NewEntityName_WithRenamer>
977                index = store.getPrimaryIndex
978                    (Integer.class,
979                     RenamedEntity2_NewEntityName_WithRenamer.class);
980            RenamedEntity2_NewEntityName_WithRenamer obj = index.get(key);
981            TestCase.assertNotNull(obj);
982            TestCase.assertEquals(99, obj.key);
983            TestCase.assertEquals(88, obj.skey);
984
985            SecondaryIndex<Integer,Integer,
986                           RenamedEntity2_NewEntityName_WithRenamer>
987                sindex = store.getSecondaryIndex(index, Integer.class, "skey");
988            obj = sindex.get(88);
989            TestCase.assertNotNull(obj);
990            TestCase.assertEquals(99, obj.key);
991            TestCase.assertEquals(88, obj.skey);
992
993            if (doUpdate) {
994                index.put(obj);
995            }
996        }
997
998        @Override
999        void copyRawObjects(RawStore rawStore, EntityStore newStore)
1000            throws DatabaseException {
1001
1002            PrimaryIndex<Integer,RenamedEntity2_NewEntityName_WithRenamer>
1003                index = newStore.getPrimaryIndex
1004                    (Integer.class,
1005                     RenamedEntity2_NewEntityName_WithRenamer.class);
1006            RawObject raw = rawStore.getPrimaryIndex(NAME2).get(99);
1007            index.put((RenamedEntity2_NewEntityName_WithRenamer)
1008                      newStore.getModel().convertRawObject(raw));
1009        }
1010
1011        @Override
1012        void readRawObjects(RawStore store,
1013                            boolean expectEvolved,
1014                            boolean expectUpdated)
1015            throws DatabaseException {
1016
1017            RawObject obj;
1018            if (expectEvolved) {
1019                obj = readRaw(store, 99, NAME2, 1, CASECLS, 0);
1020            } else {
1021                obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1022            }
1023            checkRawFields(obj, "key", 99, "skey", 88);
1024        }
1025    }
1026
1027    @Persistent
1028    static class DeleteSuperclass1_BaseClass
1029        extends EvolveCase {
1030
1031        int f = 123;
1032    }
1033
1034    /**
1035     * Disallow deleting a superclass from the hierarchy when the superclass
1036     * has persistent fields and no Deleter or Converter is specified.
1037     */
1038    @Entity
1039    static class DeleteSuperclass1_NoMutation
1040        extends EvolveCase {
1041
1042        private static final String NAME =
1043            DeleteSuperclass1_BaseClass.class.getName();
1044        private static final String NAME2 =
1045            DeleteSuperclass1_NoMutation.class.getName();
1046
1047        @PrimaryKey
1048        int key = 99;
1049
1050        int ff;
1051
1052        @Override
1053        public String getStoreOpenException() {
1054            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";
1055        }
1056
1057        @Override
1058        void checkUnevolvedModel(EntityModel model, Environment env) {
1059            checkNonEntity(true, model, env, NAME, 0);
1060            checkEntity(true, model, env, NAME2, 0, null);
1061            checkVersions(model, NAME, 0);
1062            checkVersions(model, NAME2, 0);
1063        }
1064
1065        @Override
1066        void readRawObjects(RawStore store,
1067                            boolean expectEvolved,
1068                            boolean expectUpdated)
1069            throws DatabaseException {
1070
1071            if (expectEvolved) {
1072                TestCase.fail();
1073            }
1074            RawObject obj = readRaw(store, 99, NAME2, 0, NAME, 0, CASECLS, 0);
1075            checkRawFields(obj, "key", 99, "ff", 88);
1076            checkRawFields(obj.getSuper(), "f", 123);
1077            checkRawFields(obj.getSuper().getSuper());
1078        }
1079    }
1080
1081    @Persistent
1082    static class DeleteSuperclass2_BaseClass
1083        extends EvolveCase {
1084
1085        int f;
1086
1087        @SecondaryKey(relate=ONE_TO_ONE)
1088        int skey;
1089    }
1090
1091    /**
1092     * Allow deleting a superclass from the hierarchy when the superclass has
1093     * persistent fields and a class Converter is specified.  Also check that
1094     * the secondary key field in the deleted base class is handled properly.
1095     */
1096    @Entity(version=1)
1097    static class DeleteSuperclass2_WithConverter extends EvolveCase {
1098
1099        private static final String NAME =
1100            DeleteSuperclass2_BaseClass.class.getName();
1101        private static final String NAME2 =
1102            DeleteSuperclass2_WithConverter.class.getName();
1103
1104        @PrimaryKey
1105        int key;
1106
1107        int ff;
1108
1109        @SecondaryKey(relate=ONE_TO_ONE)
1110        Integer skey2;
1111
1112        @SecondaryKey(relate=ONE_TO_ONE)
1113        int skey3;
1114
1115        @Override
1116        Mutations getMutations() {
1117            Mutations m = new Mutations();
1118            m.addConverter(new EntityConverter
1119                (NAME2, 0, new MyConversion(),
1120                 Collections.singleton("skey")));
1121            return m;
1122        }
1123
1124        static class MyConversion implements Conversion {
1125
1126            transient RawType newType;
1127
1128            public void initialize(EntityModel model) {
1129                newType = model.getRawType(NAME2);
1130                TestCase.assertNotNull(newType);
1131            }
1132
1133            public Object convert(Object fromValue) {
1134                TestCase.assertNotNull(newType);
1135                RawObject obj = (RawObject) fromValue;
1136                RawObject newSuper = obj.getSuper().getSuper();
1137                return new RawObject(newType, obj.getValues(), newSuper);
1138            }
1139
1140            @Override
1141            public boolean equals(Object other) {
1142                return other instanceof MyConversion;
1143            }
1144        }
1145
1146        @Override
1147        void checkEvolvedModel(EntityModel model,
1148                               Environment env,
1149                               boolean oldTypesExist) {
1150            checkEntity(true, model, env, NAME2, 1, null);
1151            if (oldTypesExist) {
1152                checkVersions(model, NAME2, 1, NAME2, 0);
1153                checkNonEntity(true, model, env, NAME, 0);
1154                checkVersions(model, NAME, 0);
1155            } else {
1156                checkVersions(model, NAME2, 1);
1157            }
1158        }
1159
1160        @Override
1161        void readObjects(EntityStore store, boolean doUpdate)
1162            throws DatabaseException {
1163
1164            PrimaryIndex<Integer,DeleteSuperclass2_WithConverter>
1165                index = store.getPrimaryIndex
1166                    (Integer.class,
1167                     DeleteSuperclass2_WithConverter.class);
1168            DeleteSuperclass2_WithConverter obj = index.get(99);
1169            TestCase.assertNotNull(obj);
1170            TestCase.assertSame
1171                (EvolveCase.class, obj.getClass().getSuperclass());
1172            TestCase.assertEquals(99, obj.key);
1173            TestCase.assertEquals(88, obj.ff);
1174            TestCase.assertEquals(Integer.valueOf(77), obj.skey2);
1175            TestCase.assertEquals(66, obj.skey3);
1176            if (doUpdate) {
1177                index.put(obj);
1178            }
1179        }
1180
1181        @Override
1182        void copyRawObjects(RawStore rawStore, EntityStore newStore)
1183            throws DatabaseException {
1184
1185            PrimaryIndex<Integer,DeleteSuperclass2_WithConverter>
1186                index = newStore.getPrimaryIndex
1187                    (Integer.class,
1188                     DeleteSuperclass2_WithConverter.class);
1189            RawObject raw = rawStore.getPrimaryIndex(NAME2).get(99);
1190            index.put((DeleteSuperclass2_WithConverter)
1191                      newStore.getModel().convertRawObject(raw));
1192        }
1193
1194        @Override
1195        void readRawObjects(RawStore store,
1196                            boolean expectEvolved,
1197                            boolean expectUpdated)
1198            throws DatabaseException {
1199
1200            RawObject obj;
1201            if (expectEvolved) {
1202                obj = readRaw(store, 99, NAME2, 1, CASECLS, 0);
1203            } else {
1204                obj = readRaw(store, 99, NAME2, 0, NAME, 0, CASECLS, 0);
1205            }
1206            checkRawFields
1207                (obj, "key", 99, "ff", 88, "skey2", 77, "skey3", 66);
1208            if (expectEvolved) {
1209                checkRawFields(obj.getSuper());
1210            } else {
1211                checkRawFields(obj.getSuper(), "f", 123, "skey", 456);
1212                checkRawFields(obj.getSuper().getSuper());
1213            }
1214            Environment env = store.getEnvironment();
1215            assertDbExists(!expectEvolved, env, NAME2, "skey");
1216            assertDbExists(true, env, NAME2, "skey3");
1217        }
1218    }
1219
1220    static class DeleteSuperclass3_BaseClass
1221        extends EvolveCase {
1222
1223        int f;
1224
1225        @SecondaryKey(relate=ONE_TO_ONE)
1226        int skey;
1227    }
1228
1229    /**
1230     * Allow deleting a superclass from the hierarchy when the superclass
1231     * has persistent fields and a class Deleter is specified.  Also check that
1232     * the secondary key field in the deleted base class is handled properly.
1233     */
1234    @Entity(version=1)
1235    static class DeleteSuperclass3_WithDeleter extends EvolveCase {
1236
1237        private static final String NAME =
1238            DeleteSuperclass3_BaseClass.class.getName();
1239        private static final String NAME2 =
1240            DeleteSuperclass3_WithDeleter.class.getName();
1241
1242        @PrimaryKey
1243        int key;
1244
1245        int ff;
1246
1247        @Override
1248        Mutations getMutations() {
1249            Mutations m = new Mutations();
1250            m.addDeleter(new Deleter(NAME, 0));
1251            return m;
1252        }
1253
1254        @Override
1255        void checkEvolvedModel(EntityModel model,
1256                               Environment env,
1257                               boolean oldTypesExist) {
1258            checkEntity(true, model, env, NAME2, 1, null);
1259            if (oldTypesExist) {
1260                checkVersions(model, NAME2, 1, NAME2, 0);
1261                checkNonEntity(false, model, env, NAME, 0);
1262                checkVersions(model, NAME, 0);
1263            } else {
1264                checkVersions(model, NAME2, 1);
1265            }
1266        }
1267
1268        @Override
1269        void readObjects(EntityStore store, boolean doUpdate)
1270            throws DatabaseException {
1271
1272            PrimaryIndex<Integer,DeleteSuperclass3_WithDeleter>
1273                index = store.getPrimaryIndex
1274                    (Integer.class,
1275                     DeleteSuperclass3_WithDeleter.class);
1276            DeleteSuperclass3_WithDeleter obj = index.get(99);
1277            TestCase.assertNotNull(obj);
1278            TestCase.assertSame
1279                (EvolveCase.class, obj.getClass().getSuperclass());
1280            TestCase.assertEquals(99, obj.key);
1281            TestCase.assertEquals(88, obj.ff);
1282            if (doUpdate) {
1283                index.put(obj);
1284            }
1285        }
1286
1287        @Override
1288        void copyRawObjects(RawStore rawStore, EntityStore newStore)
1289            throws DatabaseException {
1290
1291            PrimaryIndex<Integer,DeleteSuperclass3_WithDeleter>
1292                index = newStore.getPrimaryIndex
1293                    (Integer.class,
1294                     DeleteSuperclass3_WithDeleter.class);
1295            RawObject raw = rawStore.getPrimaryIndex(NAME2).get(99);
1296            index.put((DeleteSuperclass3_WithDeleter)
1297                      newStore.getModel().convertRawObject(raw));
1298        }
1299
1300        @Override
1301        void readRawObjects(RawStore store,
1302                            boolean expectEvolved,
1303                            boolean expectUpdated)
1304            throws DatabaseException {
1305
1306            RawObject obj;
1307            if (expectEvolved) {
1308                obj = readRaw(store, 99, NAME2, 1, CASECLS, 0);
1309            } else {
1310                obj = readRaw(store, 99, NAME2, 0, NAME, 0, CASECLS, 0);
1311            }
1312            checkRawFields(obj, "key", 99, "ff", 88);
1313            if (expectEvolved) {
1314                checkRawFields(obj.getSuper());
1315            } else {
1316                checkRawFields(obj.getSuper(), "f", 123, "skey", 456);
1317                checkRawFields(obj.getSuper().getSuper());
1318            }
1319            Environment env = store.getEnvironment();
1320            assertDbExists(!expectEvolved, env, NAME2, "skey");
1321        }
1322    }
1323
1324    @Persistent
1325    static class DeleteSuperclass4_BaseClass
1326        extends EvolveCase {
1327    }
1328
1329    /**
1330     * Allow deleting a superclass from the hierarchy when the superclass
1331     * has NO persistent fields.  No mutations are needed.
1332     */
1333    @Entity(version=1)
1334    static class DeleteSuperclass4_NoFields extends EvolveCase {
1335
1336        private static final String NAME =
1337            DeleteSuperclass4_BaseClass.class.getName();
1338        private static final String NAME2 =
1339            DeleteSuperclass4_NoFields.class.getName();
1340
1341        @PrimaryKey
1342        int key = 99;
1343
1344        int ff;
1345
1346        @Override
1347        void checkEvolvedModel(EntityModel model,
1348                               Environment env,
1349                               boolean oldTypesExist) {
1350            checkEntity(true, model, env, NAME2, 1, null);
1351            if (oldTypesExist) {
1352                checkVersions(model, NAME2, 1, NAME2, 0);
1353                checkNonEntity(true, model, env, NAME, 0);
1354                checkVersions(model, NAME, 0);
1355            } else {
1356                checkVersions(model, NAME2, 1);
1357            }
1358        }
1359
1360        @Override
1361        void readObjects(EntityStore store, boolean doUpdate)
1362            throws DatabaseException {
1363
1364            PrimaryIndex<Integer,DeleteSuperclass4_NoFields>
1365                index = store.getPrimaryIndex
1366                    (Integer.class,
1367                     DeleteSuperclass4_NoFields.class);
1368            DeleteSuperclass4_NoFields obj = index.get(key);
1369            TestCase.assertNotNull(obj);
1370            TestCase.assertSame
1371                (EvolveCase.class, obj.getClass().getSuperclass());
1372            TestCase.assertEquals(99, obj.key);
1373            TestCase.assertEquals(88, obj.ff);
1374            if (doUpdate) {
1375                index.put(obj);
1376            }
1377        }
1378
1379        @Override
1380        void copyRawObjects(RawStore rawStore, EntityStore newStore)
1381            throws DatabaseException {
1382
1383            PrimaryIndex<Integer,DeleteSuperclass4_NoFields>
1384                index = newStore.getPrimaryIndex
1385                    (Integer.class,
1386                     DeleteSuperclass4_NoFields.class);
1387            RawObject raw = rawStore.getPrimaryIndex(NAME2).get(99);
1388            index.put((DeleteSuperclass4_NoFields)
1389                      newStore.getModel().convertRawObject(raw));
1390        }
1391
1392        @Override
1393        void readRawObjects(RawStore store,
1394                            boolean expectEvolved,
1395                            boolean expectUpdated)
1396            throws DatabaseException {
1397
1398            RawObject obj;
1399            if (expectEvolved) {
1400                obj = readRaw(store, 99, NAME2, 1, CASECLS, 0);
1401            } else {
1402                obj = readRaw(store, 99, NAME2, 0, NAME, 0, CASECLS, 0);
1403            }
1404            checkRawFields(obj, "key", 99, "ff", 88);
1405            checkRawFields(obj.getSuper());
1406            if (expectEvolved) {
1407                TestCase.assertNull(obj.getSuper().getSuper());
1408            } else {
1409                checkRawFields(obj.getSuper().getSuper());
1410            }
1411        }
1412    }
1413
1414    @Persistent(version=1)
1415    static class DeleteSuperclass5_Embedded {
1416
1417        int f;
1418
1419        @Override
1420        public String toString() {
1421            return "" + f;
1422        }
1423    }
1424
1425    /**
1426     * Ensure that a superclass at the top of the hierarchy can be deleted.  A
1427     * class Deleter is used.
1428     */
1429    @Entity
1430    static class DeleteSuperclass5_Top
1431        extends EvolveCase {
1432
1433        private static final String NAME =
1434            DeleteSuperclass5_Top.class.getName();
1435        private static final String NAME2 =
1436            DeleteSuperclass5_Embedded.class.getName();
1437        private static final String NAME3 =
1438            PREFIX + "DeleteSuperclass5_Embedded_Base";
1439
1440        @PrimaryKey
1441        int key = 99;
1442
1443        int ff;
1444
1445        DeleteSuperclass5_Embedded embed =
1446            new DeleteSuperclass5_Embedded();
1447
1448        @Override
1449        Mutations getMutations() {
1450            Mutations m = new Mutations();
1451            m.addDeleter(new Deleter(NAME3, 0));
1452            return m;
1453        }
1454
1455        @Override
1456        void checkEvolvedModel(EntityModel model,
1457                               Environment env,
1458                               boolean oldTypesExist) {
1459            checkEntity(true, model, env, NAME, 0, null);
1460            checkNonEntity(true, model, env, NAME2, 1);
1461            checkNonEntity(false, model, env, NAME3, 0);
1462            checkVersions(model, NAME, 0);
1463            if (oldTypesExist) {
1464                checkVersions(model, NAME2, 1, NAME2, 0);
1465                checkVersions(model, NAME3, 0);
1466            } else {
1467                checkVersions(model, NAME2, 1);
1468            }
1469        }
1470
1471        @Override
1472        void readObjects(EntityStore store, boolean doUpdate)
1473            throws DatabaseException {
1474
1475            PrimaryIndex<Integer,DeleteSuperclass5_Top>
1476                index = store.getPrimaryIndex
1477                    (Integer.class,
1478                     DeleteSuperclass5_Top.class);
1479            DeleteSuperclass5_Top obj = index.get(key);
1480            TestCase.assertNotNull(obj);
1481            TestCase.assertNotNull(obj.embed);
1482            TestCase.assertEquals(99, obj.key);
1483            TestCase.assertEquals(88, obj.ff);
1484            TestCase.assertEquals(123, obj.embed.f);
1485            if (doUpdate) {
1486                index.put(obj);
1487            }
1488        }
1489
1490        @Override
1491        void copyRawObjects(RawStore rawStore, EntityStore newStore)
1492            throws DatabaseException {
1493
1494            PrimaryIndex<Integer,DeleteSuperclass5_Top>
1495                index = newStore.getPrimaryIndex
1496                    (Integer.class,
1497                     DeleteSuperclass5_Top.class);
1498            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
1499            index.put((DeleteSuperclass5_Top)
1500                      newStore.getModel().convertRawObject(raw));
1501        }
1502
1503        @Override
1504        void readRawObjects(RawStore store,
1505                            boolean expectEvolved,
1506                            boolean expectUpdated)
1507            throws DatabaseException {
1508
1509            RawType embedType = store.getModel().getRawType(NAME2);
1510            RawObject embedSuper = null;
1511            if (!expectEvolved) {
1512                RawType embedSuperType = store.getModel().getRawType(NAME3);
1513                embedSuper = new RawObject
1514                    (embedSuperType, makeValues("g", 456), null);
1515            }
1516            RawObject embed =
1517                new RawObject(embedType, makeValues("f", 123), embedSuper);
1518            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1519            checkRawFields(obj, "key", 99, "ff", 88, "embed", embed);
1520        }
1521    }
1522
1523    @Persistent
1524    static class InsertSuperclass1_BaseClass
1525        extends EvolveCase {
1526
1527        int f = 123;
1528    }
1529
1530    /**
1531     * Allow inserting a superclass between two existing classes in the
1532     * hierarchy.  No mutations are needed.
1533     */
1534    @Entity(version=1)
1535    static class InsertSuperclass1_Between
1536        extends InsertSuperclass1_BaseClass {
1537
1538        private static final String NAME =
1539            InsertSuperclass1_BaseClass.class.getName();
1540        private static final String NAME2 =
1541            InsertSuperclass1_Between.class.getName();
1542
1543        @PrimaryKey
1544        int key = 99;
1545
1546        int ff;
1547
1548        @Override
1549        void checkEvolvedModel(EntityModel model,
1550                               Environment env,
1551                               boolean oldTypesExist) {
1552            checkNonEntity(true, model, env, NAME, 0);
1553            checkEntity(true, model, env, NAME2, 1, null);
1554            checkVersions(model, NAME, 0);
1555            if (oldTypesExist) {
1556                checkVersions(model, NAME2, 1, NAME2, 0);
1557            } else {
1558                checkVersions(model, NAME2, 1);
1559            }
1560        }
1561
1562        @Override
1563        void readObjects(EntityStore store, boolean doUpdate)
1564            throws DatabaseException {
1565
1566            PrimaryIndex<Integer,InsertSuperclass1_Between>
1567                index = store.getPrimaryIndex
1568                    (Integer.class,
1569                     InsertSuperclass1_Between.class);
1570            InsertSuperclass1_Between obj = index.get(key);
1571            TestCase.assertNotNull(obj);
1572            TestCase.assertSame
1573                (InsertSuperclass1_BaseClass.class,
1574                 obj.getClass().getSuperclass());
1575            TestCase.assertSame
1576                (EvolveCase.class,
1577                 obj.getClass().getSuperclass().getSuperclass());
1578            TestCase.assertEquals(99, obj.key);
1579            TestCase.assertEquals(88, obj.ff);
1580            TestCase.assertEquals(123, obj.f);
1581            if (doUpdate) {
1582                index.put(obj);
1583            }
1584        }
1585
1586        @Override
1587        void copyRawObjects(RawStore rawStore, EntityStore newStore)
1588            throws DatabaseException {
1589
1590            PrimaryIndex<Integer,InsertSuperclass1_Between>
1591                index = newStore.getPrimaryIndex
1592                    (Integer.class,
1593                     InsertSuperclass1_Between.class);
1594            RawObject raw = rawStore.getPrimaryIndex(NAME2).get(99);
1595            index.put((InsertSuperclass1_Between)
1596                      newStore.getModel().convertRawObject(raw));
1597        }
1598
1599        @Override
1600        void readRawObjects(RawStore store,
1601                            boolean expectEvolved,
1602                            boolean expectUpdated)
1603            throws DatabaseException {
1604
1605            RawObject obj;
1606            if (expectEvolved) {
1607                obj = readRaw(store, 99, NAME2, 1, NAME, 0, CASECLS, 0);
1608            } else {
1609                obj = readRaw(store, 99, NAME2, 0, CASECLS, 0);
1610            }
1611            checkRawFields(obj, "key", 99, "ff", 88);
1612            if (expectEvolved) {
1613                if (expectUpdated) {
1614                    checkRawFields(obj.getSuper(), "f", 123);
1615                } else {
1616                    checkRawFields(obj.getSuper());
1617                }
1618                checkRawFields(obj.getSuper().getSuper());
1619                TestCase.assertNull(obj.getSuper().getSuper().getSuper());
1620            } else {
1621                checkRawFields(obj.getSuper());
1622                TestCase.assertNull(obj.getSuper().getSuper());
1623            }
1624        }
1625    }
1626
1627    @Persistent
1628    static class InsertSuperclass2_Embedded_Base {
1629
1630        int g = 456;
1631    }
1632
1633    @Persistent(version=1)
1634    static class InsertSuperclass2_Embedded
1635        extends InsertSuperclass2_Embedded_Base  {
1636
1637        int f;
1638    }
1639
1640    /**
1641     * Allow inserting a superclass at the top of the hierarchy.  No mutations
1642     * are needed.
1643     */
1644    @Entity
1645    static class InsertSuperclass2_Top
1646        extends EvolveCase {
1647
1648        private static final String NAME =
1649            InsertSuperclass2_Top.class.getName();
1650        private static final String NAME2 =
1651            InsertSuperclass2_Embedded.class.getName();
1652        private static final String NAME3 =
1653            InsertSuperclass2_Embedded_Base.class.getName();
1654
1655        @PrimaryKey
1656        int key = 99;
1657
1658        int ff;
1659
1660        InsertSuperclass2_Embedded embed =
1661            new InsertSuperclass2_Embedded();
1662
1663        @Override
1664        void checkEvolvedModel(EntityModel model,
1665                               Environment env,
1666                               boolean oldTypesExist) {
1667            checkEntity(true, model, env, NAME, 0, null);
1668            checkNonEntity(true, model, env, NAME2, 1);
1669            checkNonEntity(true, model, env, NAME3, 0);
1670            checkVersions(model, NAME, 0);
1671            if (oldTypesExist) {
1672                checkVersions(model, NAME2, 1, NAME2, 0);
1673            } else {
1674                checkVersions(model, NAME2, 1);
1675            }
1676            checkVersions(model, NAME3, 0);
1677        }
1678
1679        @Override
1680        void readObjects(EntityStore store, boolean doUpdate)
1681            throws DatabaseException {
1682
1683            PrimaryIndex<Integer,InsertSuperclass2_Top>
1684                index = store.getPrimaryIndex
1685                    (Integer.class,
1686                     InsertSuperclass2_Top.class);
1687            InsertSuperclass2_Top obj = index.get(key);
1688            TestCase.assertNotNull(obj);
1689            TestCase.assertNotNull(obj.embed);
1690            TestCase.assertEquals(99, obj.key);
1691            TestCase.assertEquals(88, obj.ff);
1692            TestCase.assertEquals(123, obj.embed.f);
1693            TestCase.assertEquals(456, obj.embed.g);
1694            if (doUpdate) {
1695                index.put(obj);
1696            }
1697        }
1698
1699        @Override
1700        void copyRawObjects(RawStore rawStore, EntityStore newStore)
1701            throws DatabaseException {
1702
1703            PrimaryIndex<Integer,InsertSuperclass2_Top>
1704                index = newStore.getPrimaryIndex
1705                    (Integer.class,
1706                     InsertSuperclass2_Top.class);
1707            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
1708            index.put((InsertSuperclass2_Top)
1709                      newStore.getModel().convertRawObject(raw));
1710        }
1711
1712        @Override
1713        void readRawObjects(RawStore store,
1714                            boolean expectEvolved,
1715                            boolean expectUpdated)
1716            throws DatabaseException {
1717
1718            RawType embedType = store.getModel().getRawType(NAME2);
1719            RawObject embedSuper = null;
1720            if (expectEvolved) {
1721                RawType embedSuperType = store.getModel().getRawType(NAME3);
1722                Map<String,Object> values =
1723                    expectUpdated ? makeValues("g", 456) : makeValues();
1724                embedSuper = new RawObject(embedSuperType, values, null);
1725            }
1726            RawObject embed =
1727                new RawObject(embedType, makeValues("f", 123), embedSuper);
1728            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1729            checkRawFields(obj, "key", 99, "ff", 88, "embed", embed);
1730        }
1731    }
1732
1733    @Entity(version=1)
1734    static class DisallowNonKeyField_PrimitiveToObject
1735        extends EvolveCase {
1736
1737        private static final String NAME =
1738            DisallowNonKeyField_PrimitiveToObject.class.getName();
1739
1740        @PrimaryKey
1741        int key = 99;
1742
1743        String ff;
1744
1745        @Override
1746        public String getStoreOpenException() {
1747            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";
1748        }
1749
1750        @Override
1751        void checkUnevolvedModel(EntityModel model, Environment env) {
1752            checkEntity(true, model, env, NAME, 0, null);
1753            checkVersions(model, NAME, 0);
1754        }
1755
1756        @Override
1757        void readRawObjects(RawStore store,
1758                            boolean expectEvolved,
1759                            boolean expectUpdated)
1760            throws DatabaseException {
1761
1762            if (expectEvolved) {
1763                TestCase.fail();
1764            }
1765            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1766            checkRawFields(obj, "key", 99, "ff", 88);
1767        }
1768    }
1769
1770    @Entity(version=1)
1771    static class DisallowNonKeyField_ObjectToPrimitive
1772        extends EvolveCase {
1773
1774        private static final String NAME =
1775            DisallowNonKeyField_ObjectToPrimitive.class.getName();
1776
1777        @PrimaryKey
1778        int key = 99;
1779
1780        int ff;
1781
1782        @Override
1783        public String getStoreOpenException() {
1784            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";
1785        }
1786
1787        @Override
1788        void checkUnevolvedModel(EntityModel model, Environment env) {
1789            checkEntity(true, model, env, NAME, 0, null);
1790            checkVersions(model, NAME, 0);
1791        }
1792
1793        @Override
1794        void readRawObjects(RawStore store,
1795                            boolean expectEvolved,
1796                            boolean expectUpdated)
1797            throws DatabaseException {
1798
1799            if (expectEvolved) {
1800                TestCase.fail();
1801            }
1802            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1803            checkRawFields(obj, "key", 99, "ff", "88");
1804        }
1805    }
1806
1807    @Persistent
1808    static class MyType {
1809
1810        @Override
1811        public boolean equals(Object o) {
1812            return o instanceof MyType;
1813        }
1814    }
1815
1816    @Persistent
1817    static class MySubtype extends MyType {
1818
1819        @Override
1820        public boolean equals(Object o) {
1821            return o instanceof MySubtype;
1822        }
1823    }
1824
1825    @Entity(version=1)
1826    static class DisallowNonKeyField_ObjectToSubtype
1827        extends EvolveCase {
1828
1829        private static final String NAME =
1830            DisallowNonKeyField_ObjectToSubtype.class.getName();
1831
1832        @PrimaryKey
1833        int key = 99;
1834
1835        MySubtype ff;
1836
1837        @Override
1838        public String getStoreOpenException() {
1839            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";
1840        }
1841
1842        @Override
1843        void checkUnevolvedModel(EntityModel model, Environment env) {
1844            checkEntity(true, model, env, NAME, 0, null);
1845            checkVersions(model, NAME, 0);
1846        }
1847
1848        @Override
1849        void readRawObjects(RawStore store,
1850                            boolean expectEvolved,
1851                            boolean expectUpdated)
1852            throws DatabaseException {
1853
1854            if (expectEvolved) {
1855                TestCase.fail();
1856            }
1857            RawType embedType = store.getModel().getRawType
1858                (MyType.class.getName());
1859            RawObject embed = new RawObject(embedType, makeValues(), null);
1860
1861            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1862            checkRawFields(obj, "key", 99, "ff", embed);
1863        }
1864    }
1865
1866    @Entity(version=1)
1867    static class DisallowNonKeyField_ObjectToUnrelatedSimple
1868        extends EvolveCase {
1869
1870        private static final String NAME =
1871            DisallowNonKeyField_ObjectToUnrelatedSimple.class.getName();
1872
1873        @PrimaryKey
1874        int key = 99;
1875
1876        String ff;
1877
1878        @Override
1879        public String getStoreOpenException() {
1880            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";
1881        }
1882
1883        @Override
1884        void checkUnevolvedModel(EntityModel model, Environment env) {
1885            checkEntity(true, model, env, NAME, 0, null);
1886            checkVersions(model, NAME, 0);
1887        }
1888
1889        @Override
1890        void readRawObjects(RawStore store,
1891                            boolean expectEvolved,
1892                            boolean expectUpdated)
1893            throws DatabaseException {
1894
1895            if (expectEvolved) {
1896                TestCase.fail();
1897            }
1898            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1899            checkRawFields(obj, "key", 99, "ff", 88);
1900        }
1901    }
1902
1903    @Entity(version=1)
1904    static class DisallowNonKeyField_ObjectToUnrelatedOther
1905        extends EvolveCase {
1906
1907        private static final String NAME =
1908            DisallowNonKeyField_ObjectToUnrelatedOther.class.getName();
1909
1910        @PrimaryKey
1911        int key = 99;
1912
1913        MyType ff;
1914
1915        @Override
1916        public String getStoreOpenException() {
1917            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";
1918        }
1919
1920        @Override
1921        void checkUnevolvedModel(EntityModel model, Environment env) {
1922            checkEntity(true, model, env, NAME, 0, null);
1923            checkVersions(model, NAME, 0);
1924        }
1925
1926        @Override
1927        void readRawObjects(RawStore store,
1928                            boolean expectEvolved,
1929                            boolean expectUpdated)
1930            throws DatabaseException {
1931
1932            if (expectEvolved) {
1933                TestCase.fail();
1934            }
1935            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1936            checkRawFields(obj, "key", 99, "ff", 88);
1937        }
1938    }
1939
1940    @Entity(version=1)
1941    static class DisallowNonKeyField_byte2boolean
1942        extends EvolveCase {
1943
1944        private static final String NAME =
1945            DisallowNonKeyField_byte2boolean.class.getName();
1946
1947        @PrimaryKey
1948        int key = 99;
1949
1950        boolean ff;
1951
1952        @Override
1953        public String getStoreOpenException() {
1954            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";
1955        }
1956
1957        @Override
1958        void checkUnevolvedModel(EntityModel model, Environment env) {
1959            checkEntity(true, model, env, NAME, 0, null);
1960            checkVersions(model, NAME, 0);
1961        }
1962
1963        @Override
1964        void readRawObjects(RawStore store,
1965                            boolean expectEvolved,
1966                            boolean expectUpdated)
1967            throws DatabaseException {
1968
1969            if (expectEvolved) {
1970                TestCase.fail();
1971            }
1972            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
1973            checkRawFields(obj, "key", 99, "ff", (byte) 88);
1974        }
1975    }
1976
1977    @Entity(version=1)
1978    static class DisallowNonKeyField_short2byte
1979        extends EvolveCase {
1980
1981        private static final String NAME =
1982            DisallowNonKeyField_short2byte.class.getName();
1983
1984        @PrimaryKey
1985        int key = 99;
1986
1987        byte ff;
1988
1989        @Override
1990        public String getStoreOpenException() {
1991            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";
1992        }
1993
1994        @Override
1995        void checkUnevolvedModel(EntityModel model, Environment env) {
1996            checkEntity(true, model, env, NAME, 0, null);
1997            checkVersions(model, NAME, 0);
1998        }
1999
2000        @Override
2001        void readRawObjects(RawStore store,
2002                            boolean expectEvolved,
2003                            boolean expectUpdated)
2004            throws DatabaseException {
2005
2006            if (expectEvolved) {
2007                TestCase.fail();
2008            }
2009            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2010            checkRawFields(obj, "key", 99, "ff", (short) 88);
2011        }
2012    }
2013
2014    @Entity(version=1)
2015    static class DisallowNonKeyField_int2short
2016        extends EvolveCase {
2017
2018        private static final String NAME =
2019            DisallowNonKeyField_int2short.class.getName();
2020
2021        @PrimaryKey
2022        int key = 99;
2023
2024        short ff;
2025
2026        @Override
2027        public String getStoreOpenException() {
2028            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";
2029        }
2030
2031        @Override
2032        void checkUnevolvedModel(EntityModel model, Environment env) {
2033            checkEntity(true, model, env, NAME, 0, null);
2034            checkVersions(model, NAME, 0);
2035        }
2036
2037        @Override
2038        void readRawObjects(RawStore store,
2039                            boolean expectEvolved,
2040                            boolean expectUpdated)
2041            throws DatabaseException {
2042
2043            if (expectEvolved) {
2044                TestCase.fail();
2045            }
2046            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2047            checkRawFields(obj, "key", 99, "ff", (int) 88);
2048        }
2049    }
2050
2051    @Entity(version=1)
2052    static class DisallowNonKeyField_long2int
2053        extends EvolveCase {
2054
2055        private static final String NAME =
2056            DisallowNonKeyField_long2int.class.getName();
2057
2058        @PrimaryKey
2059        int key = 99;
2060
2061        int ff;
2062
2063        @Override
2064        public String getStoreOpenException() {
2065            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";
2066        }
2067
2068        @Override
2069        void checkUnevolvedModel(EntityModel model, Environment env) {
2070            checkEntity(true, model, env, NAME, 0, null);
2071            checkVersions(model, NAME, 0);
2072        }
2073
2074        @Override
2075        void readRawObjects(RawStore store,
2076                            boolean expectEvolved,
2077                            boolean expectUpdated)
2078            throws DatabaseException {
2079
2080            if (expectEvolved) {
2081                TestCase.fail();
2082            }
2083            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2084            checkRawFields(obj, "key", 99, "ff", (long) 88);
2085        }
2086    }
2087
2088    @Entity(version=1)
2089    static class DisallowNonKeyField_float2long
2090        extends EvolveCase {
2091
2092        private static final String NAME =
2093            DisallowNonKeyField_float2long.class.getName();
2094
2095        @PrimaryKey
2096        int key = 99;
2097
2098        long ff;
2099
2100        @Override
2101        public String getStoreOpenException() {
2102            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";
2103        }
2104
2105        @Override
2106        void checkUnevolvedModel(EntityModel model, Environment env) {
2107            checkEntity(true, model, env, NAME, 0, null);
2108            checkVersions(model, NAME, 0);
2109        }
2110
2111        @Override
2112        void readRawObjects(RawStore store,
2113                            boolean expectEvolved,
2114                            boolean expectUpdated)
2115            throws DatabaseException {
2116
2117            if (expectEvolved) {
2118                TestCase.fail();
2119            }
2120            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2121            checkRawFields(obj, "key", 99, "ff", (float) 88);
2122        }
2123    }
2124
2125    @Entity(version=1)
2126    static class DisallowNonKeyField_double2float
2127        extends EvolveCase {
2128
2129        private static final String NAME =
2130            DisallowNonKeyField_double2float.class.getName();
2131
2132        @PrimaryKey
2133        int key = 99;
2134
2135        float ff;
2136
2137        @Override
2138        public String getStoreOpenException() {
2139            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";
2140        }
2141
2142        @Override
2143        void checkUnevolvedModel(EntityModel model, Environment env) {
2144            checkEntity(true, model, env, NAME, 0, null);
2145            checkVersions(model, NAME, 0);
2146        }
2147
2148        @Override
2149        void readRawObjects(RawStore store,
2150                            boolean expectEvolved,
2151                            boolean expectUpdated)
2152            throws DatabaseException {
2153
2154            if (expectEvolved) {
2155                TestCase.fail();
2156            }
2157            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2158            checkRawFields(obj, "key", 99, "ff", (double) 88);
2159        }
2160    }
2161
2162    @Entity(version=1)
2163    static class DisallowNonKeyField_Byte2byte
2164        extends EvolveCase {
2165
2166        private static final String NAME =
2167            DisallowNonKeyField_Byte2byte.class.getName();
2168
2169        @PrimaryKey
2170        int key = 99;
2171
2172        byte ff;
2173
2174        @Override
2175        public String getStoreOpenException() {
2176            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";
2177        }
2178
2179        @Override
2180        void checkUnevolvedModel(EntityModel model, Environment env) {
2181            checkEntity(true, model, env, NAME, 0, null);
2182            checkVersions(model, NAME, 0);
2183        }
2184
2185        @Override
2186        void readRawObjects(RawStore store,
2187                            boolean expectEvolved,
2188                            boolean expectUpdated)
2189            throws DatabaseException {
2190
2191            if (expectEvolved) {
2192                TestCase.fail();
2193            }
2194            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2195            checkRawFields(obj, "key", 99, "ff", (byte) 88);
2196        }
2197    }
2198
2199    @Entity(version=1)
2200    static class DisallowNonKeyField_Character2char
2201        extends EvolveCase {
2202
2203        private static final String NAME =
2204            DisallowNonKeyField_Character2char.class.getName();
2205
2206        @PrimaryKey
2207        int key = 99;
2208
2209        char ff;
2210
2211        @Override
2212        public String getStoreOpenException() {
2213            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";
2214        }
2215
2216        @Override
2217        void checkUnevolvedModel(EntityModel model, Environment env) {
2218            checkEntity(true, model, env, NAME, 0, null);
2219            checkVersions(model, NAME, 0);
2220        }
2221
2222        @Override
2223        void readRawObjects(RawStore store,
2224                            boolean expectEvolved,
2225                            boolean expectUpdated)
2226            throws DatabaseException {
2227
2228            if (expectEvolved) {
2229                TestCase.fail();
2230            }
2231            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2232            checkRawFields(obj, "key", 99, "ff", (char) 88);
2233        }
2234    }
2235
2236    @Entity(version=1)
2237    static class DisallowNonKeyField_Short2short
2238        extends EvolveCase {
2239
2240        private static final String NAME =
2241            DisallowNonKeyField_Short2short.class.getName();
2242
2243        @PrimaryKey
2244        int key = 99;
2245
2246        short ff;
2247
2248        @Override
2249        public String getStoreOpenException() {
2250            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";
2251        }
2252
2253        @Override
2254        void checkUnevolvedModel(EntityModel model, Environment env) {
2255            checkEntity(true, model, env, NAME, 0, null);
2256            checkVersions(model, NAME, 0);
2257        }
2258
2259        @Override
2260        void readRawObjects(RawStore store,
2261                            boolean expectEvolved,
2262                            boolean expectUpdated)
2263            throws DatabaseException {
2264
2265            if (expectEvolved) {
2266                TestCase.fail();
2267            }
2268            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2269            checkRawFields(obj, "key", 99, "ff", (short) 88);
2270        }
2271    }
2272
2273    @Entity(version=1)
2274    static class DisallowNonKeyField_Integer2int
2275        extends EvolveCase {
2276
2277        private static final String NAME =
2278            DisallowNonKeyField_Integer2int.class.getName();
2279
2280        @PrimaryKey
2281        int key = 99;
2282
2283        int ff;
2284
2285        @Override
2286        public String getStoreOpenException() {
2287            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";
2288        }
2289
2290        @Override
2291        void checkUnevolvedModel(EntityModel model, Environment env) {
2292            checkEntity(true, model, env, NAME, 0, null);
2293            checkVersions(model, NAME, 0);
2294        }
2295
2296        @Override
2297        void readRawObjects(RawStore store,
2298                            boolean expectEvolved,
2299                            boolean expectUpdated)
2300            throws DatabaseException {
2301
2302            if (expectEvolved) {
2303                TestCase.fail();
2304            }
2305            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2306            checkRawFields(obj, "key", 99, "ff", (int) 88);
2307        }
2308    }
2309
2310    @Entity(version=1)
2311    static class DisallowNonKeyField_Long2long
2312        extends EvolveCase {
2313
2314        private static final String NAME =
2315            DisallowNonKeyField_Long2long.class.getName();
2316
2317        @PrimaryKey
2318        int key = 99;
2319
2320        long ff;
2321
2322        @Override
2323        public String getStoreOpenException() {
2324            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";
2325        }
2326
2327        @Override
2328        void checkUnevolvedModel(EntityModel model, Environment env) {
2329            checkEntity(true, model, env, NAME, 0, null);
2330            checkVersions(model, NAME, 0);
2331        }
2332
2333        @Override
2334        void readRawObjects(RawStore store,
2335                            boolean expectEvolved,
2336                            boolean expectUpdated)
2337            throws DatabaseException {
2338
2339            if (expectEvolved) {
2340                TestCase.fail();
2341            }
2342            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2343            checkRawFields(obj, "key", 99, "ff", (long) 88);
2344        }
2345    }
2346
2347    @Entity(version=1)
2348    static class DisallowNonKeyField_Float2float
2349        extends EvolveCase {
2350
2351        private static final String NAME =
2352            DisallowNonKeyField_Float2float.class.getName();
2353
2354        @PrimaryKey
2355        int key = 99;
2356
2357        float ff;
2358
2359        @Override
2360        public String getStoreOpenException() {
2361            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";
2362        }
2363
2364        @Override
2365        void checkUnevolvedModel(EntityModel model, Environment env) {
2366            checkEntity(true, model, env, NAME, 0, null);
2367            checkVersions(model, NAME, 0);
2368        }
2369
2370        @Override
2371        void readRawObjects(RawStore store,
2372                            boolean expectEvolved,
2373                            boolean expectUpdated)
2374            throws DatabaseException {
2375
2376            if (expectEvolved) {
2377                TestCase.fail();
2378            }
2379            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2380            checkRawFields(obj, "key", 99, "ff", (float) 88);
2381        }
2382    }
2383
2384    @Entity(version=1)
2385    static class DisallowNonKeyField_Double2double
2386        extends EvolveCase {
2387
2388        private static final String NAME =
2389            DisallowNonKeyField_Double2double.class.getName();
2390
2391        @PrimaryKey
2392        int key = 99;
2393
2394        double ff;
2395
2396        @Override
2397        public String getStoreOpenException() {
2398            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";
2399        }
2400
2401        @Override
2402        void checkUnevolvedModel(EntityModel model, Environment env) {
2403            checkEntity(true, model, env, NAME, 0, null);
2404            checkVersions(model, NAME, 0);
2405        }
2406
2407        @Override
2408        void readRawObjects(RawStore store,
2409                            boolean expectEvolved,
2410                            boolean expectUpdated)
2411            throws DatabaseException {
2412
2413            if (expectEvolved) {
2414                TestCase.fail();
2415            }
2416            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2417            checkRawFields(obj, "key", 99, "ff", (double) 88);
2418        }
2419    }
2420
2421    @Entity(version=1)
2422    static class DisallowNonKeyField_float2BigInt
2423        extends EvolveCase {
2424
2425        private static final String NAME =
2426            DisallowNonKeyField_float2BigInt.class.getName();
2427
2428        @PrimaryKey
2429        int key = 99;
2430
2431        BigInteger ff;
2432
2433        @Override
2434        public String getStoreOpenException() {
2435            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";
2436        }
2437
2438        @Override
2439        void checkUnevolvedModel(EntityModel model, Environment env) {
2440            checkEntity(true, model, env, NAME, 0, null);
2441            checkVersions(model, NAME, 0);
2442        }
2443
2444        @Override
2445        void readRawObjects(RawStore store,
2446                            boolean expectEvolved,
2447                            boolean expectUpdated)
2448            throws DatabaseException {
2449
2450            if (expectEvolved) {
2451                TestCase.fail();
2452            }
2453            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2454            checkRawFields(obj, "key", 99, "ff", (float) 88);
2455        }
2456    }
2457
2458    @Entity(version=1)
2459    static class DisallowNonKeyField_BigInt2long
2460        extends EvolveCase {
2461
2462        private static final String NAME =
2463            DisallowNonKeyField_BigInt2long.class.getName();
2464
2465        @PrimaryKey
2466        int key = 99;
2467
2468        long ff;
2469
2470        @Override
2471        public String getStoreOpenException() {
2472            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";
2473        }
2474
2475        @Override
2476        void checkUnevolvedModel(EntityModel model, Environment env) {
2477            checkEntity(true, model, env, NAME, 0, null);
2478            checkVersions(model, NAME, 0);
2479        }
2480
2481        @Override
2482        void readRawObjects(RawStore store,
2483                            boolean expectEvolved,
2484                            boolean expectUpdated)
2485            throws DatabaseException {
2486
2487            if (expectEvolved) {
2488                TestCase.fail();
2489            }
2490            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2491            checkRawFields(obj, "key", 99, "ff", BigInteger.valueOf(88));
2492        }
2493    }
2494
2495    @Entity(version=1)
2496    static class DisallowSecKeyField_byte2short
2497        extends EvolveCase {
2498
2499        private static final String NAME =
2500            DisallowSecKeyField_byte2short.class.getName();
2501
2502        @PrimaryKey
2503        int key = 99;
2504
2505        @SecondaryKey(relate=ONE_TO_ONE)
2506        short ff;
2507
2508        @Override
2509        public String getStoreOpenException() {
2510            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";
2511        }
2512
2513        @Override
2514        void checkUnevolvedModel(EntityModel model, Environment env) {
2515            checkEntity(true, model, env, NAME, 0, "ff");
2516            checkVersions(model, NAME, 0);
2517        }
2518
2519        @Override
2520        void readRawObjects(RawStore store,
2521                            boolean expectEvolved,
2522                            boolean expectUpdated)
2523            throws DatabaseException {
2524
2525            if (expectEvolved) {
2526                TestCase.fail();
2527            }
2528            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2529            checkRawFields(obj, "key", 99, "ff", (byte) 88);
2530        }
2531    }
2532
2533    @Entity(version=1)
2534    static class DisallowSecKeyField_char2int
2535        extends EvolveCase {
2536
2537        private static final String NAME =
2538            DisallowSecKeyField_char2int.class.getName();
2539
2540        @PrimaryKey
2541        int key = 99;
2542
2543        @SecondaryKey(relate=ONE_TO_ONE)
2544        int ff;
2545
2546        @Override
2547        public String getStoreOpenException() {
2548            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";
2549        }
2550
2551        @Override
2552        void checkUnevolvedModel(EntityModel model, Environment env) {
2553            checkEntity(true, model, env, NAME, 0, "ff");
2554            checkVersions(model, NAME, 0);
2555        }
2556
2557        @Override
2558        void readRawObjects(RawStore store,
2559                            boolean expectEvolved,
2560                            boolean expectUpdated)
2561            throws DatabaseException {
2562
2563            if (expectEvolved) {
2564                TestCase.fail();
2565            }
2566            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2567            checkRawFields(obj, "key", 99, "ff", (char) 88);
2568        }
2569    }
2570
2571    @Entity(version=1)
2572    static class DisallowSecKeyField_short2int
2573        extends EvolveCase {
2574
2575        private static final String NAME =
2576            DisallowSecKeyField_short2int.class.getName();
2577
2578        @PrimaryKey
2579        int key = 99;
2580
2581        @SecondaryKey(relate=ONE_TO_ONE)
2582        int ff;
2583
2584        @Override
2585        public String getStoreOpenException() {
2586            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";
2587        }
2588
2589        @Override
2590        void checkUnevolvedModel(EntityModel model, Environment env) {
2591            checkEntity(true, model, env, NAME, 0, "ff");
2592            checkVersions(model, NAME, 0);
2593        }
2594
2595        @Override
2596        void readRawObjects(RawStore store,
2597                            boolean expectEvolved,
2598                            boolean expectUpdated)
2599            throws DatabaseException {
2600
2601            if (expectEvolved) {
2602                TestCase.fail();
2603            }
2604            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2605            checkRawFields(obj, "key", 99, "ff", (short) 88);
2606        }
2607    }
2608
2609    @Entity(version=1)
2610    static class DisallowSecKeyField_int2long
2611        extends EvolveCase {
2612
2613        private static final String NAME =
2614            DisallowSecKeyField_int2long.class.getName();
2615
2616        @PrimaryKey
2617        int key = 99;
2618
2619        @SecondaryKey(relate=ONE_TO_ONE)
2620        long ff;
2621
2622        @Override
2623        public String getStoreOpenException() {
2624            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";
2625        }
2626
2627        @Override
2628        void checkUnevolvedModel(EntityModel model, Environment env) {
2629            checkEntity(true, model, env, NAME, 0, "ff");
2630            checkVersions(model, NAME, 0);
2631        }
2632
2633        @Override
2634        void readRawObjects(RawStore store,
2635                            boolean expectEvolved,
2636                            boolean expectUpdated)
2637            throws DatabaseException {
2638
2639            if (expectEvolved) {
2640                TestCase.fail();
2641            }
2642            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2643            checkRawFields(obj, "key", 99, "ff", (int) 88);
2644        }
2645    }
2646
2647    @Entity(version=1)
2648    static class DisallowSecKeyField_long2float
2649        extends EvolveCase {
2650
2651        private static final String NAME =
2652            DisallowSecKeyField_long2float.class.getName();
2653
2654        @PrimaryKey
2655        int key = 99;
2656
2657        @SecondaryKey(relate=ONE_TO_ONE)
2658        float ff;
2659
2660        @Override
2661        public String getStoreOpenException() {
2662            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";
2663        }
2664
2665        @Override
2666        void checkUnevolvedModel(EntityModel model, Environment env) {
2667            checkEntity(true, model, env, NAME, 0, "ff");
2668            checkVersions(model, NAME, 0);
2669        }
2670
2671        @Override
2672        void readRawObjects(RawStore store,
2673                            boolean expectEvolved,
2674                            boolean expectUpdated)
2675            throws DatabaseException {
2676
2677            if (expectEvolved) {
2678                TestCase.fail();
2679            }
2680            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2681            checkRawFields(obj, "key", 99, "ff", (long) 88);
2682        }
2683    }
2684
2685    @Entity(version=1)
2686    static class DisallowSecKeyField_float2double
2687        extends EvolveCase {
2688
2689        private static final String NAME =
2690            DisallowSecKeyField_float2double.class.getName();
2691
2692        @PrimaryKey
2693        int key = 99;
2694
2695        @SecondaryKey(relate=ONE_TO_ONE)
2696        double ff;
2697
2698        @Override
2699        public String getStoreOpenException() {
2700            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";
2701        }
2702
2703        @Override
2704        void checkUnevolvedModel(EntityModel model, Environment env) {
2705            checkEntity(true, model, env, NAME, 0, "ff");
2706            checkVersions(model, NAME, 0);
2707        }
2708
2709        @Override
2710        void readRawObjects(RawStore store,
2711                            boolean expectEvolved,
2712                            boolean expectUpdated)
2713            throws DatabaseException {
2714
2715            if (expectEvolved) {
2716                TestCase.fail();
2717            }
2718            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2719            checkRawFields(obj, "key", 99, "ff", (float) 88);
2720        }
2721    }
2722
2723    @Entity(version=1)
2724    static class DisallowSecKeyField_Byte2short2
2725        extends EvolveCase {
2726
2727        private static final String NAME =
2728            DisallowSecKeyField_Byte2short2.class.getName();
2729
2730        @PrimaryKey
2731        int key = 99;
2732
2733        @SecondaryKey(relate=ONE_TO_ONE)
2734        short ff;
2735
2736        @Override
2737        public String getStoreOpenException() {
2738            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";
2739        }
2740
2741        @Override
2742        void checkUnevolvedModel(EntityModel model, Environment env) {
2743            checkEntity(true, model, env, NAME, 0, "ff");
2744            checkVersions(model, NAME, 0);
2745        }
2746
2747        @Override
2748        void readRawObjects(RawStore store,
2749                            boolean expectEvolved,
2750                            boolean expectUpdated)
2751            throws DatabaseException {
2752
2753            if (expectEvolved) {
2754                TestCase.fail();
2755            }
2756            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2757            checkRawFields(obj, "key", 99, "ff", (byte) 88);
2758        }
2759    }
2760
2761    @Entity(version=1)
2762    static class DisallowSecKeyField_Character2int
2763        extends EvolveCase {
2764
2765        private static final String NAME =
2766            DisallowSecKeyField_Character2int.class.getName();
2767
2768        @PrimaryKey
2769        int key = 99;
2770
2771        @SecondaryKey(relate=ONE_TO_ONE)
2772        int ff;
2773
2774        @Override
2775        public String getStoreOpenException() {
2776            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";
2777        }
2778
2779        @Override
2780        void checkUnevolvedModel(EntityModel model, Environment env) {
2781            checkEntity(true, model, env, NAME, 0, "ff");
2782            checkVersions(model, NAME, 0);
2783        }
2784
2785        @Override
2786        void readRawObjects(RawStore store,
2787                            boolean expectEvolved,
2788                            boolean expectUpdated)
2789            throws DatabaseException {
2790
2791            if (expectEvolved) {
2792                TestCase.fail();
2793            }
2794            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2795            checkRawFields(obj, "key", 99, "ff", (char) 88);
2796        }
2797    }
2798
2799    @Entity(version=1)
2800    static class DisallowSecKeyField_Short2int2
2801        extends EvolveCase {
2802
2803        private static final String NAME =
2804            DisallowSecKeyField_Short2int2.class.getName();
2805
2806        @PrimaryKey
2807        int key = 99;
2808
2809        @SecondaryKey(relate=ONE_TO_ONE)
2810        int ff;
2811
2812        @Override
2813        public String getStoreOpenException() {
2814            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";
2815        }
2816
2817        @Override
2818        void checkUnevolvedModel(EntityModel model, Environment env) {
2819            checkEntity(true, model, env, NAME, 0, "ff");
2820            checkVersions(model, NAME, 0);
2821        }
2822
2823        @Override
2824        void readRawObjects(RawStore store,
2825                            boolean expectEvolved,
2826                            boolean expectUpdated)
2827            throws DatabaseException {
2828
2829            if (expectEvolved) {
2830                TestCase.fail();
2831            }
2832            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2833            checkRawFields(obj, "key", 99, "ff", (short) 88);
2834        }
2835    }
2836
2837    @Entity(version=1)
2838    static class DisallowSecKeyField_Integer2long
2839        extends EvolveCase {
2840
2841        private static final String NAME =
2842            DisallowSecKeyField_Integer2long.class.getName();
2843
2844        @PrimaryKey
2845        int key = 99;
2846
2847        @SecondaryKey(relate=ONE_TO_ONE)
2848        long ff;
2849
2850        @Override
2851        public String getStoreOpenException() {
2852            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";
2853        }
2854
2855        @Override
2856        void checkUnevolvedModel(EntityModel model, Environment env) {
2857            checkEntity(true, model, env, NAME, 0, "ff");
2858            checkVersions(model, NAME, 0);
2859        }
2860
2861        @Override
2862        void readRawObjects(RawStore store,
2863                            boolean expectEvolved,
2864                            boolean expectUpdated)
2865            throws DatabaseException {
2866
2867            if (expectEvolved) {
2868                TestCase.fail();
2869            }
2870            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2871            checkRawFields(obj, "key", 99, "ff", (int) 88);
2872        }
2873    }
2874
2875    @Entity(version=1)
2876    static class DisallowSecKeyField_Long2float2
2877        extends EvolveCase {
2878
2879        private static final String NAME =
2880            DisallowSecKeyField_Long2float2.class.getName();
2881
2882        @PrimaryKey
2883        int key = 99;
2884
2885        @SecondaryKey(relate=ONE_TO_ONE)
2886        float ff;
2887
2888        @Override
2889        public String getStoreOpenException() {
2890            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";
2891        }
2892
2893        @Override
2894        void checkUnevolvedModel(EntityModel model, Environment env) {
2895            checkEntity(true, model, env, NAME, 0, "ff");
2896            checkVersions(model, NAME, 0);
2897        }
2898
2899        @Override
2900        void readRawObjects(RawStore store,
2901                            boolean expectEvolved,
2902                            boolean expectUpdated)
2903            throws DatabaseException {
2904
2905            if (expectEvolved) {
2906                TestCase.fail();
2907            }
2908            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2909            checkRawFields(obj, "key", 99, "ff", (long) 88);
2910        }
2911    }
2912
2913    @Entity(version=1)
2914    static class DisallowSecKeyField_Float2double2
2915        extends EvolveCase {
2916
2917        private static final String NAME =
2918            DisallowSecKeyField_Float2double2.class.getName();
2919
2920        @PrimaryKey
2921        int key = 99;
2922
2923        @SecondaryKey(relate=ONE_TO_ONE)
2924        double ff;
2925
2926        @Override
2927        public String getStoreOpenException() {
2928            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";
2929        }
2930
2931        @Override
2932        void checkUnevolvedModel(EntityModel model, Environment env) {
2933            checkEntity(true, model, env, NAME, 0, "ff");
2934            checkVersions(model, NAME, 0);
2935        }
2936
2937        @Override
2938        void readRawObjects(RawStore store,
2939                            boolean expectEvolved,
2940                            boolean expectUpdated)
2941            throws DatabaseException {
2942
2943            if (expectEvolved) {
2944                TestCase.fail();
2945            }
2946            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2947            checkRawFields(obj, "key", 99, "ff", (float) 88);
2948        }
2949    }
2950
2951    @Entity(version=1)
2952    static class DisallowSecKeyField_int2BigInt
2953        extends EvolveCase {
2954
2955        private static final String NAME =
2956            DisallowSecKeyField_int2BigInt.class.getName();
2957
2958        @PrimaryKey
2959        int key = 99;
2960
2961        @SecondaryKey(relate=ONE_TO_ONE)
2962        BigInteger ff;
2963
2964        @Override
2965        public String getStoreOpenException() {
2966            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";
2967        }
2968
2969        @Override
2970        void checkUnevolvedModel(EntityModel model, Environment env) {
2971            checkEntity(true, model, env, NAME, 0, "ff");
2972            checkVersions(model, NAME, 0);
2973        }
2974
2975        @Override
2976        void readRawObjects(RawStore store,
2977                            boolean expectEvolved,
2978                            boolean expectUpdated)
2979            throws DatabaseException {
2980
2981            if (expectEvolved) {
2982                TestCase.fail();
2983            }
2984            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
2985            checkRawFields(obj, "key", 99, "ff", 88);
2986        }
2987    }
2988
2989    // ---
2990
2991    @Entity(version=1)
2992    static class DisallowPriKeyField_byte2short
2993        extends EvolveCase {
2994
2995        private static final String NAME =
2996            DisallowPriKeyField_byte2short.class.getName();
2997
2998        @PrimaryKey
2999        short key;
3000
3001        @Override
3002        public String getStoreOpenException() {
3003            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";
3004        }
3005
3006        @Override
3007        void checkUnevolvedModel(EntityModel model, Environment env) {
3008            checkEntity(true, model, env, NAME, 0, null);
3009            checkVersions(model, NAME, 0);
3010        }
3011
3012        @Override
3013        void readRawObjects(RawStore store,
3014                            boolean expectEvolved,
3015                            boolean expectUpdated)
3016            throws DatabaseException {
3017
3018            if (expectEvolved) {
3019                TestCase.fail();
3020            }
3021            RawObject obj = readRaw(store, (byte) 99, NAME, 0, CASECLS, 0);
3022            checkRawFields(obj, "key", (byte) 99);
3023        }
3024    }
3025
3026    @Entity(version=1)
3027    static class DisallowPriKeyField_char2int
3028        extends EvolveCase {
3029
3030        private static final String NAME =
3031            DisallowPriKeyField_char2int.class.getName();
3032
3033        @PrimaryKey
3034        int key;
3035
3036        @Override
3037        public String getStoreOpenException() {
3038            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";
3039        }
3040
3041        @Override
3042        void checkUnevolvedModel(EntityModel model, Environment env) {
3043            checkEntity(true, model, env, NAME, 0, null);
3044            checkVersions(model, NAME, 0);
3045        }
3046
3047        @Override
3048        void readRawObjects(RawStore store,
3049                            boolean expectEvolved,
3050                            boolean expectUpdated)
3051            throws DatabaseException {
3052
3053            if (expectEvolved) {
3054                TestCase.fail();
3055            }
3056            RawObject obj = readRaw(store, (char) 99, NAME, 0, CASECLS, 0);
3057            checkRawFields(obj, "key", (char) 99);
3058        }
3059    }
3060
3061    @Entity(version=1)
3062    static class DisallowPriKeyField_short2int
3063        extends EvolveCase {
3064
3065        private static final String NAME =
3066            DisallowPriKeyField_short2int.class.getName();
3067
3068        @PrimaryKey
3069        int key;
3070
3071        @Override
3072        public String getStoreOpenException() {
3073            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";
3074        }
3075
3076        @Override
3077        void checkUnevolvedModel(EntityModel model, Environment env) {
3078            checkEntity(true, model, env, NAME, 0, null);
3079            checkVersions(model, NAME, 0);
3080        }
3081
3082        @Override
3083        void readRawObjects(RawStore store,
3084                            boolean expectEvolved,
3085                            boolean expectUpdated)
3086            throws DatabaseException {
3087
3088            if (expectEvolved) {
3089                TestCase.fail();
3090            }
3091            RawObject obj = readRaw(store, (short) 99, NAME, 0, CASECLS, 0);
3092            checkRawFields(obj, "key", (short) 99);
3093        }
3094    }
3095
3096    @Entity(version=1)
3097    static class DisallowPriKeyField_int2long
3098        extends EvolveCase {
3099
3100        private static final String NAME =
3101            DisallowPriKeyField_int2long.class.getName();
3102
3103        @PrimaryKey
3104        long key;
3105
3106        @Override
3107        public String getStoreOpenException() {
3108            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";
3109        }
3110
3111        @Override
3112        void checkUnevolvedModel(EntityModel model, Environment env) {
3113            checkEntity(true, model, env, NAME, 0, null);
3114            checkVersions(model, NAME, 0);
3115        }
3116
3117        @Override
3118        void readRawObjects(RawStore store,
3119                            boolean expectEvolved,
3120                            boolean expectUpdated)
3121            throws DatabaseException {
3122
3123            if (expectEvolved) {
3124                TestCase.fail();
3125            }
3126            RawObject obj = readRaw(store, (int) 99, NAME, 0, CASECLS, 0);
3127            checkRawFields(obj, "key", (int) 99);
3128        }
3129    }
3130
3131    @Entity(version=1)
3132    static class DisallowPriKeyField_long2float
3133        extends EvolveCase {
3134
3135        private static final String NAME =
3136            DisallowPriKeyField_long2float.class.getName();
3137
3138        @PrimaryKey
3139        float key;
3140
3141        @Override
3142        public String getStoreOpenException() {
3143            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";
3144        }
3145
3146        @Override
3147        void checkUnevolvedModel(EntityModel model, Environment env) {
3148            checkEntity(true, model, env, NAME, 0, null);
3149            checkVersions(model, NAME, 0);
3150        }
3151
3152        @Override
3153        void readRawObjects(RawStore store,
3154                            boolean expectEvolved,
3155                            boolean expectUpdated)
3156            throws DatabaseException {
3157
3158            if (expectEvolved) {
3159                TestCase.fail();
3160            }
3161            RawObject obj = readRaw(store, (long) 99, NAME, 0, CASECLS, 0);
3162            checkRawFields(obj, "key", (long) 99);
3163        }
3164    }
3165
3166    @Entity(version=1)
3167    static class DisallowPriKeyField_float2double
3168        extends EvolveCase {
3169
3170        private static final String NAME =
3171            DisallowPriKeyField_float2double.class.getName();
3172
3173        @PrimaryKey
3174        double key;
3175
3176        @Override
3177        public String getStoreOpenException() {
3178            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";
3179        }
3180
3181        @Override
3182        void checkUnevolvedModel(EntityModel model, Environment env) {
3183            checkEntity(true, model, env, NAME, 0, null);
3184            checkVersions(model, NAME, 0);
3185        }
3186
3187        @Override
3188        void readRawObjects(RawStore store,
3189                            boolean expectEvolved,
3190                            boolean expectUpdated)
3191            throws DatabaseException {
3192
3193            if (expectEvolved) {
3194                TestCase.fail();
3195            }
3196            RawObject obj = readRaw(store, (float) 99, NAME, 0, CASECLS, 0);
3197            checkRawFields(obj, "key", (float) 99);
3198        }
3199    }
3200
3201    @Entity(version=1)
3202    static class DisallowPriKeyField_Byte2short2
3203        extends EvolveCase {
3204
3205        private static final String NAME =
3206            DisallowPriKeyField_Byte2short2.class.getName();
3207
3208        @PrimaryKey
3209        short key;
3210
3211        @Override
3212        public String getStoreOpenException() {
3213            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";
3214        }
3215
3216        @Override
3217        void checkUnevolvedModel(EntityModel model, Environment env) {
3218            checkEntity(true, model, env, NAME, 0, null);
3219            checkVersions(model, NAME, 0);
3220        }
3221
3222        @Override
3223        void readRawObjects(RawStore store,
3224                            boolean expectEvolved,
3225                            boolean expectUpdated)
3226            throws DatabaseException {
3227
3228            if (expectEvolved) {
3229                TestCase.fail();
3230            }
3231            RawObject obj = readRaw(store, (byte) 99, NAME, 0, CASECLS, 0);
3232            checkRawFields(obj, "key", (byte) 99);
3233        }
3234    }
3235
3236    @Entity(version=1)
3237    static class DisallowPriKeyField_Character2int
3238        extends EvolveCase {
3239
3240        private static final String NAME =
3241            DisallowPriKeyField_Character2int.class.getName();
3242
3243        @PrimaryKey
3244        int key;
3245
3246        @Override
3247        public String getStoreOpenException() {
3248            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";
3249        }
3250
3251        @Override
3252        void checkUnevolvedModel(EntityModel model, Environment env) {
3253            checkEntity(true, model, env, NAME, 0, null);
3254            checkVersions(model, NAME, 0);
3255        }
3256
3257        @Override
3258        void readRawObjects(RawStore store,
3259                            boolean expectEvolved,
3260                            boolean expectUpdated)
3261            throws DatabaseException {
3262
3263            if (expectEvolved) {
3264                TestCase.fail();
3265            }
3266            RawObject obj = readRaw(store, (char) 99, NAME, 0, CASECLS, 0);
3267            checkRawFields(obj, "key", (char) 99);
3268        }
3269    }
3270
3271    @Entity(version=1)
3272    static class DisallowPriKeyField_Short2int2
3273        extends EvolveCase {
3274
3275        private static final String NAME =
3276            DisallowPriKeyField_Short2int2.class.getName();
3277
3278        @PrimaryKey
3279        int key;
3280
3281        @Override
3282        public String getStoreOpenException() {
3283            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";
3284        }
3285
3286        @Override
3287        void checkUnevolvedModel(EntityModel model, Environment env) {
3288            checkEntity(true, model, env, NAME, 0, null);
3289            checkVersions(model, NAME, 0);
3290        }
3291
3292        @Override
3293        void readRawObjects(RawStore store,
3294                            boolean expectEvolved,
3295                            boolean expectUpdated)
3296            throws DatabaseException {
3297
3298            if (expectEvolved) {
3299                TestCase.fail();
3300            }
3301            RawObject obj = readRaw(store, (short) 99, NAME, 0, CASECLS, 0);
3302            checkRawFields(obj, "key", (short) 99);
3303        }
3304    }
3305
3306    @Entity(version=1)
3307    static class DisallowPriKeyField_Integer2long
3308        extends EvolveCase {
3309
3310        private static final String NAME =
3311            DisallowPriKeyField_Integer2long.class.getName();
3312
3313        @PrimaryKey
3314        long key;
3315
3316        @Override
3317        public String getStoreOpenException() {
3318            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";
3319        }
3320
3321        @Override
3322        void checkUnevolvedModel(EntityModel model, Environment env) {
3323            checkEntity(true, model, env, NAME, 0, null);
3324            checkVersions(model, NAME, 0);
3325        }
3326
3327        @Override
3328        void readRawObjects(RawStore store,
3329                            boolean expectEvolved,
3330                            boolean expectUpdated)
3331            throws DatabaseException {
3332
3333            if (expectEvolved) {
3334                TestCase.fail();
3335            }
3336            RawObject obj = readRaw(store, (int) 99, NAME, 0, CASECLS, 0);
3337            checkRawFields(obj, "key", (int) 99);
3338        }
3339    }
3340
3341    @Entity(version=1)
3342    static class DisallowPriKeyField_Long2float2
3343        extends EvolveCase {
3344
3345        private static final String NAME =
3346            DisallowPriKeyField_Long2float2.class.getName();
3347
3348        @PrimaryKey
3349        float key;
3350
3351        @Override
3352        public String getStoreOpenException() {
3353            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";
3354        }
3355
3356        @Override
3357        void checkUnevolvedModel(EntityModel model, Environment env) {
3358            checkEntity(true, model, env, NAME, 0, null);
3359            checkVersions(model, NAME, 0);
3360        }
3361
3362        @Override
3363        void readRawObjects(RawStore store,
3364                            boolean expectEvolved,
3365                            boolean expectUpdated)
3366            throws DatabaseException {
3367
3368            if (expectEvolved) {
3369                TestCase.fail();
3370            }
3371            RawObject obj = readRaw(store, (long) 99, NAME, 0, CASECLS, 0);
3372            checkRawFields(obj, "key", (long) 99);
3373        }
3374    }
3375
3376    @Entity(version=1)
3377    static class DisallowPriKeyField_Float2double2
3378        extends EvolveCase {
3379
3380        private static final String NAME =
3381            DisallowPriKeyField_Float2double2.class.getName();
3382
3383        @PrimaryKey
3384        double key;
3385
3386        @Override
3387        public String getStoreOpenException() {
3388            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";
3389        }
3390
3391        @Override
3392        void checkUnevolvedModel(EntityModel model, Environment env) {
3393            checkEntity(true, model, env, NAME, 0, null);
3394            checkVersions(model, NAME, 0);
3395        }
3396
3397        @Override
3398        void readRawObjects(RawStore store,
3399                            boolean expectEvolved,
3400                            boolean expectUpdated)
3401            throws DatabaseException {
3402
3403            if (expectEvolved) {
3404                TestCase.fail();
3405            }
3406            RawObject obj = readRaw(store, (float) 99, NAME, 0, CASECLS, 0);
3407            checkRawFields(obj, "key", (float) 99);
3408        }
3409    }
3410
3411    @Entity(version=1)
3412    static class DisallowPriKeyField_Long2BigInt
3413        extends EvolveCase {
3414
3415        private static final String NAME =
3416            DisallowPriKeyField_Long2BigInt.class.getName();
3417
3418        @PrimaryKey
3419        BigInteger key;
3420
3421        @Override
3422        public String getStoreOpenException() {
3423            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";
3424        }
3425
3426        @Override
3427        void checkUnevolvedModel(EntityModel model, Environment env) {
3428            checkEntity(true, model, env, NAME, 0, null);
3429            checkVersions(model, NAME, 0);
3430        }
3431
3432        @Override
3433        void readRawObjects(RawStore store,
3434                            boolean expectEvolved,
3435                            boolean expectUpdated)
3436            throws DatabaseException {
3437
3438            if (expectEvolved) {
3439                TestCase.fail();
3440            }
3441            RawObject obj = readRaw(store, 99L, NAME, 0, CASECLS, 0);
3442            checkRawFields(obj, "key", 99L);
3443        }
3444    }
3445
3446    @Persistent(version=1)
3447    static class DisallowCompositeKeyField_byte2short_Key {
3448
3449        @KeyField(1)
3450        int f1 = 1;
3451
3452        @KeyField(2)
3453        short f2 = 2;
3454
3455        @KeyField(3)
3456        String f3 = "3";
3457    }
3458
3459    @Entity
3460    static class DisallowCompositeKeyField_byte2short
3461        extends EvolveCase {
3462
3463        private static final String NAME =
3464            DisallowCompositeKeyField_byte2short.class.getName();
3465        private static final String NAME2 =
3466            DisallowCompositeKeyField_byte2short_Key.class.getName();
3467
3468        @PrimaryKey
3469        DisallowCompositeKeyField_byte2short_Key key;
3470
3471        @Override
3472        public String getStoreOpenException() {
3473            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";
3474        }
3475
3476        @Override
3477        void checkUnevolvedModel(EntityModel model, Environment env) {
3478            checkEntity(true, model, env, NAME, 0, null);
3479            checkNonEntity(true, model, env, NAME2, 0);
3480            checkVersions(model, NAME, 0);
3481            checkVersions(model, NAME2, 0);
3482        }
3483
3484        @Override
3485        void readRawObjects(RawStore store,
3486                            boolean expectEvolved,
3487                            boolean expectUpdated)
3488            throws DatabaseException {
3489
3490            if (expectEvolved) {
3491                TestCase.fail();
3492            }
3493            RawType rawKeyType = store.getModel().getRawType(NAME2);
3494            RawObject rawKey = new RawObject
3495                (rawKeyType,
3496                 makeValues("f1", (int) 1, "f2", (byte) 2, "f3", "3"),
3497                 null);
3498
3499            RawObject obj = readRaw(store, rawKey, NAME, 0, CASECLS, 0);
3500            checkRawFields(obj, "key", rawKey);
3501        }
3502    }
3503
3504    @Entity(version=1)
3505    static class AllowPriKeyField_byte2Byte
3506        extends EvolveCase {
3507
3508        private static final String NAME =
3509            AllowPriKeyField_byte2Byte.class.getName();
3510
3511        @PrimaryKey
3512        Byte key = 99;
3513
3514        @Override
3515        void checkEvolvedModel(EntityModel model,
3516                               Environment env,
3517                               boolean oldTypesExist) {
3518            checkEntity(true, model, env, NAME, 1, null);
3519            if (oldTypesExist) {
3520                checkVersions(model, NAME, 1, NAME, 0);
3521            } else {
3522                checkVersions(model, NAME, 1);
3523            }
3524        }
3525
3526        @Override
3527        void readObjects(EntityStore store, boolean doUpdate)
3528            throws DatabaseException {
3529
3530            PrimaryIndex<Byte,AllowPriKeyField_byte2Byte>
3531                index = store.getPrimaryIndex
3532                    (Byte.class,
3533                     AllowPriKeyField_byte2Byte.class);
3534            AllowPriKeyField_byte2Byte obj = index.get(key);
3535            TestCase.assertNotNull(obj);
3536            TestCase.assertEquals(Byte.valueOf((byte) 99), obj.key);
3537
3538            if (doUpdate) {
3539                index.put(obj);
3540            }
3541        }
3542
3543        @Override
3544        void copyRawObjects(RawStore rawStore, EntityStore newStore)
3545            throws DatabaseException {
3546
3547            PrimaryIndex<Byte,AllowPriKeyField_byte2Byte>
3548                index = newStore.getPrimaryIndex
3549                    (Byte.class,
3550                     AllowPriKeyField_byte2Byte.class);
3551            RawObject raw = rawStore.getPrimaryIndex(NAME).get((byte) 99);
3552            index.put((AllowPriKeyField_byte2Byte)
3553                      newStore.getModel().convertRawObject(raw));
3554        }
3555
3556        @Override
3557        void readRawObjects(RawStore store,
3558                            boolean expectEvolved,
3559                            boolean expectUpdated)
3560            throws DatabaseException {
3561
3562            RawObject obj;
3563            if (expectEvolved) {
3564                obj = readRaw(store, (byte) 99, NAME, 1, CASECLS, 0);
3565            } else {
3566                obj = readRaw(store, (byte) 99, NAME, 0, CASECLS, 0);
3567            }
3568            checkRawFields(obj, "key", (byte) 99);
3569        }
3570    }
3571
3572    @Entity(version=1)
3573    static class AllowPriKeyField_Byte2byte2
3574        extends EvolveCase {
3575
3576        private static final String NAME =
3577            AllowPriKeyField_Byte2byte2.class.getName();
3578
3579        @PrimaryKey
3580        byte key = 99;
3581
3582        @Override
3583        void checkEvolvedModel(EntityModel model,
3584                               Environment env,
3585                               boolean oldTypesExist) {
3586            checkEntity(true, model, env, NAME, 1, null);
3587            if (oldTypesExist) {
3588                checkVersions(model, NAME, 1, NAME, 0);
3589            } else {
3590                checkVersions(model, NAME, 1);
3591            }
3592        }
3593
3594        @Override
3595        void readObjects(EntityStore store, boolean doUpdate)
3596            throws DatabaseException {
3597
3598            PrimaryIndex<Byte,AllowPriKeyField_Byte2byte2>
3599                index = store.getPrimaryIndex
3600                    (Byte.class,
3601                     AllowPriKeyField_Byte2byte2.class);
3602            AllowPriKeyField_Byte2byte2 obj = index.get(key);
3603            TestCase.assertNotNull(obj);
3604            TestCase.assertEquals((byte) 99, obj.key);
3605
3606            if (doUpdate) {
3607                index.put(obj);
3608            }
3609        }
3610
3611        @Override
3612        void copyRawObjects(RawStore rawStore, EntityStore newStore)
3613            throws DatabaseException {
3614
3615            PrimaryIndex<Byte,AllowPriKeyField_Byte2byte2>
3616                index = newStore.getPrimaryIndex
3617                    (Byte.class,
3618                     AllowPriKeyField_Byte2byte2.class);
3619            RawObject raw = rawStore.getPrimaryIndex(NAME).get((byte) 99);
3620            index.put((AllowPriKeyField_Byte2byte2)
3621                      newStore.getModel().convertRawObject(raw));
3622        }
3623
3624        @Override
3625        void readRawObjects(RawStore store,
3626                            boolean expectEvolved,
3627                            boolean expectUpdated)
3628            throws DatabaseException {
3629
3630            RawObject obj;
3631            if (expectEvolved) {
3632                obj = readRaw(store, (byte) 99, NAME, 1, CASECLS, 0);
3633            } else {
3634                obj = readRaw(store, (byte) 99, NAME, 0, CASECLS, 0);
3635            }
3636            checkRawFields(obj, "key", (byte) 99);
3637        }
3638    }
3639
3640    @Persistent(version=1)
3641    static class AllowFieldTypeChanges_Key {
3642
3643        AllowFieldTypeChanges_Key() {
3644            this(false);
3645        }
3646
3647        AllowFieldTypeChanges_Key(boolean init) {
3648            if (init) {
3649                f1 = true;
3650                f2 = (byte) 2;
3651                f3 = (short) 3;
3652                f4 = 4;
3653                f5 = 5L;
3654                f6 = 6F;
3655                f7 = 7D;
3656                f8 = (char) 8;
3657                f9 = true;
3658                f10 = (byte) 10;
3659                f11 = (short) 11;
3660                f12 = 12;
3661                f13 = 13L;
3662                f14 = 14F;
3663                f15 = 15D;
3664                f16 = (char) 16;
3665            }
3666        }
3667
3668        @KeyField(1)
3669        boolean f1;
3670
3671        @KeyField(2)
3672        byte f2;
3673
3674        @KeyField(3)
3675        short f3;
3676
3677        @KeyField(4)
3678        int f4;
3679
3680        @KeyField(5)
3681        long f5;
3682
3683        @KeyField(6)
3684        float f6;
3685
3686        @KeyField(7)
3687        double f7;
3688
3689        @KeyField(8)
3690        char f8;
3691
3692        @KeyField(9)
3693        Boolean f9;
3694
3695        @KeyField(10)
3696        Byte f10;
3697
3698        @KeyField(11)
3699        Short f11;
3700
3701        @KeyField(12)
3702        Integer f12;
3703
3704        @KeyField(13)
3705        Long f13;
3706
3707        @KeyField(14)
3708        Float f14;
3709
3710        @KeyField(15)
3711        Double f15;
3712
3713        @KeyField(16)
3714        Character f16;
3715    }
3716
3717    @Persistent(version=1)
3718    static class AllowFieldTypeChanges_Base
3719        extends EvolveCase {
3720
3721        @SecondaryKey(relate=ONE_TO_ONE)
3722        AllowFieldTypeChanges_Key kComposite;
3723
3724        Integer f_long2Integer;
3725        Long f_String2Long;
3726    }
3727
3728    /**
3729     * Allow field type changes: automatic widening, supported widening,
3730     * and Converter mutations.  Also tests primary and secondary key field
3731     * renaming.
3732     */
3733    @Entity(version=1)
3734    static class AllowFieldTypeChanges
3735        extends AllowFieldTypeChanges_Base {
3736
3737        private static final String NAME =
3738            AllowFieldTypeChanges.class.getName();
3739        private static final String NAME2 =
3740            AllowFieldTypeChanges_Base.class.getName();
3741        private static final String NAME3 =
3742            AllowFieldTypeChanges_Key.class.getName();
3743
3744        @PrimaryKey
3745        Integer pkeyInteger;
3746
3747        @SecondaryKey(relate=ONE_TO_ONE)
3748        Boolean kBoolean;
3749
3750        @SecondaryKey(relate=ONE_TO_ONE)
3751        Byte kByte;
3752
3753        @SecondaryKey(relate=ONE_TO_ONE)
3754        Short kShort;
3755
3756        @SecondaryKey(relate=ONE_TO_ONE)
3757        Integer kInteger;
3758
3759        @SecondaryKey(relate=ONE_TO_ONE)
3760        Long kLong;
3761
3762        @SecondaryKey(relate=ONE_TO_ONE)
3763        Float kFloat;
3764
3765        @SecondaryKey(relate=ONE_TO_ONE)
3766        Double kDouble;
3767
3768        @SecondaryKey(relate=ONE_TO_ONE)
3769        Character kCharacter;
3770
3771        short f01;
3772        int f02;
3773        long f03;
3774        float f04;
3775        double f06;
3776        int f07;
3777        long f08;
3778        float f09;
3779        double f10;
3780        int f11;
3781        long f12;
3782        float f13;
3783        double f14;
3784        long f15;
3785        float f16;
3786        double f17;
3787        float f18;
3788        double f19;
3789        double f20;
3790
3791        Short f21;
3792        Integer f22;
3793        Long f23;
3794        Float f24;
3795        Double f26;
3796        Integer f27;
3797        Long f28;
3798        Float f29;
3799        Double f30;
3800        Integer f31;
3801        Long f32;
3802        Float f33;
3803        Double f34;
3804        Long f35;
3805        Float f36;
3806        Double f37;
3807        Float f38;
3808        Double f39;
3809        Double f40;
3810
3811        Short f41;
3812        Integer f42;
3813        Long f43;
3814        Float f44;
3815        Double f46;
3816        Integer f47;
3817        Long f48;
3818        Float f49;
3819        Double f50;
3820        Integer f51;
3821        Long f52;
3822        Float f53;
3823        Double f54;
3824        Long f55;
3825        Float f56;
3826        Double f57;
3827        Float f58;
3828        Double f59;
3829        Double f60;
3830
3831        BigInteger f70;
3832        BigInteger f71;
3833        BigInteger f72;
3834        BigInteger f73;
3835        BigInteger f74;
3836        BigInteger f75;
3837        BigInteger f76;
3838        BigInteger f77;
3839        BigInteger f78;
3840        BigInteger f79;
3841
3842        int f_long2int;
3843        long f_String2long;
3844
3845        @Override
3846        Mutations getMutations() {
3847            Mutations m = new Mutations();
3848            m.addRenamer(new Renamer(NAME, 0, "pkeyint", "pkeyInteger"));
3849            m.addRenamer(new Renamer(NAME, 0, "kboolean", "kBoolean"));
3850            m.addRenamer(new Renamer(NAME, 0, "kbyte", "kByte"));
3851            m.addRenamer(new Renamer(NAME, 0, "kshort", "kShort"));
3852            m.addRenamer(new Renamer(NAME, 0, "kint", "kInteger"));
3853            m.addRenamer(new Renamer(NAME, 0, "klong", "kLong"));
3854            m.addRenamer(new Renamer(NAME, 0, "kfloat", "kFloat"));
3855            m.addRenamer(new Renamer(NAME, 0, "kdouble", "kDouble"));
3856            m.addRenamer(new Renamer(NAME, 0, "kchar", "kCharacter"));
3857            m.addRenamer(new Renamer(NAME2, 0, "kcomposite", "kComposite"));
3858
3859            Conversion conv1 = new MyConversion1();
3860            Conversion conv2 = new MyConversion2();
3861
3862            m.addConverter(new Converter(NAME, 0, "f_long2int", conv1));
3863            m.addConverter(new Converter(NAME, 0, "f_String2long", conv2));
3864            m.addConverter(new Converter(NAME2, 0, "f_long2Integer", conv1));
3865            m.addConverter(new Converter(NAME2, 0, "f_String2Long", conv2));
3866            return m;
3867        }
3868
3869        static class MyConversion1 implements Conversion {
3870
3871            public void initialize(EntityModel model) {}
3872
3873            public Object convert(Object o) {
3874                return ((Long) o).intValue();
3875            }
3876
3877            @Override
3878            public boolean equals(Object other) { return true; }
3879        }
3880
3881        static class MyConversion2 implements Conversion {
3882
3883            public void initialize(EntityModel model) {}
3884
3885            public Object convert(Object o) {
3886                return Long.valueOf((String) o);
3887            }
3888
3889            @Override
3890            public boolean equals(Object other) { return true; }
3891        }
3892
3893        @Override
3894        void checkEvolvedModel(EntityModel model,
3895                               Environment env,
3896                               boolean oldTypesExist) {
3897            checkEntity(true, model, env, NAME, 1, null);
3898            checkNonEntity(true, model, env, NAME2, 1);
3899            if (oldTypesExist) {
3900                checkVersions(model, NAME, 1, NAME, 0);
3901                checkVersions(model, NAME2, 1, NAME2, 0);
3902                checkVersions(model, NAME3, 1, NAME3, 0);
3903            } else {
3904                checkVersions(model, NAME, 1);
3905                checkVersions(model, NAME2, 1);
3906                checkVersions(model, NAME3, 1);
3907            }
3908        }
3909
3910        @Override
3911        void readObjects(EntityStore store, boolean doUpdate)
3912            throws DatabaseException {
3913
3914            PrimaryIndex<Integer,AllowFieldTypeChanges>
3915                index = store.getPrimaryIndex
3916                    (Integer.class, AllowFieldTypeChanges.class);
3917            AllowFieldTypeChanges obj = index.get((int) 99);
3918            checkValues(obj);
3919            checkSecondaries(store, index);
3920
3921            if (doUpdate) {
3922                index.put(obj);
3923                checkSecondaries(store, index);
3924            }
3925        }
3926
3927        @Override
3928        void copyRawObjects(RawStore rawStore, EntityStore newStore)
3929            throws DatabaseException {
3930
3931            PrimaryIndex<Integer,AllowFieldTypeChanges>
3932                index = newStore.getPrimaryIndex
3933                    (Integer.class, AllowFieldTypeChanges.class);
3934            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
3935            index.put((AllowFieldTypeChanges)
3936                      newStore.getModel().convertRawObject(raw));
3937        }
3938
3939        private void checkSecondaries(EntityStore store,
3940                                      PrimaryIndex<Integer,
3941                                                   AllowFieldTypeChanges>
3942                                                   index)
3943            throws DatabaseException {
3944
3945            checkValues(store.getSecondaryIndex
3946                (index, Boolean.class, "kBoolean").get(true));
3947            checkValues(store.getSecondaryIndex
3948                (index, Byte.class, "kByte").get((byte) 77));
3949            checkValues(store.getSecondaryIndex
3950                (index, Short.class, "kShort").get((short) 66));
3951            checkValues(store.getSecondaryIndex
3952                (index, Integer.class, "kInteger").get((int) 55));
3953            checkValues(store.getSecondaryIndex
3954                (index, Long.class, "kLong").get((long) 44));
3955            checkValues(store.getSecondaryIndex
3956                (index, Float.class, "kFloat").get((float) 33));
3957            checkValues(store.getSecondaryIndex
3958                (index, Double.class, "kDouble").get((double) 22));
3959            checkValues(store.getSecondaryIndex
3960                (index, Character.class, "kCharacter").get((char) 11));
3961            checkValues(store.getSecondaryIndex
3962                (index, AllowFieldTypeChanges_Key.class, "kComposite").get
3963                    (new AllowFieldTypeChanges_Key(true)));
3964        }
3965
3966        private void checkValues(AllowFieldTypeChanges obj) {
3967            TestCase.assertNotNull(obj);
3968            TestCase.assertEquals(obj.pkeyInteger, Integer.valueOf(99));
3969            TestCase.assertEquals(obj.kBoolean, Boolean.valueOf(true));
3970            TestCase.assertEquals(obj.kByte, Byte.valueOf((byte) 77));
3971            TestCase.assertEquals(obj.kShort, Short.valueOf((short) 66));
3972            TestCase.assertEquals(obj.kInteger, Integer.valueOf(55));
3973            TestCase.assertEquals(obj.kLong, Long.valueOf(44));
3974            TestCase.assertEquals(obj.kFloat, Float.valueOf(33));
3975            TestCase.assertEquals(obj.kDouble, Double.valueOf(22));
3976            TestCase.assertEquals(obj.kCharacter, Character.valueOf((char) 11));
3977
3978            AllowFieldTypeChanges_Key embed = obj.kComposite;
3979            TestCase.assertNotNull(embed);
3980            TestCase.assertEquals(embed.f1, true);
3981            TestCase.assertEquals(embed.f2, (byte) 2);
3982            TestCase.assertEquals(embed.f3, (short) 3);
3983            TestCase.assertEquals(embed.f4, 4);
3984            TestCase.assertEquals(embed.f5, 5L);
3985            TestCase.assertEquals(embed.f6, 6F);
3986            TestCase.assertEquals(embed.f7, 7D);
3987            TestCase.assertEquals(embed.f8, (char) 8);
3988            TestCase.assertEquals(embed.f9, Boolean.valueOf(true));
3989            TestCase.assertEquals(embed.f10, Byte.valueOf((byte) 10));
3990            TestCase.assertEquals(embed.f11, Short.valueOf((short) 11));
3991            TestCase.assertEquals(embed.f12, Integer.valueOf(12));
3992            TestCase.assertEquals(embed.f13, Long.valueOf(13L));
3993            TestCase.assertEquals(embed.f14, Float.valueOf(14F));
3994            TestCase.assertEquals(embed.f15, Double.valueOf(15D));
3995            TestCase.assertEquals(embed.f16, Character.valueOf((char) 16));
3996
3997            TestCase.assertEquals(obj.f01, (short) 1);
3998            TestCase.assertEquals(obj.f02, (int) 2);
3999            TestCase.assertEquals(obj.f03, (long) 3);
4000            TestCase.assertEquals(obj.f04, (float) 4);
4001            TestCase.assertEquals(obj.f06, (double) 6);
4002            TestCase.assertEquals(obj.f07, (int) 7);
4003            TestCase.assertEquals(obj.f08, (long) 8);
4004            TestCase.assertEquals(obj.f09, (float) 9);
4005            TestCase.assertEquals(obj.f10, (double) 10);
4006            TestCase.assertEquals(obj.f11, (int) 11);
4007            TestCase.assertEquals(obj.f12, (long) 12);
4008            TestCase.assertEquals(obj.f13, (float) 13);
4009            TestCase.assertEquals(obj.f14, (double) 14);
4010            TestCase.assertEquals(obj.f15, 15L);
4011            TestCase.assertEquals(obj.f16, 16F);
4012            TestCase.assertEquals(obj.f17, 17D);
4013            TestCase.assertEquals(obj.f18, (float) 18);
4014            TestCase.assertEquals(obj.f19, (double) 19);
4015            TestCase.assertEquals(obj.f20, (double) 20);
4016
4017            TestCase.assertEquals(obj.f21, Short.valueOf((byte) 21));
4018            TestCase.assertEquals(obj.f22, Integer.valueOf((byte) 22));
4019            TestCase.assertEquals(obj.f23, Long.valueOf((byte) 23));
4020            TestCase.assertEquals(obj.f24, Float.valueOf((byte) 24));
4021            TestCase.assertEquals(obj.f26, Double.valueOf((byte) 26));
4022            TestCase.assertEquals(obj.f27, Integer.valueOf((short) 27));
4023            TestCase.assertEquals(obj.f28, Long.valueOf((short) 28));
4024            TestCase.assertEquals(obj.f29, Float.valueOf((short) 29));
4025            TestCase.assertEquals(obj.f30, Double.valueOf((short) 30));
4026            TestCase.assertEquals(obj.f31, Integer.valueOf((char) 31));
4027            TestCase.assertEquals(obj.f32, Long.valueOf((char) 32));
4028            TestCase.assertEquals(obj.f33, Float.valueOf((char) 33));
4029            TestCase.assertEquals(obj.f34, Double.valueOf((char) 34));
4030            TestCase.assertEquals(obj.f35, Long.valueOf(35));
4031            TestCase.assertEquals(obj.f36, Float.valueOf(36));
4032            TestCase.assertEquals(obj.f37, Double.valueOf(37));
4033            TestCase.assertEquals(obj.f38, Float.valueOf((long) 38));
4034            TestCase.assertEquals(obj.f39, Double.valueOf((long) 39));
4035            TestCase.assertEquals(obj.f40, Double.valueOf((float) 40));
4036
4037            TestCase.assertEquals(obj.f41, Short.valueOf((byte) 41));
4038            TestCase.assertEquals(obj.f42, Integer.valueOf((byte) 42));
4039            TestCase.assertEquals(obj.f43, Long.valueOf((byte) 43));
4040            TestCase.assertEquals(obj.f44, Float.valueOf((byte) 44));
4041            TestCase.assertEquals(obj.f46, Double.valueOf((byte) 46));
4042            TestCase.assertEquals(obj.f47, Integer.valueOf((short) 47));
4043            TestCase.assertEquals(obj.f48, Long.valueOf((short) 48));
4044            TestCase.assertEquals(obj.f49, Float.valueOf((short) 49));
4045            TestCase.assertEquals(obj.f50, Double.valueOf((short) 50));
4046            TestCase.assertEquals(obj.f51, Integer.valueOf((char) 51));
4047            TestCase.assertEquals(obj.f52, Long.valueOf((char) 52));
4048            TestCase.assertEquals(obj.f53, Float.valueOf((char) 53));
4049            TestCase.assertEquals(obj.f54, Double.valueOf((char) 54));
4050            TestCase.assertEquals(obj.f55, Long.valueOf(55));
4051            TestCase.assertEquals(obj.f56, Float.valueOf(56));
4052            TestCase.assertEquals(obj.f57, Double.valueOf(57));
4053            TestCase.assertEquals(obj.f58, Float.valueOf((long) 58));
4054            TestCase.assertEquals(obj.f59, Double.valueOf((long) 59));
4055            TestCase.assertEquals(obj.f60, Double.valueOf((float) 60));
4056
4057            TestCase.assertEquals(obj.f70, BigInteger.valueOf(70));
4058            TestCase.assertEquals(obj.f71, BigInteger.valueOf(71));
4059            TestCase.assertEquals(obj.f72, BigInteger.valueOf(72));
4060            TestCase.assertEquals(obj.f73, BigInteger.valueOf(73));
4061            TestCase.assertEquals(obj.f74, BigInteger.valueOf(74));
4062            TestCase.assertEquals(obj.f75, BigInteger.valueOf(75));
4063            TestCase.assertEquals(obj.f76, BigInteger.valueOf(76));
4064            TestCase.assertEquals(obj.f77, BigInteger.valueOf(77));
4065            TestCase.assertEquals(obj.f78, BigInteger.valueOf(78));
4066            TestCase.assertEquals(obj.f79, BigInteger.valueOf(79));
4067
4068            TestCase.assertEquals(obj.f_long2Integer, Integer.valueOf(111));
4069            TestCase.assertEquals(obj.f_String2Long, Long.valueOf(222));
4070            TestCase.assertEquals(obj.f_long2int, 333);
4071            TestCase.assertEquals(obj.f_String2long, 444L);
4072        }
4073
4074        @Override
4075        void readRawObjects(RawStore store,
4076                            boolean expectEvolved,
4077                            boolean expectUpdated)
4078            throws DatabaseException {
4079
4080            RawType embedType = store.getModel().getRawType(NAME3);
4081            RawObject embed = new RawObject
4082                (embedType,
4083                 makeValues
4084                    ("f1", true,
4085                     "f2", (byte) 2,
4086                     "f3", (short) 3,
4087                     "f4", 4,
4088                     "f5", 5L,
4089                     "f6", 6F,
4090                     "f7", 7D,
4091                     "f8", (char) 8,
4092                     "f9", true,
4093                     "f10", (byte) 10,
4094                     "f11", (short) 11,
4095                     "f12", 12,
4096                     "f13", 13L,
4097                     "f14", 14F,
4098                     "f15", 15D,
4099                     "f16", (char) 16),
4100                 null);
4101
4102            RawObject obj;
4103            if (expectEvolved) {
4104                obj = readRaw(store, 99, NAME, 1, NAME2, 1, CASECLS, 0);
4105                checkRawFields(obj, "pkeyInteger", (int) 99,
4106                               "kBoolean", true,
4107                               "kByte", (byte) 77,
4108                               "kShort", (short) 66,
4109                               "kInteger", (int) 55,
4110                               "kLong", (long) 44,
4111                               "kFloat", (float) 33,
4112                               "kDouble", (double) 22,
4113                               "kCharacter", (char) 11,
4114
4115                               "f01", (short) 1,
4116                               "f02", (int) 2,
4117                               "f03", (long) 3,
4118                               "f04", (float) 4,
4119                               "f06", (double) 6,
4120                               "f07", (int) 7,
4121                               "f08", (long) 8,
4122                               "f09", (float) 9,
4123                               "f10", (double) 10,
4124                               "f11", (int) 11,
4125                               "f12", (long) 12,
4126                               "f13", (float) 13,
4127                               "f14", (double) 14,
4128                               "f15", 15L,
4129                               "f16", 16F,
4130                               "f17", 17D,
4131                               "f18", (float) 18,
4132                               "f19", (double) 19,
4133                               "f20", (double) 20,
4134
4135                               "f21", (short) 21,
4136                               "f22", (int) 22,
4137                               "f23", (long) 23,
4138                               "f24", (float) 24,
4139                               "f26", (double) 26,
4140                               "f27", (int) 27,
4141                               "f28", (long) 28,
4142                               "f29", (float) 29,
4143                               "f30", (double) 30,
4144                               "f31", (int) 31,
4145                               "f32", (long) 32,
4146                               "f33", (float) 33,
4147                               "f34", (double) 34,
4148                               "f35", 35L,
4149                               "f36", 36F,
4150                               "f37", 37D,
4151                               "f38", (float) 38,
4152                               "f39", (double) 39,
4153                               "f40", (double) 40,
4154
4155                               "f41", (short) 41,
4156                               "f42", (int) 42,
4157                               "f43", (long) 43,
4158                               "f44", (float) 44,
4159                               "f46", (double) 46,
4160                               "f47", (int) 47,
4161                               "f48", (long) 48,
4162                               "f49", (float) 49,
4163                               "f50", (double) 50,
4164                               "f51", (int) 51,
4165                               "f52", (long) 52,
4166                               "f53", (float) 53,
4167                               "f54", (double) 54,
4168                               "f55", 55L,
4169                               "f56", 56F,
4170                               "f57", 57D,
4171                               "f58", (float) 58,
4172                               "f59", (double) 59,
4173                               "f60", (double) 60,
4174
4175                               "f70", BigInteger.valueOf(70),
4176                               "f71", BigInteger.valueOf(71),
4177                               "f72", BigInteger.valueOf(72),
4178                               "f73", BigInteger.valueOf(73),
4179                               "f74", BigInteger.valueOf(74),
4180                               "f75", BigInteger.valueOf(75),
4181                               "f76", BigInteger.valueOf(76),
4182                               "f77", BigInteger.valueOf(77),
4183                               "f78", BigInteger.valueOf(78),
4184                               "f79", BigInteger.valueOf(79),
4185
4186                               "f_long2int", 333,
4187                               "f_String2long", 444L);
4188                checkRawFields(obj.getSuper(),
4189                               "kComposite", embed,
4190                               "f_long2Integer", 111,
4191                               "f_String2Long", 222L);
4192            } else {
4193                obj = readRaw(store, 99, NAME, 0, NAME2, 0, CASECLS, 0);
4194                checkRawFields(obj, "pkeyint", (int) 99,
4195                               "kboolean", true,
4196                               "kbyte", (byte) 77,
4197                               "kshort", (short) 66,
4198                               "kint", (int) 55,
4199                               "klong", (long) 44,
4200                               "kfloat", (float) 33,
4201                               "kdouble", (double) 22,
4202                               "kchar", (char) 11,
4203
4204                               "f01", (byte) 1,
4205                               "f02", (byte) 2,
4206                               "f03", (byte) 3,
4207                               "f04", (byte) 4,
4208                               "f06", (byte) 6,
4209                               "f07", (short) 7,
4210                               "f08", (short) 8,
4211                               "f09", (short) 9,
4212                               "f10", (short) 10,
4213                               "f11", (char) 11,
4214                               "f12", (char) 12,
4215                               "f13", (char) 13,
4216                               "f14", (char) 14,
4217                               "f15", 15,
4218                               "f16", 16,
4219                               "f17", 17,
4220                               "f18", (long) 18,
4221                               "f19", (long) 19,
4222                               "f20", (float) 20,
4223
4224                               "f21", (byte) 21,
4225                               "f22", (byte) 22,
4226                               "f23", (byte) 23,
4227                               "f24", (byte) 24,
4228                               "f26", (byte) 26,
4229                               "f27", (short) 27,
4230                               "f28", (short) 28,
4231                               "f29", (short) 29,
4232                               "f30", (short) 30,
4233                               "f31", (char) 31,
4234                               "f32", (char) 32,
4235                               "f33", (char) 33,
4236                               "f34", (char) 34,
4237                               "f35", 35,
4238                               "f36", 36,
4239                               "f37", 37,
4240                               "f38", (long) 38,
4241                               "f39", (long) 39,
4242                               "f40", (float) 40,
4243
4244                               "f41", (byte) 41,
4245                               "f42", (byte) 42,
4246                               "f43", (byte) 43,
4247                               "f44", (byte) 44,
4248                               "f46", (byte) 46,
4249                               "f47", (short) 47,
4250                               "f48", (short) 48,
4251                               "f49", (short) 49,
4252                               "f50", (short) 50,
4253                               "f51", (char) 51,
4254                               "f52", (char) 52,
4255                               "f53", (char) 53,
4256                               "f54", (char) 54,
4257                               "f55", 55,
4258                               "f56", 56,
4259                               "f57", 57,
4260                               "f58", (long) 58,
4261                               "f59", (long) 59,
4262                               "f60", (float) 60,
4263
4264                               "f70", (byte) 70,
4265                               "f71", (short) 71,
4266                               "f72", (char) 72,
4267                               "f73", 73,
4268                               "f74", (long) 74,
4269                               "f75", (byte) 75,
4270                               "f76", (short) 76,
4271                               "f77", (char) 77,
4272                               "f78", 78,
4273                               "f79", (long) 79,
4274
4275                               "f_long2int", 333L,
4276                               "f_String2long", "444");
4277
4278                checkRawFields(obj.getSuper(),
4279                               "kcomposite", embed,
4280                               "f_long2Integer", 111L,
4281                               "f_String2Long", "222");
4282            }
4283            Environment env = store.getEnvironment();
4284
4285            assertDbExists(expectEvolved, env, NAME, "kBoolean");
4286            assertDbExists(expectEvolved, env, NAME, "kByte");
4287            assertDbExists(expectEvolved, env, NAME, "kShort");
4288            assertDbExists(expectEvolved, env, NAME, "kInteger");
4289            assertDbExists(expectEvolved, env, NAME, "kLong");
4290            assertDbExists(expectEvolved, env, NAME, "kFloat");
4291            assertDbExists(expectEvolved, env, NAME, "kDouble");
4292            assertDbExists(expectEvolved, env, NAME, "kCharacter");
4293            assertDbExists(expectEvolved, env, NAME, "kComposite");
4294
4295            assertDbExists(!expectEvolved, env, NAME, "kboolean");
4296            assertDbExists(!expectEvolved, env, NAME, "kbyte");
4297            assertDbExists(!expectEvolved, env, NAME, "kshort");
4298            assertDbExists(!expectEvolved, env, NAME, "kint");
4299            assertDbExists(!expectEvolved, env, NAME, "klong");
4300            assertDbExists(!expectEvolved, env, NAME, "kfloat");
4301            assertDbExists(!expectEvolved, env, NAME, "kdouble");
4302            assertDbExists(!expectEvolved, env, NAME, "kchar");
4303            assertDbExists(!expectEvolved, env, NAME, "kcomposite");
4304        }
4305    }
4306
4307    @Persistent(version=1)
4308    static class ConvertExample1_Address {
4309        String street;
4310        String city;
4311        String state;
4312        int zipCode;
4313    }
4314
4315    static class ConvertExample1_Conversion implements Conversion {
4316
4317        public void initialize(EntityModel model) {
4318        }
4319
4320        public Object convert(Object fromValue) {
4321            return Integer.valueOf((String) fromValue);
4322        }
4323
4324        @Override
4325        public boolean equals(Object o) {
4326            return o instanceof ConvertExample1_Conversion;
4327        }
4328    }
4329
4330    @Entity
4331    static class ConvertExample1_Entity
4332        extends EvolveCase {
4333
4334        private static final String NAME =
4335            ConvertExample1_Entity.class.getName();
4336        private static final String NAME2 =
4337            ConvertExample1_Address.class.getName();
4338
4339        @PrimaryKey
4340        int key = 99;
4341
4342        ConvertExample1_Address embed;
4343
4344        @Override
4345        Mutations getMutations() {
4346            Mutations m = new Mutations();
4347            Converter converter = new Converter
4348                (ConvertExample1_Address.class.getName(), 0,
4349                 "zipCode", new ConvertExample1_Conversion());
4350            m.addConverter(converter);
4351            return m;
4352        }
4353
4354        @Override
4355        void checkEvolvedModel(EntityModel model,
4356                               Environment env,
4357                               boolean oldTypesExist) {
4358            checkEntity(true, model, env, NAME, 0, null);
4359            checkVersions(model, NAME, 0);
4360            if (oldTypesExist) {
4361                checkVersions(model, NAME2, 1, NAME2, 0);
4362            } else {
4363                checkVersions(model, NAME2, 1);
4364            }
4365        }
4366
4367        @Override
4368        void readObjects(EntityStore store, boolean doUpdate)
4369            throws DatabaseException {
4370
4371            PrimaryIndex<Integer,ConvertExample1_Entity>
4372                index = store.getPrimaryIndex
4373                    (Integer.class,
4374                     ConvertExample1_Entity.class);
4375            ConvertExample1_Entity obj = index.get(99);
4376            TestCase.assertNotNull(obj);
4377            TestCase.assertEquals(99, obj.key);
4378            TestCase.assertNotNull(obj.embed);
4379            TestCase.assertEquals("street", obj.embed.street);
4380            TestCase.assertEquals("city", obj.embed.city);
4381            TestCase.assertEquals("state", obj.embed.state);
4382            TestCase.assertEquals(12345, obj.embed.zipCode);
4383
4384            if (doUpdate) {
4385                index.put(obj);
4386            }
4387        }
4388
4389        @Override
4390        void copyRawObjects(RawStore rawStore, EntityStore newStore)
4391            throws DatabaseException {
4392
4393            PrimaryIndex<Integer,ConvertExample1_Entity>
4394                index = newStore.getPrimaryIndex
4395                    (Integer.class,
4396                     ConvertExample1_Entity.class);
4397            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
4398            index.put((ConvertExample1_Entity)
4399                      newStore.getModel().convertRawObject(raw));
4400        }
4401
4402        @Override
4403        void readRawObjects(RawStore store,
4404                            boolean expectEvolved,
4405                            boolean expectUpdated)
4406            throws DatabaseException {
4407
4408            RawType embedType = store.getModel().getRawType(NAME2);
4409            RawObject embed;
4410            if (expectEvolved) {
4411                embed = new RawObject
4412                    (embedType,
4413                     makeValues("street", "street",
4414                                "city", "city",
4415                                "state", "state",
4416                                "zipCode", 12345),
4417                     null);
4418            } else {
4419                embed = new RawObject
4420                    (embedType,
4421                     makeValues("street", "street",
4422                                "city", "city",
4423                                "state", "state",
4424                                "zipCode", "12345"),
4425                     null);
4426            }
4427            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
4428            checkRawFields(obj, "key", 99, "embed", embed);
4429        }
4430    }
4431
4432    @Persistent
4433    static class ConvertExample2_Address {
4434        String street;
4435        String city;
4436        String state;
4437        int zipCode;
4438    }
4439
4440    @Entity(version=1)
4441    static class ConvertExample2_Person
4442        extends EvolveCase {
4443
4444        private static final String NAME =
4445            ConvertExample2_Person.class.getName();
4446        private static final String NAME2 =
4447            ConvertExample2_Address .class.getName();
4448
4449        @PrimaryKey
4450        int key;
4451
4452        ConvertExample2_Address address;
4453
4454        @Override
4455        Mutations getMutations() {
4456            Mutations m = new Mutations();
4457            Converter converter = new Converter
4458                (ConvertExample2_Person.class.getName(), 0,
4459                 "address", new ConvertExample2_Conversion());
4460            m.addConverter(converter);
4461            return m;
4462        }
4463
4464        @Override
4465        void checkEvolvedModel(EntityModel model,
4466                               Environment env,
4467                               boolean oldTypesExist) {
4468            checkEntity(true, model, env, NAME, 1, null);
4469            if (oldTypesExist) {
4470                checkVersions(model, NAME, 1, NAME, 0);
4471            } else {
4472                checkVersions(model, NAME, 1);
4473            }
4474            checkVersions(model, NAME2, 0);
4475        }
4476
4477        @Override
4478        void readObjects(EntityStore store, boolean doUpdate)
4479            throws DatabaseException {
4480
4481            PrimaryIndex<Integer,ConvertExample2_Person>
4482                index = store.getPrimaryIndex
4483                    (Integer.class,
4484                     ConvertExample2_Person.class);
4485            ConvertExample2_Person obj = index.get(99);
4486            TestCase.assertNotNull(obj);
4487            TestCase.assertEquals(99, obj.key);
4488            TestCase.assertNotNull(obj.address);
4489            TestCase.assertEquals("street", obj.address.street);
4490            TestCase.assertEquals("city", obj.address.city);
4491            TestCase.assertEquals("state", obj.address.state);
4492            TestCase.assertEquals(12345, obj.address.zipCode);
4493
4494            if (doUpdate) {
4495                index.put(obj);
4496            }
4497        }
4498
4499        @Override
4500        void copyRawObjects(RawStore rawStore, EntityStore newStore)
4501            throws DatabaseException {
4502
4503            PrimaryIndex<Integer,ConvertExample2_Person>
4504                index = newStore.getPrimaryIndex
4505                    (Integer.class,
4506                     ConvertExample2_Person.class);
4507            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
4508            index.put((ConvertExample2_Person)
4509                      newStore.getModel().convertRawObject(raw));
4510        }
4511
4512        @Override
4513        void readRawObjects(RawStore store,
4514                            boolean expectEvolved,
4515                            boolean expectUpdated)
4516            throws DatabaseException {
4517
4518            Object embed;
4519            if (expectEvolved) {
4520                RawType embedType = store.getModel().getRawType(NAME2);
4521                embed = new RawObject
4522                    (embedType,
4523                     makeValues("street", "street",
4524                                "city", "city",
4525                                "state", "state",
4526                                "zipCode", 12345),
4527                     null);
4528            } else {
4529                embed = "street#city#state#12345";
4530            }
4531            RawObject obj = readRaw
4532                (store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
4533            checkRawFields(obj, "key", 99, "address", embed);
4534        }
4535    }
4536
4537    static class ConvertExample2_Conversion implements Conversion {
4538        private transient RawType addressType;
4539
4540        public void initialize(EntityModel model) {
4541            addressType = model.getRawType
4542                (ConvertExample2_Address.class.getName());
4543        }
4544
4545        public Object convert(Object fromValue) {
4546
4547            String oldAddress = (String) fromValue;
4548            Map<String,Object> addressValues = new HashMap<String,Object>();
4549            addressValues.put("street", parseAddress(1, oldAddress));
4550            addressValues.put("city", parseAddress(2, oldAddress));
4551            addressValues.put("state", parseAddress(3, oldAddress));
4552            addressValues.put("zipCode",
4553                              Integer.valueOf(parseAddress(4, oldAddress)));
4554
4555            return new RawObject(addressType, addressValues, null);
4556        }
4557
4558        @Override
4559        public boolean equals(Object o) {
4560            return o instanceof ConvertExample2_Conversion;
4561        }
4562
4563        private String parseAddress(int fieldNum, String oldAddress) {
4564            StringTokenizer tokens = new StringTokenizer(oldAddress, "#");
4565            String field = null;
4566            for (int i = 0; i < fieldNum; i += 1) {
4567                field = tokens.nextToken();
4568            }
4569            return field;
4570        }
4571    }
4572
4573    @Persistent
4574    static class ConvertExample3_Address {
4575        String street;
4576        String city;
4577        String state;
4578        int zipCode;
4579    }
4580
4581    static class ConvertExample3_Conversion implements Conversion {
4582        private transient RawType newPersonType;
4583        private transient RawType addressType;
4584
4585        public void initialize(EntityModel model) {
4586            newPersonType = model.getRawType
4587                (ConvertExample3_Person.class.getName());
4588            addressType = model.getRawType
4589                (ConvertExample3_Address.class.getName());
4590        }
4591
4592        public Object convert(Object fromValue) {
4593
4594            RawObject person = (RawObject) fromValue;
4595            Map<String,Object> personValues = person.getValues();
4596            Map<String,Object> addressValues = new HashMap<String,Object>();
4597            RawObject address = new RawObject
4598                (addressType, addressValues, null);
4599
4600            addressValues.put("street", personValues.remove("street"));
4601            addressValues.put("city", personValues.remove("city"));
4602            addressValues.put("state", personValues.remove("state"));
4603            addressValues.put("zipCode", personValues.remove("zipCode"));
4604            personValues.put("address", address);
4605
4606            return new RawObject
4607                (newPersonType, personValues, person.getSuper());
4608        }
4609
4610        @Override
4611        public boolean equals(Object o) {
4612            return o instanceof ConvertExample3_Conversion;
4613        }
4614    }
4615
4616    @Entity(version=1)
4617    static class ConvertExample3_Person
4618        extends EvolveCase {
4619
4620        private static final String NAME =
4621            ConvertExample3_Person.class.getName();
4622        private static final String NAME2 =
4623            ConvertExample3_Address .class.getName();
4624
4625        @PrimaryKey
4626        int key;
4627
4628        ConvertExample3_Address address;
4629
4630        @Override
4631        Mutations getMutations() {
4632            Mutations m = new Mutations();
4633            Converter converter = new Converter
4634                (ConvertExample3_Person.class.getName(), 0,
4635                 new ConvertExample3_Conversion());
4636            m.addConverter(converter);
4637            return m;
4638        }
4639
4640        @Override
4641        void checkEvolvedModel(EntityModel model,
4642                               Environment env,
4643                               boolean oldTypesExist) {
4644            checkEntity(true, model, env, NAME, 1, null);
4645            if (oldTypesExist) {
4646                checkVersions(model, NAME, 1, NAME, 0);
4647            } else {
4648                checkVersions(model, NAME, 1);
4649            }
4650            checkVersions(model, NAME2, 0);
4651        }
4652
4653        @Override
4654        void readObjects(EntityStore store, boolean doUpdate)
4655            throws DatabaseException {
4656
4657            PrimaryIndex<Integer,ConvertExample3_Person>
4658                index = store.getPrimaryIndex
4659                    (Integer.class,
4660                     ConvertExample3_Person.class);
4661            ConvertExample3_Person obj = index.get(99);
4662            TestCase.assertNotNull(obj);
4663            TestCase.assertEquals(99, obj.key);
4664            TestCase.assertNotNull(obj.address);
4665            TestCase.assertEquals("street", obj.address.street);
4666            TestCase.assertEquals("city", obj.address.city);
4667            TestCase.assertEquals("state", obj.address.state);
4668            TestCase.assertEquals(12345, obj.address.zipCode);
4669
4670            if (doUpdate) {
4671                index.put(obj);
4672            }
4673        }
4674
4675        @Override
4676        void copyRawObjects(RawStore rawStore, EntityStore newStore)
4677            throws DatabaseException {
4678
4679            PrimaryIndex<Integer,ConvertExample3_Person>
4680                index = newStore.getPrimaryIndex
4681                    (Integer.class,
4682                     ConvertExample3_Person.class);
4683            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
4684            index.put((ConvertExample3_Person)
4685                      newStore.getModel().convertRawObject(raw));
4686        }
4687
4688        @Override
4689        void readRawObjects(RawStore store,
4690                            boolean expectEvolved,
4691                            boolean expectUpdated)
4692            throws DatabaseException {
4693
4694            RawObject obj = readRaw
4695                (store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
4696            if (expectEvolved) {
4697                RawType embedType = store.getModel().getRawType(NAME2);
4698                Object embed = new RawObject
4699                    (embedType,
4700                     makeValues("street", "street",
4701                                "city", "city",
4702                                "state", "state",
4703                                "zipCode", 12345),
4704                     null);
4705                checkRawFields(obj, "key", 99, "address", embed);
4706            } else {
4707                checkRawFields(obj, "key", 99,
4708                                    "street", "street",
4709                                    "city", "city",
4710                                    "state", "state",
4711                                    "zipCode", 12345);
4712            }
4713        }
4714    }
4715
4716    @Persistent(version=1)
4717    static class ConvertExample4_A extends ConvertExample4_B {
4718    }
4719
4720    @Persistent(version=1)
4721    static class ConvertExample4_B {
4722        String name;
4723    }
4724
4725    static class Example4_Conversion implements Conversion {
4726        private transient RawType newAType;
4727        private transient RawType newBType;
4728
4729        public void initialize(EntityModel model) {
4730            newAType = model.getRawType(ConvertExample4_A.class.getName());
4731            newBType = model.getRawType(ConvertExample4_B.class.getName());
4732        }
4733
4734        public Object convert(Object fromValue) {
4735            RawObject oldA = (RawObject) fromValue;
4736            RawObject oldB = oldA.getSuper();
4737            Map<String,Object> aValues = oldA.getValues();
4738            Map<String,Object> bValues = oldB.getValues();
4739            bValues.put("name", aValues.remove("name"));
4740            RawObject newB = new RawObject(newBType, bValues, oldB.getSuper());
4741            RawObject newA = new RawObject(newAType, aValues, newB);
4742            return newA;
4743        }
4744
4745        @Override
4746        public boolean equals(Object o) {
4747            return o instanceof Example4_Conversion;
4748        }
4749    }
4750
4751    @Entity(version=1)
4752    static class ConvertExample4_Entity
4753        extends EvolveCase {
4754
4755        private static final String NAME =
4756            ConvertExample4_Entity.class.getName();
4757        private static final String NAME2 =
4758            ConvertExample4_A .class.getName();
4759        private static final String NAME3 =
4760            ConvertExample4_B .class.getName();
4761
4762        @PrimaryKey
4763        int key;
4764
4765        ConvertExample4_A embed;
4766
4767        @Override
4768        Mutations getMutations() {
4769            Mutations m = new Mutations();
4770            Converter converter = new Converter
4771                (ConvertExample4_A.class.getName(), 0,
4772                 new Example4_Conversion());
4773            m.addConverter(converter);
4774            return m;
4775        }
4776
4777        @Override
4778        void checkEvolvedModel(EntityModel model,
4779                               Environment env,
4780                               boolean oldTypesExist) {
4781            checkEntity(true, model, env, NAME, 1, null);
4782            if (oldTypesExist) {
4783                checkVersions(model, NAME, 1, NAME, 0);
4784                checkVersions(model, NAME2, 1, NAME2, 0);
4785                checkVersions(model, NAME3, 1, NAME3, 0);
4786            } else {
4787                checkVersions(model, NAME, 1);
4788                checkVersions(model, NAME2, 1);
4789                checkVersions(model, NAME3, 1);
4790            }
4791        }
4792
4793        @Override
4794        void readObjects(EntityStore store, boolean doUpdate)
4795            throws DatabaseException {
4796
4797            PrimaryIndex<Integer,ConvertExample4_Entity>
4798                index = store.getPrimaryIndex
4799                    (Integer.class,
4800                     ConvertExample4_Entity.class);
4801            ConvertExample4_Entity obj = index.get(99);
4802            TestCase.assertNotNull(obj);
4803            TestCase.assertEquals(99, obj.key);
4804            TestCase.assertNotNull(obj.embed);
4805            TestCase.assertEquals("name", obj.embed.name);
4806
4807            if (doUpdate) {
4808                index.put(obj);
4809            }
4810        }
4811
4812        @Override
4813        void copyRawObjects(RawStore rawStore, EntityStore newStore)
4814            throws DatabaseException {
4815
4816            PrimaryIndex<Integer,ConvertExample4_Entity>
4817                index = newStore.getPrimaryIndex
4818                    (Integer.class,
4819                     ConvertExample4_Entity.class);
4820            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
4821            index.put((ConvertExample4_Entity)
4822                      newStore.getModel().convertRawObject(raw));
4823        }
4824
4825        @Override
4826        void readRawObjects(RawStore store,
4827                            boolean expectEvolved,
4828                            boolean expectUpdated)
4829            throws DatabaseException {
4830
4831            RawType embedTypeA = store.getModel().getRawType(NAME2);
4832            RawType embedTypeB = store.getModel().getRawType(NAME3);
4833            Object embed;
4834            if (expectEvolved) {
4835                embed = new RawObject(embedTypeA, makeValues(),
4836                        new RawObject
4837                            (embedTypeB, makeValues("name", "name"), null));
4838            } else {
4839                embed = new RawObject(embedTypeA, makeValues("name", "name"),
4840                        new RawObject
4841                            (embedTypeB, makeValues(), null));
4842            }
4843            RawObject obj = readRaw
4844                (store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
4845            checkRawFields(obj, "key", 99, "embed", embed);
4846        }
4847    }
4848
4849    @Persistent(version=1)
4850    static class ConvertExample5_Pet {
4851        String name;
4852    }
4853
4854    @Persistent
4855    static class ConvertExample5_Cat extends ConvertExample5_Pet {
4856        int finickyLevel;
4857    }
4858
4859    @Persistent
4860    static class ConvertExample5_Dog extends ConvertExample5_Pet {
4861        double barkVolume;
4862    }
4863
4864    static class ConvertExample5_Conversion implements Conversion {
4865        private transient RawType newPetType;
4866        private transient RawType dogType;
4867        private transient RawType catType;
4868
4869        public void initialize(EntityModel model) {
4870            newPetType = model.getRawType(ConvertExample5_Pet.class.getName());
4871            dogType = model.getRawType(ConvertExample5_Dog.class.getName());
4872            catType = model.getRawType(ConvertExample5_Cat.class.getName());
4873        }
4874
4875        public Object convert(Object fromValue) {
4876            RawObject pet = (RawObject) fromValue;
4877            Map<String,Object> petValues = pet.getValues();
4878            Map<String,Object> subTypeValues = new HashMap<String,Object>();
4879            Boolean isCat = (Boolean) petValues.remove("isCatNotDog");
4880            Integer finickyLevel = (Integer) petValues.remove("finickyLevel");
4881            Double barkVolume = (Double) petValues.remove("barkVolume");
4882            RawType newSubType;
4883            if (isCat) {
4884                newSubType = catType;
4885                subTypeValues.put("finickyLevel", finickyLevel);
4886            } else {
4887                newSubType = dogType;
4888                subTypeValues.put("barkVolume", barkVolume);
4889            }
4890            RawObject newPet = new RawObject
4891                (newPetType, petValues, pet.getSuper());
4892            return new RawObject(newSubType, subTypeValues, newPet);
4893        }
4894
4895        @Override
4896        public boolean equals(Object o) {
4897            return o instanceof ConvertExample5_Conversion;
4898        }
4899    }
4900
4901    @Entity(version=1)
4902    static class ConvertExample5_Entity
4903        extends EvolveCase {
4904
4905        private static final String NAME =
4906            ConvertExample5_Entity.class.getName();
4907        private static final String NAME2 =
4908            ConvertExample5_Pet.class.getName();
4909        private static final String NAME3 =
4910            ConvertExample5_Cat.class.getName();
4911        private static final String NAME4 =
4912            ConvertExample5_Dog.class.getName();
4913
4914        @PrimaryKey
4915        int key;
4916
4917        ConvertExample5_Cat cat;
4918        ConvertExample5_Dog dog;
4919
4920        @Override
4921        Mutations getMutations() {
4922            Mutations m = new Mutations();
4923            Converter converter = new Converter
4924                (ConvertExample5_Pet.class.getName(), 0,
4925                 new ConvertExample5_Conversion());
4926            m.addConverter(converter);
4927            return m;
4928        }
4929
4930        @Override
4931        void checkEvolvedModel(EntityModel model,
4932                               Environment env,
4933                               boolean oldTypesExist) {
4934            checkEntity(true, model, env, NAME, 1, null);
4935            if (oldTypesExist) {
4936                checkVersions(model, NAME, 1, NAME, 0);
4937                checkVersions(model, NAME2, 1, NAME2, 0);
4938            } else {
4939                checkVersions(model, NAME, 1);
4940                checkVersions(model, NAME2, 1);
4941            }
4942            checkVersions(model, NAME3, 0);
4943            checkVersions(model, NAME4, 0);
4944        }
4945
4946        @Override
4947        void readObjects(EntityStore store, boolean doUpdate)
4948            throws DatabaseException {
4949
4950            PrimaryIndex<Integer,ConvertExample5_Entity>
4951                index = store.getPrimaryIndex
4952                    (Integer.class,
4953                     ConvertExample5_Entity.class);
4954            ConvertExample5_Entity obj = index.get(99);
4955            TestCase.assertNotNull(obj);
4956            TestCase.assertEquals(99, obj.key);
4957            TestCase.assertNotNull(obj.cat);
4958            TestCase.assertEquals("Jeffry", obj.cat.name);
4959            TestCase.assertEquals(999, obj.cat.finickyLevel);
4960            TestCase.assertNotNull(obj.dog);
4961            TestCase.assertEquals("Nelson", obj.dog.name);
4962            TestCase.assertEquals(0.01, obj.dog.barkVolume);
4963
4964            if (doUpdate) {
4965                index.put(obj);
4966            }
4967        }
4968
4969        @Override
4970        void copyRawObjects(RawStore rawStore, EntityStore newStore)
4971            throws DatabaseException {
4972
4973            PrimaryIndex<Integer,ConvertExample5_Entity>
4974                index = newStore.getPrimaryIndex
4975                    (Integer.class,
4976                     ConvertExample5_Entity.class);
4977            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
4978            index.put((ConvertExample5_Entity)
4979                      newStore.getModel().convertRawObject(raw));
4980        }
4981
4982        @Override
4983        void readRawObjects(RawStore store,
4984                            boolean expectEvolved,
4985                            boolean expectUpdated)
4986            throws DatabaseException {
4987
4988            RawType petType = store.getModel().getRawType(NAME2);
4989            RawObject cat;
4990            RawObject dog;
4991            if (expectEvolved) {
4992                RawType catType = store.getModel().getRawType(NAME3);
4993                RawType dogType = store.getModel().getRawType(NAME4);
4994                cat = new RawObject(catType, makeValues("finickyLevel", 999),
4995                      new RawObject(petType, makeValues("name", "Jeffry"),
4996                                    null));
4997                dog = new RawObject(dogType, makeValues("barkVolume", 0.01),
4998                      new RawObject(petType, makeValues("name", "Nelson"),
4999                                    null));
5000            } else {
5001                cat = new RawObject(petType, makeValues("name", "Jeffry",
5002                                                        "isCatNotDog", true,
5003                                                        "finickyLevel", 999,
5004                                                        "barkVolume", 0.0),
5005                                    null);
5006                dog = new RawObject(petType, makeValues("name", "Nelson",
5007                                                        "isCatNotDog", false,
5008                                                        "finickyLevel", 0,
5009                                                        "barkVolume", 0.01),
5010                                    null);
5011            }
5012            RawObject obj = readRaw
5013                (store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
5014            checkRawFields(obj, "key", 99, "cat", cat, "dog", dog);
5015        }
5016    }
5017
5018    @Persistent(version=1)
5019    static class AllowFieldAddDelete_Embed {
5020        private String f0 = "0";
5021        private String f2;
5022        private int f3 = 3;
5023        private String f4;
5024        private int f5 = 5;
5025        private String f8 = "8";
5026        private int f9 = 9;
5027    }
5028
5029    @Persistent(version=1)
5030    static class AllowFieldAddDelete_Base
5031        extends EvolveCase {
5032
5033        private String f0 = "0";
5034        private String f2;
5035        private int f3 = 3;
5036        private String f4;
5037        private int f5 = 5;
5038        private String f8 = "8";
5039        private int f9 = 9;
5040    }
5041
5042    @Entity(version=1)
5043    static class AllowFieldAddDelete
5044        extends AllowFieldAddDelete_Base {
5045
5046        private static final String NAME =
5047            AllowFieldAddDelete.class.getName();
5048        private static final String NAME2 =
5049            AllowFieldAddDelete_Base.class.getName();
5050        private static final String NAME3 =
5051            AllowFieldAddDelete_Embed.class.getName();
5052
5053        @PrimaryKey
5054        int key;
5055
5056        AllowFieldAddDelete_Embed embed;
5057
5058        private String f0 = "0";
5059        private String f2;
5060        private int f3 = 3;
5061        private String f4;
5062        private int f5 = 5;
5063        private String f8 = "8";
5064        private int f9 = 9;
5065
5066        @Override
5067        Mutations getMutations() {
5068            Mutations m = new Mutations();
5069            for (String name : new String[] {NAME, NAME2, NAME3}) {
5070                m.addDeleter(new Deleter(name, 0, "f1"));
5071                m.addDeleter(new Deleter(name, 0, "f6"));
5072                m.addDeleter(new Deleter(name, 0, "f7"));
5073            }
5074            return m;
5075        }
5076
5077        @Override
5078        void checkEvolvedModel(EntityModel model,
5079                               Environment env,
5080                               boolean oldTypesExist) {
5081            checkEntity(true, model, env, NAME, 1, null);
5082            if (oldTypesExist) {
5083                checkVersions(model, NAME, 1, NAME, 0);
5084                checkVersions(model, NAME2, 1, NAME2, 0);
5085                checkVersions(model, NAME3, 1, NAME3, 0);
5086            } else {
5087                checkVersions(model, NAME, 1);
5088                checkVersions(model, NAME2, 1);
5089                checkVersions(model, NAME3, 1);
5090            }
5091        }
5092
5093        @Override
5094        void readObjects(EntityStore store, boolean doUpdate)
5095            throws DatabaseException {
5096
5097            PrimaryIndex<Integer,AllowFieldAddDelete>
5098                index = store.getPrimaryIndex
5099                    (Integer.class,
5100                     AllowFieldAddDelete.class);
5101            AllowFieldAddDelete obj = index.get(99);
5102            TestCase.assertNotNull(obj);
5103            TestCase.assertEquals(99, obj.key);
5104            {
5105                AllowFieldAddDelete o = obj;
5106
5107                TestCase.assertNotNull(o);
5108                TestCase.assertEquals("0", o.f0);
5109                TestCase.assertEquals("2", o.f2);
5110                TestCase.assertEquals(3, o.f3);
5111                TestCase.assertEquals("4", o.f4);
5112                TestCase.assertEquals(5, o.f5);
5113                TestCase.assertEquals("8", o.f8);
5114                TestCase.assertEquals(9, o.f9);
5115            }
5116            {
5117                AllowFieldAddDelete_Base o = (AllowFieldAddDelete_Base) obj;
5118
5119                TestCase.assertNotNull(o);
5120                TestCase.assertEquals("0", o.f0);
5121                TestCase.assertEquals("2", o.f2);
5122                TestCase.assertEquals(3, o.f3);
5123                TestCase.assertEquals("4", o.f4);
5124                TestCase.assertEquals(5, o.f5);
5125                TestCase.assertEquals("8", o.f8);
5126                TestCase.assertEquals(9, o.f9);
5127            }
5128            {
5129                AllowFieldAddDelete_Embed o = obj.embed;
5130
5131                TestCase.assertNotNull(o);
5132                TestCase.assertEquals("0", o.f0);
5133                TestCase.assertEquals("2", o.f2);
5134                TestCase.assertEquals(3, o.f3);
5135                TestCase.assertEquals("4", o.f4);
5136                TestCase.assertEquals(5, o.f5);
5137                TestCase.assertEquals("8", o.f8);
5138                TestCase.assertEquals(9, o.f9);
5139            }
5140
5141            if (doUpdate) {
5142                index.put(obj);
5143            }
5144        }
5145
5146        @Override
5147        void copyRawObjects(RawStore rawStore, EntityStore newStore)
5148            throws DatabaseException {
5149
5150            PrimaryIndex<Integer,AllowFieldAddDelete>
5151                index = newStore.getPrimaryIndex
5152                    (Integer.class,
5153                     AllowFieldAddDelete.class);
5154            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
5155            index.put((AllowFieldAddDelete)
5156                      newStore.getModel().convertRawObject(raw));
5157        }
5158
5159        static final Object[] fixedFields0 = {
5160            "f1", 1,
5161            "f2", "2",
5162            "f4", "4",
5163            "f6", 6,
5164            "f7", "7",
5165        };
5166
5167        static final Object[] fixedFields1 = {
5168            "f2", "2",
5169            "f4", "4",
5170        };
5171
5172        static final Object[] fixedFields2 = {
5173            "f0", "0",
5174            "f2", "2",
5175            "f3", 3,
5176            "f4", "4",
5177            "f5", 5,
5178            "f8", "8",
5179            "f9", 9,
5180        };
5181
5182        @Override
5183        void readRawObjects(RawStore store,
5184                            boolean expectEvolved,
5185                            boolean expectUpdated)
5186            throws DatabaseException {
5187
5188            RawType baseType = store.getModel().getRawType(NAME2);
5189            RawType embedType = store.getModel().getRawType(NAME3);
5190
5191            Object[] ff;
5192            if (expectEvolved) {
5193                if (expectUpdated) {
5194                    ff = fixedFields2;
5195                } else {
5196                    ff = fixedFields1;
5197                }
5198            } else {
5199                ff = fixedFields0;
5200            }
5201            RawObject embed = new RawObject(embedType, makeValues(ff), null);
5202            RawObject obj = readRaw
5203                (store, 99, NAME, expectEvolved ? 1 : 0,
5204                            NAME2, expectEvolved ? 1 : 0,
5205                            CASECLS, 0);
5206            checkRaw(obj, ff, "key", 99, "embed", embed);
5207            checkRaw(obj.getSuper(), ff);
5208        }
5209
5210        private void checkRaw(RawObject obj,
5211                              Object[] fixedFields,
5212                              Object... otherFields) {
5213            Object[] allFields =
5214                new Object[otherFields.length + fixedFields.length];
5215            System.arraycopy(otherFields, 0, allFields, 0, otherFields.length);
5216            System.arraycopy(fixedFields, 0, allFields,
5217                             otherFields.length, fixedFields.length);
5218            checkRawFields(obj, allFields);
5219        }
5220    }
5221
5222    static class ProxiedClass {
5223        int data;
5224
5225        ProxiedClass(int data) {
5226            this.data = data;
5227        }
5228    }
5229
5230    @Persistent(version=1, proxyFor=ProxiedClass.class)
5231    static class ProxiedClass_Proxy implements PersistentProxy<ProxiedClass> {
5232        long data;
5233
5234        public void initializeProxy(ProxiedClass o) {
5235            data = o.data;
5236        }
5237
5238        public ProxiedClass convertProxy() {
5239            return new ProxiedClass((int) data);
5240        }
5241    }
5242
5243    @Entity
5244    static class ProxiedClass_Entity
5245        extends EvolveCase {
5246
5247        private static final String NAME =
5248            ProxiedClass_Entity.class.getName();
5249        private static final String NAME2 =
5250            ProxiedClass_Proxy.class.getName();
5251
5252        @PrimaryKey
5253        int key;
5254
5255        ProxiedClass embed;
5256
5257        @Override
5258        void configure(EntityModel model, StoreConfig config) {
5259            model.registerClass(ProxiedClass_Proxy.class);
5260        }
5261
5262        @Override
5263        void checkEvolvedModel(EntityModel model,
5264                               Environment env,
5265                               boolean oldTypesExist) {
5266            checkEntity(true, model, env, NAME, 0, null);
5267            checkVersions(model, NAME, 0);
5268            if (oldTypesExist) {
5269                checkVersions(model, NAME2, 1, NAME2, 0);
5270            } else {
5271                checkVersions(model, NAME2, 1);
5272            }
5273        }
5274
5275        @Override
5276        void readObjects(EntityStore store, boolean doUpdate)
5277            throws DatabaseException {
5278
5279            PrimaryIndex<Integer,ProxiedClass_Entity>
5280                index = store.getPrimaryIndex
5281                    (Integer.class,
5282                     ProxiedClass_Entity.class);
5283            ProxiedClass_Entity obj = index.get(99);
5284            TestCase.assertNotNull(obj);
5285            TestCase.assertEquals(99, obj.key);
5286            TestCase.assertNotNull(obj.embed);
5287            TestCase.assertEquals(88, obj.embed.data);
5288
5289            if (doUpdate) {
5290                index.put(obj);
5291            }
5292        }
5293
5294        @Override
5295        void copyRawObjects(RawStore rawStore, EntityStore newStore)
5296            throws DatabaseException {
5297
5298            PrimaryIndex<Integer,ProxiedClass_Entity>
5299                index = newStore.getPrimaryIndex
5300                    (Integer.class,
5301                     ProxiedClass_Entity.class);
5302            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
5303            index.put((ProxiedClass_Entity)
5304                      newStore.getModel().convertRawObject(raw));
5305        }
5306
5307        @Override
5308        void readRawObjects(RawStore store,
5309                            boolean expectEvolved,
5310                            boolean expectUpdated)
5311            throws DatabaseException {
5312
5313            RawType embedType = store.getModel().getRawType(NAME2);
5314            RawObject embed;
5315            if (expectEvolved) {
5316                embed = new RawObject
5317                    (embedType, makeValues("data", 88L), null);
5318            } else {
5319                embed = new RawObject
5320                    (embedType, makeValues("data", 88), null);
5321            }
5322            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
5323            checkRawFields(obj, "key", 99, "embed", embed);
5324        }
5325    }
5326
5327    @Persistent(proxyFor=StringBuffer.class)
5328    static class DisallowChangeProxyFor_Proxy2
5329        implements PersistentProxy<StringBuffer> {
5330
5331        String data;
5332
5333        public void initializeProxy(StringBuffer o) {
5334            data = o.toString();
5335        }
5336
5337        public StringBuffer convertProxy() {
5338            return new StringBuffer(data);
5339        }
5340    }
5341
5342    @Persistent(proxyFor=StringBuilder.class)
5343    static class DisallowChangeProxyFor_Proxy
5344        implements PersistentProxy<StringBuilder> {
5345
5346        String data;
5347
5348        public void initializeProxy(StringBuilder o) {
5349            data = o.toString();
5350        }
5351
5352        public StringBuilder convertProxy() {
5353            return new StringBuilder(data);
5354        }
5355    }
5356
5357    @Entity
5358    static class DisallowChangeProxyFor
5359        extends EvolveCase {
5360
5361        @PrimaryKey
5362        int key;
5363
5364        @Override
5365        public String getStoreOpenException() {
5366            return "com.sleepycat.persist.evolve.IncompatibleClassException: Error when evolving class: java.lang.StringBuffer version: 0 to class: java.lang.StringBuffer 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";
5367        }
5368
5369        @Override
5370        void configure(EntityModel model, StoreConfig config) {
5371            model.registerClass(DisallowChangeProxyFor_Proxy.class);
5372            model.registerClass(DisallowChangeProxyFor_Proxy2.class);
5373        }
5374    }
5375
5376    @Persistent
5377    static class DisallowDeleteProxyFor_Proxy {
5378        String data;
5379    }
5380
5381    @Entity
5382    static class DisallowDeleteProxyFor
5383        extends EvolveCase {
5384
5385        @PrimaryKey
5386        int key;
5387
5388        @Override
5389        public String getStoreOpenException() {
5390            return "com.sleepycat.persist.evolve.IncompatibleClassException: Mutation is missing to evolve class: java.lang.StringBuffer version: 0 Error: java.lang.IllegalArgumentException: Class could not be loaded or is not persistent: java.lang.StringBuffer";
5391        }
5392    }
5393
5394    @Persistent(version=1)
5395    static class ArrayNameChange_Component_Renamed {
5396
5397        long data;
5398    }
5399
5400    @Entity
5401    static class ArrayNameChange_Entity
5402        extends EvolveCase {
5403
5404        private static final String NAME =
5405            ArrayNameChange_Entity.class.getName();
5406        private static final String NAME2 =
5407            ArrayNameChange_Component_Renamed.class.getName();
5408        private static final String NAME3 =
5409            PREFIX + "ArrayNameChange_Component";
5410
5411        @PrimaryKey
5412        int key;
5413
5414        ArrayNameChange_Component_Renamed[] embed;
5415        ArrayNameChange_Component_Renamed embed2;
5416
5417        @Override
5418        Mutations getMutations() {
5419            Mutations m = new Mutations();
5420            m.addRenamer(new Renamer(NAME3, 0, NAME2));
5421            return m;
5422        }
5423
5424        @Override
5425        void checkEvolvedModel(EntityModel model,
5426                               Environment env,
5427                               boolean oldTypesExist) {
5428            checkEntity(true, model, env, NAME, 0, null);
5429            checkVersions(model, NAME, 0);
5430            if (oldTypesExist) {
5431                checkVersions(model, NAME2, 1, NAME3, 0);
5432            } else {
5433                checkVersions(model, NAME2, 1);
5434            }
5435        }
5436
5437        @Override
5438        void readObjects(EntityStore store, boolean doUpdate)
5439            throws DatabaseException {
5440
5441            PrimaryIndex<Integer,ArrayNameChange_Entity>
5442                index = store.getPrimaryIndex
5443                    (Integer.class,
5444                     ArrayNameChange_Entity.class);
5445            ArrayNameChange_Entity obj = index.get(99);
5446            TestCase.assertNotNull(obj);
5447            TestCase.assertEquals(99, obj.key);
5448            TestCase.assertNotNull(obj.embed);
5449            TestCase.assertEquals(1, obj.embed.length);
5450            TestCase.assertEquals(88L, obj.embed[0].data);
5451            TestCase.assertSame(obj.embed2, obj.embed[0]);
5452
5453            if (doUpdate) {
5454                index.put(obj);
5455            }
5456        }
5457
5458        @Override
5459        void copyRawObjects(RawStore rawStore, EntityStore newStore)
5460            throws DatabaseException {
5461
5462            PrimaryIndex<Integer,ArrayNameChange_Entity>
5463                index = newStore.getPrimaryIndex
5464                    (Integer.class,
5465                     ArrayNameChange_Entity.class);
5466            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
5467            index.put((ArrayNameChange_Entity)
5468                      newStore.getModel().convertRawObject(raw));
5469        }
5470
5471        @Override
5472        void readRawObjects(RawStore store,
5473                            boolean expectEvolved,
5474                            boolean expectUpdated)
5475            throws DatabaseException {
5476
5477            String compTypeName = expectEvolved ? NAME2 : NAME3;
5478            String arrayTypeName = "[L" + compTypeName + ';';
5479            RawType compType = store.getModel().getRawType(compTypeName);
5480            RawType arrayType = store.getModel().getRawType(arrayTypeName);
5481            RawObject embed2;
5482            if (expectEvolved) {
5483                embed2 = new RawObject
5484                    (compType, makeValues("data", 88L), null);
5485            } else {
5486                embed2 = new RawObject
5487                    (compType, makeValues("data", 88), null);
5488            }
5489            RawObject embed = new RawObject
5490                (arrayType, new Object[] { embed2 });
5491            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
5492            checkRawFields(obj, "key", 99, "embed", embed, "embed2", embed2);
5493        }
5494    }
5495
5496    enum AddEnumConstant_Enum {
5497        A, B, C;
5498    }
5499
5500    @Entity(version=1)
5501    static class AddEnumConstant_Entity
5502        extends EvolveCase {
5503
5504        private static final String NAME =
5505            AddEnumConstant_Entity.class.getName();
5506        private static final String NAME2 =
5507            AddEnumConstant_Enum.class.getName();
5508
5509        @PrimaryKey
5510        int key;
5511
5512        AddEnumConstant_Enum e1;
5513        AddEnumConstant_Enum e2;
5514        AddEnumConstant_Enum e3 = AddEnumConstant_Enum.C;
5515
5516        @Override
5517        void checkEvolvedModel(EntityModel model,
5518                               Environment env,
5519                               boolean oldTypesExist) {
5520            checkEntity(true, model, env, NAME, 1, null);
5521            if (oldTypesExist) {
5522                checkVersions(model, NAME, 1, NAME, 0);
5523                checkVersions(model, NAME2, 0, NAME2, 0);
5524            } else {
5525                checkVersions(model, NAME, 1);
5526                checkVersions(model, NAME2, 0);
5527            }
5528        }
5529
5530        @Override
5531        void readObjects(EntityStore store, boolean doUpdate)
5532            throws DatabaseException {
5533
5534            PrimaryIndex<Integer,AddEnumConstant_Entity>
5535                index = store.getPrimaryIndex
5536                    (Integer.class,
5537                     AddEnumConstant_Entity.class);
5538            AddEnumConstant_Entity obj = index.get(99);
5539            TestCase.assertNotNull(obj);
5540            TestCase.assertEquals(99, obj.key);
5541            TestCase.assertSame(AddEnumConstant_Enum.A, obj.e1);
5542            TestCase.assertSame(AddEnumConstant_Enum.B, obj.e2);
5543            TestCase.assertSame(AddEnumConstant_Enum.C, obj.e3);
5544
5545            if (doUpdate) {
5546                index.put(obj);
5547            }
5548        }
5549
5550        @Override
5551        void copyRawObjects(RawStore rawStore, EntityStore newStore)
5552            throws DatabaseException {
5553
5554            PrimaryIndex<Integer,AddEnumConstant_Entity>
5555                index = newStore.getPrimaryIndex
5556                    (Integer.class,
5557                     AddEnumConstant_Entity.class);
5558            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
5559            index.put((AddEnumConstant_Entity)
5560                      newStore.getModel().convertRawObject(raw));
5561        }
5562
5563        @Override
5564        void readRawObjects(RawStore store,
5565                            boolean expectEvolved,
5566                            boolean expectUpdated)
5567            throws DatabaseException {
5568
5569            RawObject obj = readRaw
5570                (store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
5571            RawType enumType = store.getModel().getRawType(NAME2);
5572            if (expectUpdated) {
5573                checkRawFields(obj, "key", 99,
5574                               "e1", new RawObject(enumType, "A"),
5575                               "e2", new RawObject(enumType, "B"),
5576                               "e3", new RawObject(enumType, "C"));
5577            } else {
5578                checkRawFields(obj, "key", 99,
5579                               "e1", new RawObject(enumType, "A"),
5580                               "e2", new RawObject(enumType, "B"));
5581            }
5582        }
5583    }
5584
5585    enum DeleteEnumConstant_Enum {
5586        A, C;
5587    }
5588
5589    /**
5590     * For now we don't allow deleting enum values.  This test case has code
5591     * for testing conversions, for when we add versioning to enums.
5592     */
5593    @Entity
5594    static class DeleteEnumConstant_NoMutation
5595        extends EvolveCase {
5596
5597        private static final String NAME =
5598            DeleteEnumConstant_NoMutation.class.getName();
5599        private static final String NAME2 =
5600            DeleteEnumConstant_Enum.class.getName();
5601
5602        @PrimaryKey
5603        int key;
5604
5605        DeleteEnumConstant_Enum e1;
5606        DeleteEnumConstant_Enum e2;
5607        DeleteEnumConstant_Enum e3;
5608
5609        @Override
5610        public String getStoreOpenException() {
5611            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]";
5612        }
5613
5614            /*
5615            Mutation is missing to evolve class: com.sleepycat.persist.test.EvolveClasses$DeleteEnumConstant_Enum version: 0 to class: com.sleepycat.persist.test.EvolveClasses$DeleteEnumConstant_Enum version: 0 Error: Converter is required when a value is removed from an enum: [B]
5616            */
5617
5618        /*
5619        @Override
5620        Mutations getMutations() {
5621            Mutations m = new Mutations();
5622            Converter converter = new Converter(NAME2, 0, new MyConversion());
5623            m.addConverter(converter);
5624            return m;
5625        }
5626        */
5627
5628        static class MyConversion implements Conversion {
5629
5630            transient RawType newType;
5631
5632            public void initialize(EntityModel model) {
5633                newType = model.getRawType(NAME2);
5634                TestCase.assertNotNull(newType);
5635            }
5636
5637            public Object convert(Object fromValue) {
5638                TestCase.assertNotNull(newType);
5639                RawObject obj = (RawObject) fromValue;
5640                String val = obj.getEnum();
5641                TestCase.assertNotNull(val);
5642                if ("B".equals(val)) {
5643                    val = "C";
5644                }
5645                return new RawObject(newType, val);
5646            }
5647
5648            @Override
5649            public boolean equals(Object other) {
5650                return other instanceof MyConversion;
5651            }
5652        }
5653
5654        @Override
5655        void checkEvolvedModel(EntityModel model,
5656                               Environment env,
5657                               boolean oldTypesExist) {
5658            checkEntity(true, model, env, NAME, 0, null);
5659            checkVersions(model, NAME, 0);
5660            if (oldTypesExist) {
5661                checkVersions(model, NAME2, 0, NAME2, 0);
5662            } else {
5663                checkVersions(model, NAME2, 0);
5664            }
5665        }
5666
5667        @Override
5668        void readObjects(EntityStore store, boolean doUpdate)
5669            throws DatabaseException {
5670
5671            PrimaryIndex<Integer,DeleteEnumConstant_NoMutation>
5672                index = store.getPrimaryIndex
5673                    (Integer.class,
5674                     DeleteEnumConstant_NoMutation.class);
5675            DeleteEnumConstant_NoMutation obj = index.get(99);
5676            TestCase.assertNotNull(obj);
5677            TestCase.assertEquals(99, obj.key);
5678            TestCase.assertSame(DeleteEnumConstant_Enum.A, obj.e1);
5679            TestCase.assertSame(DeleteEnumConstant_Enum.C, obj.e2);
5680            TestCase.assertSame(DeleteEnumConstant_Enum.C, obj.e3);
5681
5682            if (doUpdate) {
5683                index.put(obj);
5684            }
5685        }
5686
5687        @Override
5688        void copyRawObjects(RawStore rawStore, EntityStore newStore)
5689            throws DatabaseException {
5690
5691            PrimaryIndex<Integer,DeleteEnumConstant_NoMutation>
5692                index = newStore.getPrimaryIndex
5693                    (Integer.class,
5694                     DeleteEnumConstant_NoMutation.class);
5695            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
5696            index.put((DeleteEnumConstant_NoMutation)
5697                      newStore.getModel().convertRawObject(raw));
5698        }
5699
5700        @Override
5701        void readRawObjects(RawStore store,
5702                            boolean expectEvolved,
5703                            boolean expectUpdated)
5704            throws DatabaseException {
5705
5706            RawObject obj = readRaw(store, 99, NAME, 0, CASECLS, 0);
5707            RawType enumType = store.getModel().getRawType(NAME2);
5708            if (expectEvolved) {
5709                checkRawFields(obj, "key", 99,
5710                               "e1", new RawObject(enumType, "A"),
5711                               "e2", new RawObject(enumType, "C"),
5712                               "e3", new RawObject(enumType, "C"));
5713            } else {
5714                checkRawFields(obj, "key", 99,
5715                               "e1", new RawObject(enumType, "A"),
5716                               "e2", new RawObject(enumType, "B"),
5717                               "e3", new RawObject(enumType, "C"));
5718            }
5719        }
5720    }
5721
5722    @Entity
5723    static class DisallowChangeKeyRelate
5724        extends EvolveCase {
5725
5726        private static final String NAME =
5727            DisallowChangeKeyRelate.class.getName();
5728
5729        @PrimaryKey
5730        int key;
5731
5732        @SecondaryKey(relate=MANY_TO_ONE)
5733        int skey;
5734
5735        @Override
5736        public String getStoreOpenException() {
5737            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";
5738        }
5739    }
5740
5741    @Entity(version=1)
5742    static class AllowChangeKeyMetadata
5743        extends EvolveCase {
5744
5745        private static final String NAME =
5746            AllowChangeKeyMetadata.class.getName();
5747
5748        @PrimaryKey
5749        int key;
5750
5751        /*
5752         * Combined fields from version 0 and 1:
5753         *  addAnnotation = 88;
5754         *  dropField = 77;
5755         *  dropAnnotation = 66;
5756         *  addField = 55;
5757         *  aa = 33;
5758         *  ff = 22;
5759         */
5760
5761        int aa;
5762
5763        @SecondaryKey(relate=ONE_TO_ONE)
5764        int addAnnotation;
5765
5766        int dropAnnotation;
5767
5768        @SecondaryKey(relate=ONE_TO_ONE)
5769        Integer addField;
5770
5771        int ff;
5772
5773        @Override
5774        Mutations getMutations() {
5775            Mutations m = new Mutations();
5776            m.addDeleter(new Deleter(NAME, 0, "dropField"));
5777            return m;
5778        }
5779
5780        @Override
5781        void checkEvolvedModel(EntityModel model,
5782                               Environment env,
5783                               boolean oldTypesExist) {
5784            checkEntity(true, model, env, NAME, 1, null);
5785            if (oldTypesExist) {
5786                checkVersions(model, NAME, 1, NAME, 0);
5787            } else {
5788                checkVersions(model, NAME, 1);
5789            }
5790        }
5791
5792        @Override
5793        void readObjects(EntityStore store, boolean doUpdate)
5794            throws DatabaseException {
5795
5796            PrimaryIndex<Integer,AllowChangeKeyMetadata>
5797                index = store.getPrimaryIndex
5798                    (Integer.class,
5799                     AllowChangeKeyMetadata.class);
5800            AllowChangeKeyMetadata obj = index.get(99);
5801            checkValues(obj);
5802
5803            checkValues(store.getSecondaryIndex
5804                (index, Integer.class, "addAnnotation").get(88));
5805            if (updated) {
5806                checkValues(store.getSecondaryIndex
5807                    (index, Integer.class, "addField").get(55));
5808            } else {
5809                TestCase.assertNull(store.getSecondaryIndex
5810                    (index, Integer.class, "addField").get(55));
5811            }
5812
5813            if (doUpdate) {
5814                obj.addField = 55;
5815                index.put(obj);
5816                updated = true;
5817                checkValues(store.getSecondaryIndex
5818                    (index, Integer.class, "addAnnotation").get(88));
5819                checkValues(store.getSecondaryIndex
5820                    (index, Integer.class, "addField").get(55));
5821            }
5822        }
5823
5824        @Override
5825        void copyRawObjects(RawStore rawStore, EntityStore newStore)
5826            throws DatabaseException {
5827
5828            PrimaryIndex<Integer,AllowChangeKeyMetadata>
5829                index = newStore.getPrimaryIndex
5830                    (Integer.class,
5831                     AllowChangeKeyMetadata.class);
5832            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
5833            index.put((AllowChangeKeyMetadata)
5834                      newStore.getModel().convertRawObject(raw));
5835        }
5836
5837        private void checkValues(AllowChangeKeyMetadata obj) {
5838            TestCase.assertNotNull(obj);
5839            TestCase.assertEquals(99, obj.key);
5840            TestCase.assertEquals(88, obj.addAnnotation);
5841            TestCase.assertEquals(66, obj.dropAnnotation);
5842            TestCase.assertEquals(33, obj.aa);
5843            TestCase.assertEquals(22, obj.ff);
5844            if (updated) {
5845                TestCase.assertEquals(Integer.valueOf(55), obj.addField);
5846            } else {
5847                TestCase.assertNull(obj.addField);
5848            }
5849        }
5850
5851        @Override
5852        void readRawObjects(RawStore store,
5853                            boolean expectEvolved,
5854                            boolean expectUpdated)
5855            throws DatabaseException {
5856
5857            RawObject obj = readRaw
5858                (store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
5859            if (expectUpdated) {
5860                checkRawFields(obj, "key", 99,
5861                               "addAnnotation", 88,
5862                               "dropAnnotation", 66,
5863                               "addField", 55,
5864                               "aa", 33,
5865                               "ff", 22);
5866            } else if (expectEvolved) {
5867                checkRawFields(obj, "key", 99,
5868                               "addAnnotation", 88,
5869                               "dropAnnotation", 66,
5870                               "aa", 33,
5871                               "ff", 22);
5872            } else {
5873                checkRawFields(obj, "key", 99,
5874                               "addAnnotation", 88,
5875                               "dropField", 77,
5876                               "dropAnnotation", 66,
5877                               "aa", 33,
5878                               "ff", 22);
5879            }
5880            Environment env = store.getEnvironment();
5881            assertDbExists(expectEvolved, env, NAME, "addAnnotation");
5882            assertDbExists(expectEvolved, env, NAME, "addField");
5883            assertDbExists(!expectEvolved, env, NAME, "dropField");
5884            assertDbExists(!expectEvolved, env, NAME, "dropAnnotation");
5885        }
5886    }
5887
5888    /** [#15524] */
5889    @Entity(version=1)
5890    static class AllowAddSecondary
5891        extends EvolveCase {
5892
5893        private static final String NAME =
5894            AllowAddSecondary.class.getName();
5895
5896        @PrimaryKey
5897        long key;
5898
5899        @SecondaryKey(relate=ONE_TO_ONE)
5900        int a;
5901
5902        @SecondaryKey(relate=ONE_TO_ONE)
5903        int b;
5904
5905        @Override
5906        void checkEvolvedModel(EntityModel model,
5907                               Environment env,
5908                               boolean oldTypesExist) {
5909            checkEntity(true, model, env, NAME, 1, null);
5910            if (oldTypesExist) {
5911                checkVersions(model, NAME, 1, NAME, 0);
5912            } else {
5913                checkVersions(model, NAME, 1);
5914            }
5915        }
5916
5917        @Override
5918        void readObjects(EntityStore store, boolean doUpdate)
5919            throws DatabaseException {
5920
5921            PrimaryIndex<Long,AllowAddSecondary>
5922                index = store.getPrimaryIndex
5923                    (Long.class,
5924                     AllowAddSecondary.class);
5925            AllowAddSecondary obj = index.get(99L);
5926            checkValues(obj);
5927
5928            checkValues(store.getSecondaryIndex
5929                (index, Integer.class, "a").get(1));
5930            if (updated) {
5931                checkValues(store.getSecondaryIndex
5932                    (index, Integer.class, "b").get(3));
5933                TestCase.assertNull(store.getSecondaryIndex
5934                    (index, Integer.class, "b").get(2));
5935            } else {
5936                checkValues(store.getSecondaryIndex
5937                    (index, Integer.class, "b").get(2));
5938                TestCase.assertNull(store.getSecondaryIndex
5939                    (index, Integer.class, "b").get(3));
5940            }
5941
5942            if (doUpdate) {
5943                obj.b = 3;
5944                index.put(obj);
5945                updated = true;
5946                checkValues(store.getSecondaryIndex
5947                    (index, Integer.class, "a").get(1));
5948                checkValues(store.getSecondaryIndex
5949                    (index, Integer.class, "b").get(3));
5950            }
5951        }
5952
5953        @Override
5954        void copyRawObjects(RawStore rawStore, EntityStore newStore)
5955            throws DatabaseException {
5956
5957            PrimaryIndex<Long,AllowAddSecondary>
5958                index = newStore.getPrimaryIndex
5959                    (Long.class,
5960                     AllowAddSecondary.class);
5961            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99L);
5962            index.put((AllowAddSecondary)
5963                      newStore.getModel().convertRawObject(raw));
5964        }
5965
5966        private void checkValues(AllowAddSecondary obj) {
5967            TestCase.assertNotNull(obj);
5968            TestCase.assertEquals(99L, obj.key);
5969            TestCase.assertEquals(1, obj.a);
5970            if (updated) {
5971                TestCase.assertEquals(3, obj.b);
5972            } else {
5973                TestCase.assertEquals(2, obj.b);
5974            }
5975        }
5976
5977        @Override
5978        void readRawObjects(RawStore store,
5979                            boolean expectEvolved,
5980                            boolean expectUpdated)
5981            throws DatabaseException {
5982
5983            RawObject obj = readRaw
5984                (store, 99L, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
5985            if (expectUpdated) {
5986                checkRawFields(obj, "key", 99L,
5987                               "a", 1,
5988                               "b", 3);
5989            } else {
5990                checkRawFields(obj, "key", 99L,
5991                               "a", 1,
5992                               "b", 2);
5993            }
5994            Environment env = store.getEnvironment();
5995            assertDbExists(expectEvolved, env, NAME, "a");
5996            assertDbExists(expectEvolved, env, NAME, "b");
5997        }
5998    }
5999
6000    @Entity(version=1)
6001    static class FieldAddAndConvert
6002        extends EvolveCase {
6003
6004        private static final String NAME =
6005            FieldAddAndConvert.class.getName();
6006
6007        @PrimaryKey
6008        int key;
6009
6010        private String f0 = "0"; // new field
6011        private String f1 = "1"; // converted field
6012        private String f2 = "2"; // new field
6013        private String f3 = "3"; // converted field
6014        private String f4 = "4"; // new field
6015
6016        @Override
6017        Mutations getMutations() {
6018            Mutations m = new Mutations();
6019            m.addConverter(new Converter(NAME, 0, "f1", new IntToString()));
6020            m.addConverter(new Converter(NAME, 0, "f3", new IntToString()));
6021            return m;
6022        }
6023
6024        private static class IntToString implements Conversion {
6025
6026            public void initialize(EntityModel model) {
6027            }
6028
6029            public Object convert(Object fromValue) {
6030                return fromValue.toString();
6031            }
6032
6033            @Override
6034            public boolean equals(Object other) {
6035                return other instanceof IntToString;
6036            }
6037        }
6038
6039        @Override
6040        void checkEvolvedModel(EntityModel model,
6041                               Environment env,
6042                               boolean oldTypesExist) {
6043            checkEntity(true, model, env, NAME, 1, null);
6044            if (oldTypesExist) {
6045                checkVersions(model, NAME, 1, NAME, 0);
6046            } else {
6047                checkVersions(model, NAME, 1);
6048            }
6049        }
6050
6051        @Override
6052        void readObjects(EntityStore store, boolean doUpdate)
6053            throws DatabaseException {
6054
6055            PrimaryIndex<Integer,FieldAddAndConvert>
6056                index = store.getPrimaryIndex
6057                    (Integer.class,
6058                     FieldAddAndConvert.class);
6059            FieldAddAndConvert obj = index.get(99);
6060            TestCase.assertNotNull(obj);
6061            TestCase.assertEquals(99, obj.key);
6062            TestCase.assertEquals("0", obj.f0);
6063            TestCase.assertEquals("1", obj.f1);
6064            TestCase.assertEquals("2", obj.f2);
6065            TestCase.assertEquals("3", obj.f3);
6066            TestCase.assertEquals("4", obj.f4);
6067
6068            if (doUpdate) {
6069                index.put(obj);
6070            }
6071        }
6072
6073        @Override
6074        void copyRawObjects(RawStore rawStore, EntityStore newStore)
6075            throws DatabaseException {
6076
6077            PrimaryIndex<Integer,FieldAddAndConvert>
6078                index = newStore.getPrimaryIndex
6079                    (Integer.class,
6080                     FieldAddAndConvert.class);
6081            RawObject raw = rawStore.getPrimaryIndex(NAME).get(99);
6082            index.put((FieldAddAndConvert)
6083                      newStore.getModel().convertRawObject(raw));
6084        }
6085
6086        @Override
6087        void readRawObjects(RawStore store,
6088                            boolean expectEvolved,
6089                            boolean expectUpdated)
6090            throws DatabaseException {
6091
6092            RawObject obj = readRaw
6093                (store, 99, NAME, expectEvolved ? 1 : 0, CASECLS, 0);
6094            if (expectUpdated) {
6095                checkRawFields(obj,
6096                               "key", 99,
6097                               "f0", "0",
6098                               "f1", "1",
6099                               "f2", "2",
6100                               "f3", "3",
6101                               "f4", "4");
6102            } else if (expectEvolved) {
6103                checkRawFields(obj,
6104                               "key", 99,
6105                               "f1", "1",
6106                               "f3", "3");
6107            } else {
6108                checkRawFields(obj,
6109                               "key", 99,
6110                               "f1", 1,
6111                               "f3", 3);
6112            }
6113        }
6114    }
6115}
6116