This Bugzilla instance is deprecated, and most Eclipse projects now use GitHub or Eclipse GitLab. Please see the deprecation plan for details.
View | Details | Raw Unified | Return to bug 290567 | Differences between
and this patch

Collapse All | Expand All

(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/ClassDescriptor.java (-12 / +20 lines)
Lines 180-187 Link Here
180
    /** Allow zero primary key validation to be configured. */
180
    /** Allow zero primary key validation to be configured. */
181
    protected IdValidation idValidation;
181
    protected IdValidation idValidation;
182
    
182
    
183
    //bug241765: JPA 2.0 Derived identities - check if any mappings are marked as a derived id
183
    // JPA 2.0 Derived identities - map of mappings that act as derived ids
184
    protected boolean hasDerivedId;
184
    protected Map<String, DatabaseMapping> derivesIdMappings;
185
    
185
    
186
    //Added for interceptor support.
186
    //Added for interceptor support.
187
    protected Class cacheInterceptorClass;
187
    protected Class cacheInterceptorClass;
Lines 252-258 Link Here
252
        this.shouldAlwaysConformResultsInUnitOfWork = false;
252
        this.shouldAlwaysConformResultsInUnitOfWork = false;
253
        this.shouldAcquireCascadedLocks = false;
253
        this.shouldAcquireCascadedLocks = false;
254
        this.hasSimplePrimaryKey = false;
254
        this.hasSimplePrimaryKey = false;
255
        this.hasDerivedId = false;
255
        this.derivesIdMappings = new HashMap(5);
256
256
257
        // Policies
257
        // Policies
258
        this.objectBuilder = new ObjectBuilder(this);
258
        this.objectBuilder = new ObjectBuilder(this);
Lines 1890-1895 Link Here
1890
    }
1890
    }
1891
1891
1892
    /**
1892
    /**
1893
     * ADVANCED:
1894
     * Return the derives id mappings.
1895
     */
1896
    public Collection<DatabaseMapping> getDerivesIdMappinps() {
1897
        return derivesIdMappings.values();
1898
    }
1899
    
1900
    /**
1893
     * PUBLIC:
1901
     * PUBLIC:
1894
     * Get the event manager for the descriptor.  The event manager is responsible
1902
     * Get the event manager for the descriptor.  The event manager is responsible
1895
     * for managing the pre/post selectors.
1903
     * for managing the pre/post selectors.
Lines 2467-2477 Link Here
2467
2475
2468
    /**
2476
    /**
2469
     * INTERNAL:
2477
     * INTERNAL:
2470
     * returns true if users have designated one or more mappings as IDs.  Used for CMP3Policy 
2478
     * returns true if users have designated one or more mappings as IDs. Used 
2471
     * primary key class processing. 
2479
     * for CMP3Policy primary key class processing. 
2472
     */
2480
     */
2473
    public boolean hasDerivedId() {
2481
    public boolean hasDerivedId() {
2474
        return this.hasDerivedId;
2482
        return ! derivesIdMappings.isEmpty();
2475
    }
2483
    }
2476
    
2484
    
2477
    /**
2485
    /**
Lines 2621-2629 Link Here
2621
                prepareCascadeLockingPolicy(mapping);
2629
                prepareCascadeLockingPolicy(mapping);
2622
            }
2630
            }
2623
2631
2624
            //bug241765: JPA 2.0 Derived identities - check if any mappings are marked as an ID
2632
            // JPA 2.0 Derived identities - build a map of derived id mappings.
2625
            if (mapping.isDerivedIdMapping()){
2633
            if (mapping.derivesId()) {
2626
                this.hasDerivedId = true;
2634
                derivesIdMappings.put(mapping.getAttributeName(), mapping);
2627
            }
2635
            }
2628
            
2636
            
2629
            // Add all the fields in the mapping to myself.
2637
            // Add all the fields in the mapping to myself.
Lines 2661-2669 Link Here
2661
                    if (mapping.isAggregateObjectMapping() || ((mapping.isForeignReferenceMapping() && (!mapping.isDirectCollectionMapping())) && (!((ForeignReferenceMapping)mapping).usesIndirection()))) {
2669
                    if (mapping.isAggregateObjectMapping() || ((mapping.isForeignReferenceMapping() && (!mapping.isDirectCollectionMapping())) && (!((ForeignReferenceMapping)mapping).usesIndirection()))) {
2662
                        getLockableMappings().add(mapping);// add those mappings from the parent.
2670
                        getLockableMappings().add(mapping);// add those mappings from the parent.
2663
                    }
2671
                    }
2664
                    //bug241765: JPA 2.0 Derived identities - check if any mappings are marked as an ID
2672
                    // JPA 2.0 Derived identities - build a map of derived id mappings.
2665
                    if (mapping.isDerivedIdMapping()) {
2673
                    if (mapping.derivesId()) {
2666
                        this.hasDerivedId = true;
2674
                        derivesIdMappings.put(mapping.getAttributeName(), mapping);
2667
                    }
2675
                    }
2668
                }
2676
                }
2669
            }
2677
            }
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/CMPPolicy.java (-7 / +7 lines)
Lines 317-336 Link Here
317
        
317
        
318
        Object keyInstance = getPKClassInstance();
318
        Object keyInstance = getPKClassInstance();
319
        for (int index = 0; index < pkElementArray.length; index++) {
319
        for (int index = 0; index < pkElementArray.length; index++) {
320
            Object keyObj = key;
320
            KeyElementAccessor accessor = pkElementArray[index];
321
            KeyElementAccessor accessor = pkElementArray[index];
321
            DatabaseMapping mapping = builder.getMappingForAttributeName(accessor.getAttributeName());
322
            DatabaseField field = accessor.getDatabaseField();
323
            DatabaseMapping mapping = builder.getMappingForField(field);
324
            
322
            // With session validation, the mapping shouldn't be null at this 
325
            // With session validation, the mapping shouldn't be null at this 
323
            // point, don't bother checking.
326
            // point, don't bother checking.
324
            
327
            
325
            while (mapping.isAggregateObjectMapping()) {
328
            while (mapping.isAggregateObjectMapping()) {
326
                mapping = mapping.getReferenceDescriptor().getObjectBuilder().getMappingForAttributeName(pkElementArray[index].getAttributeName());
329
                keyObj = mapping.getRealAttributeValueFromObject(keyObj, session);
327
            
330
                mapping = mapping.getReferenceDescriptor().getObjectBuilder().getMappingForField(accessor.getDatabaseField());
328
                if (mapping == null) { // must be aggregate
329
                    mapping = builder.getMappingForField(accessor.getDatabaseField());
330
                }
331
            }
331
            }
332
            
332
            
333
            Object fieldValue = mapping.getRealAttributeValueFromObject(key, session);
333
            Object fieldValue = mapping.getRealAttributeValueFromObject(keyObj, session);
334
            accessor.setValue(keyInstance, fieldValue);
334
            accessor.setValue(keyInstance, fieldValue);
335
        }
335
        }
336
        
336
        
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/sessions/UnitOfWorkImpl.java (-1 / +59 lines)
Lines 607-612 Link Here
607
            
607
            
608
            ClassDescriptor descriptor = getDescriptor(object);
608
            ClassDescriptor descriptor = getDescriptor(object);
609
609
610
            // Update any derived id's.
611
            updateDerivedIds(object, descriptor);
612
            
610
            // Block of code removed for code coverage, as it would never have been touched. bug # 2903600
613
            // Block of code removed for code coverage, as it would never have been touched. bug # 2903600
611
            
614
            
612
            boolean isNew = isObjectNew(object);
615
            boolean isNew = isObjectNew(object);
Lines 4153-4158 Link Here
4153
                this.undeleteObject(newObject);
4156
                this.undeleteObject(newObject);
4154
            }
4157
            }
4155
            descriptor.getObjectBuilder().cascadeRegisterNewForCreate(newObject, this, visitedObjects);
4158
            descriptor.getObjectBuilder().cascadeRegisterNewForCreate(newObject, this, visitedObjects);
4159
            // After any cascade persists and assigning any sequence numbers,
4160
            // update any derived id attributes on the new object.
4161
            updateDerivedIds(newObject, descriptor);
4156
        } finally {
4162
        } finally {
4157
            endOperationProfile(SessionProfiler.Register);
4163
            endOperationProfile(SessionProfiler.Register);
4158
        }
4164
        }
Lines 4229-4235 Link Here
4229
            descriptor.getEventManager().executeEvent(event);
4235
            descriptor.getEventManager().executeEvent(event);
4230
        }  
4236
        }  
4231
    }
4237
    }
4232
4238
    
4233
    /**
4239
    /**
4234
     * INTERNAL:
4240
     * INTERNAL:
4235
     * Add the new object to the cache if set to.
4241
     * Add the new object to the cache if set to.
Lines 5287-5292 Link Here
5287
    }
5293
    }
5288
5294
5289
    /**
5295
    /**
5296
     * INTERNAL:
5297
     * On persist and flush operations we must update any derived id fields.
5298
     */
5299
    protected Object updateDerivedIds(Object clone, ClassDescriptor descriptor) {
5300
        if (descriptor.hasDerivedId()) {
5301
            ObjectBuilder dependentBuilder = descriptor.getObjectBuilder();
5302
            
5303
            for (DatabaseMapping derivesIdMapping : descriptor.getDerivesIdMappinps()) {
5304
                DatabaseMapping derivedIdMapping = derivesIdMapping.getDerivedIdMapping();
5305
                
5306
                // If there is no derived id mapping, then there is no update required. Case #1a-#6a 
5307
                // from the JPA spec.
5308
                if (derivedIdMapping != null) {
5309
                    ClassDescriptor parentDescriptor = derivesIdMapping.getReferenceDescriptor();
5310
                    ObjectBuilder parentBuilder = parentDescriptor.getObjectBuilder();
5311
                    Object parentClone = derivesIdMapping.getRealAttributeValueFromObject(clone, this);
5312
                    
5313
                    // If the parent clone is null, we don't have any work to do, continue to the next 
5314
                    // mapping. Some mappings may be part of a composite primary key that allows for a 
5315
                    // null setting or the mapping may just not be set.
5316
                    if (parentClone != null) {
5317
                        Object key;
5318
                        // Recurse up the chain to figure out the key. The first dependent will figure 
5319
                        // it out and pass it to its sub-dependents (keeping it the same)
5320
                        if (parentDescriptor.hasDerivedId()) {
5321
                            key = updateDerivedIds(parentClone, parentDescriptor);
5322
                        } else {
5323
                            key = parentDescriptor.getCMPPolicy().createPrimaryKeyInstance(parentClone, this);
5324
                        }
5325
                        
5326
                        if (derivesIdMapping.hasMapsIdValue()) {
5327
                            // Case #1b, #2b and #3b from the JPA spec. The derived id is within our 
5328
                            // embedded id. We need to deal with that object and its mapping within the clone.
5329
                            Object aggregateClone = derivedIdMapping.getRealAttributeValueFromObject(clone, this);
5330
                            DatabaseMapping aggregateMapping = derivedIdMapping.getReferenceDescriptor().getMappingForAttributeName(derivesIdMapping.getMapsIdValue());
5331
                            aggregateMapping.setRealAttributeValueInObject(aggregateClone, key);
5332
                        } else {
5333
                            // Case #4b, #5b, #6b from the JPA spec. Our id mapping is the derived id. 
5334
                            // We will deal with the clone provided.
5335
                            derivedIdMapping.setRealAttributeValueInObject(clone, key);
5336
                        }
5337
                        
5338
                        return key;
5339
                    }
5340
                }
5341
            }
5342
        }
5343
        
5344
        return null;
5345
    }
5346
    
5347
    /**
5290
     * ADVANCED:
5348
     * ADVANCED:
5291
     * This can be used to help debugging an object-space corruption.
5349
     * This can be used to help debugging an object-space corruption.
5292
     * An object-space corruption is when your application has incorrectly related a clone to an original object.
5350
     * An object-space corruption is when your application has incorrectly related a clone to an original object.
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/mappings/DatabaseMapping.java (-29 / +83 lines)
Lines 92-106 Link Here
92
    protected Map properties;
92
    protected Map properties;
93
    
93
    
94
    /**
94
    /**
95
     * Used by the CMP3Policy to see if this mapping should be used in processing pk classes 
95
     * Used by the CMP3Policy to see if this mapping should be used in 
96
     * for find methods.  
96
     * processing pk classes for find methods
97
     */
97
     */
98
    protected boolean isDerivedIdMapping = false;
98
    protected boolean derivesId;
99
    
99
    
100
    /**
100
    /**
101
     * 
102
     */
103
    protected boolean isJPAId = false;
104
    
105
    /**
101
     * A mapsId value.
106
     * A mapsId value.
102
     */
107
     */
103
    protected String mappedByIdValue;
108
    protected String mapsIdValue;
109
    
110
    /**
111
     * The id mapping this mapping derives. Used by the CMP3Policy to see if 
112
     * this mapping should be used in processing pk classes for find methods.
113
     */
114
    protected DatabaseMapping derivedIdMapping;
104
115
105
    /**
116
    /**
106
     * PERF: Used as a quick check to see if this mapping is a primary key mapping,
117
     * PERF: Used as a quick check to see if this mapping is a primary key mapping,
Lines 336-341 Link Here
336
    }
347
    }
337
348
338
    /**
349
    /**
350
     * ADVANCED:
351
     * Returns true if the mapping references a JPA ID attribute for the CMP3Policy and JPA ID classes.  
352
     */
353
    public boolean derivesId() {
354
        return derivesId;
355
    }
356
    
357
    /**
339
     * INTERNAL:
358
     * INTERNAL:
340
     * This method is called to update collection tables prior to commit.
359
     * This method is called to update collection tables prior to commit.
341
     */
360
     */
Lines 473-478 Link Here
473
    }
492
    }
474
493
475
    /**
494
    /**
495
     * ADVANCED:
496
     * Set the maps id value  
497
     */
498
    public DatabaseMapping getDerivedIdMapping() {
499
        return derivedIdMapping;
500
    }
501
    
502
    /**
476
     * INTERNAL:
503
     * INTERNAL:
477
     * Return the descriptor to which this mapping belongs
504
     * Return the descriptor to which this mapping belongs
478
     */
505
     */
Lines 543-558 Link Here
543
     * ADVANCED:
570
     * ADVANCED:
544
     * Set the mapped by id value  
571
     * Set the mapped by id value  
545
     */
572
     */
546
    public boolean hasMappedByIdValue() {
573
    public boolean hasMapsIdValue() {
547
        return mappedByIdValue != null;
574
        return mapsIdValue != null;
548
    }
575
    }
549
    
576
    
550
    /**
577
    /**
551
     * ADVANCED:
578
     * ADVANCED:
552
     * Set the mapped by id value  
579
     * Set the mapped by id value  
553
     */
580
     */
554
    public String getMappedByIdValue() {
581
    public String getMapsIdValue() {
555
        return mappedByIdValue;
582
        return mapsIdValue;
556
    }
583
    }
557
    
584
    
558
    /**
585
    /**
Lines 747-760 Link Here
747
    public boolean isDatabaseMapping() {
774
    public boolean isDatabaseMapping() {
748
        return true;
775
        return true;
749
    }
776
    }
750
751
    /**
752
     * ADVANCED:
753
     * Returns true if the mapping references a JPA ID attribute for the CMP3Policy and JPA ID classes.  
754
     */
755
    public boolean isDerivedIdMapping() {
756
        return this.isDerivedIdMapping;
757
    }
758
    
777
    
759
    /**
778
    /**
760
     * INTERNAL:
779
     * INTERNAL:
Lines 860-865 Link Here
860
    }
879
    }
861
880
862
    /**
881
    /**
882
     * INTERNAL:
883
     * Flags that this mapping is part of a JPA id mapping. It should be
884
     * temporary though, as the CMP3Policy should be able to figure things 
885
     * out on its own. The problem being that the JPA mapped superclass
886
     * descriptors are not initialize and do not have a CMP3Policy set by
887
     * default. 
888
     */
889
    public boolean isJPAId() {
890
        return isJPAId;
891
    }
892
    
893
    /**
863
     * Return if this mapping is lazy.
894
     * Return if this mapping is lazy.
864
     * Lazy has different meaning for different mappings.
895
     * Lazy has different meaning for different mappings.
865
     * For basic/direct mappings, this can be used exclude it from the descriptor's
896
     * For basic/direct mappings, this can be used exclude it from the descriptor's
Lines 881-895 Link Here
881
    }
912
    }
882
    
913
    
883
    /**
914
    /**
884
     * ADVANCED:
915
     * INTERNAL:
885
     * Used to indicate the mapping references a JPA ID or MapsId attribute 
916
     * Flags that this mapping is part of a JPA id mapping. It should be
886
     * for the CMP3Policy and JPA Id classes (as well as Embeddable Id classes). 
917
     * temporary though, as the CMP3Policy should be able to figure things 
887
     * This is different from isPrimaryKeyMapping, as an ID mapping is user 
918
     * out on its own. The problem being that the JPA mapped superclass
888
     * specified and can be read only, as long as another writable mapping for 
919
     * descriptors are not initialize and do not have a CMP3Policy set by
889
     * the field exists.  
920
     * default. 
890
     */
921
     */
891
    public void setIsDerivedIdMapping(boolean isDerivedIdMapping) {
922
    public void setIsJPAId() {
892
        this.isDerivedIdMapping = isDerivedIdMapping;
923
        this.isJPAId = true;
893
    }
924
    }
894
    
925
    
895
    /**
926
    /**
Lines 1409-1422 Link Here
1409
    public void setIsReadOnly(boolean aBoolean) {
1440
    public void setIsReadOnly(boolean aBoolean) {
1410
        isReadOnly = aBoolean;
1441
        isReadOnly = aBoolean;
1411
    }
1442
    }
1412
1443
    
1413
    /**
1444
    /**
1414
     * ADVANCED:
1445
     * ADVANCED:
1415
     * Set the mapped by id value  
1446
     * Set the maps id value  
1416
     */
1447
     */
1417
    public void setMappedByIdValue(String mappedByIdValue) {
1448
    public void setMapsIdValue(String mapsIdValue) {
1418
        setIsDerivedIdMapping(true);
1449
        this.mapsIdValue = mapsIdValue;
1419
        this.mappedByIdValue = mappedByIdValue;
1420
    }
1450
    }
1421
    
1451
    
1422
    /**
1452
    /**
Lines 1669-1674 Link Here
1669
    }
1699
    }
1670
1700
1671
    /**
1701
    /**
1702
     * ADVANCED:
1703
     * Used to indicate the mapping references a JPA ID or MapsId attribute 
1704
     * for the CMP3Policy and JPA Id classes (as well as Embeddable Id classes). 
1705
     * This is different from isPrimaryKeyMapping, as an ID mapping is user 
1706
     * specified and can be read only, as long as another writable mapping for 
1707
     * the field exists.  
1708
     */
1709
    public void setDerivesId(boolean derivesId) {
1710
        this.derivesId = derivesId;
1711
    }
1712
    
1713
    /**
1714
     * ADVANCED:
1715
     * Used to indicate the mapping references a JPA ID or MapsId attribute 
1716
     * for the CMP3Policy and JPA Id classes (as well as Embeddable Id classes). 
1717
     * This is different from isPrimaryKeyMapping, as an ID mapping is user 
1718
     * specified and can be read only, as long as another writable mapping for 
1719
     * the field exists.  
1720
     */
1721
    public void setDerivedIdMapping(DatabaseMapping derivedIdMapping) {
1722
        this.derivedIdMapping = derivedIdMapping;
1723
    }
1724
    
1725
    /**
1672
     * INTERNAL:
1726
     * INTERNAL:
1673
     * Directly build a change record without comparison
1727
     * Directly build a change record without comparison
1674
     */
1728
     */
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/compositepk/CompositePKTableCreator.java (+28 lines)
Lines 40-45 Link Here
40
        addTableDefinition(buildLIEUTENANTGENERALTable());
40
        addTableDefinition(buildLIEUTENANTGENERALTable());
41
        addTableDefinition(buildLIEUTENANTTable());
41
        addTableDefinition(buildLIEUTENANTTable());
42
        addTableDefinition(buildSECONDLIEUTENANTTable());
42
        addTableDefinition(buildSECONDLIEUTENANTTable());
43
        addTableDefinition(buildOFFICERCADETTable());
43
        addTableDefinition(buildLACKEYTable());
44
        addTableDefinition(buildLACKEYTable());
44
        addTableDefinition(buildLACKEYCREWTable());
45
        addTableDefinition(buildLACKEYCREWTable());
45
    }
46
    }
Lines 742-747 Link Here
742
        return table;
743
        return table;
743
    }
744
    }
744
    
745
    
746
    public static TableDefinition buildOFFICERCADETTable() {
747
        TableDefinition table = new TableDefinition();
748
        table.setName("JPA_OFFICER_CADET");
749
        
750
        FieldDefinition fieldF_NAME = new FieldDefinition();
751
        fieldF_NAME.setName("F_NAME");
752
        fieldF_NAME.setTypeName("VARCHAR");
753
        fieldF_NAME.setSize(40);
754
        fieldF_NAME.setShouldAllowNull(false);
755
        fieldF_NAME.setIsPrimaryKey(true);
756
        fieldF_NAME.setUnique(false);
757
        fieldF_NAME.setIsIdentity(false);
758
        table.addField(fieldF_NAME);
759
        
760
        FieldDefinition fieldL_NAME = new FieldDefinition();
761
        fieldL_NAME.setName("L_NAME");
762
        fieldL_NAME.setTypeName("VARCHAR");
763
        fieldL_NAME.setSize(40);
764
        fieldL_NAME.setShouldAllowNull(false);
765
        fieldL_NAME.setIsPrimaryKey(true);
766
        fieldL_NAME.setUnique(false);
767
        fieldL_NAME.setIsIdentity(false);
768
        table.addField(fieldL_NAME);
769
        
770
        return table;
771
    }
772
    
745
    /**
773
    /**
746
     * Dropping old foreign keys from schema change.
774
     * Dropping old foreign keys from schema change.
747
     */
775
     */
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/derivedid/BrigadierGeneral.java (-2 / +1 lines)
Lines 39-45 Link Here
39
        @JoinColumn(name="FIRST_NAME", referencedColumnName="F_NAME"),
39
        @JoinColumn(name="FIRST_NAME", referencedColumnName="F_NAME"),
40
        @JoinColumn(name="LAST_NAME", referencedColumnName="L_NAME")
40
        @JoinColumn(name="LAST_NAME", referencedColumnName="L_NAME")
41
    })
41
    })
42
    @MapsId
42
    @MapsId("id")
43
    MajorGeneral majorGeneral;
43
    MajorGeneral majorGeneral;
44
    
44
    
45
    public GeneralId getId() {
45
    public GeneralId getId() {
Lines 56-62 Link Here
56
56
57
    public void setMajorGeneral(MajorGeneral majorGeneral) {
57
    public void setMajorGeneral(MajorGeneral majorGeneral) {
58
        this.majorGeneral = majorGeneral;
58
        this.majorGeneral = majorGeneral;
59
        id = majorGeneral.getPK();
60
    }
59
    }
61
}
60
}
62
61
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/derivedid/Captain.java (-1 lines)
Lines 57-62 Link Here
57
57
58
    public void setMajor(Major major) {
58
    public void setMajor(Major major) {
59
        this.major = major;
59
        this.major = major;
60
        id.setMajor(major.getPK());
61
    }
60
    }
62
}
61
}
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/derivedid/LieutenantGeneral.java (-1 lines)
Lines 45-51 Link Here
45
45
46
    public void setGeneral(General general) {
46
    public void setGeneral(General general) {
47
        this.general = general;
47
        this.general = general;
48
        this.id = general.getGeneralId();
49
    }
48
    }
50
    
49
    
51
    public void setId(Integer id) {
50
    public void setId(Integer id) {
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/derivedid/MasterCorporal.java (-2 / +3 lines)
Lines 19-24 Link Here
19
import javax.persistence.MapsId;
19
import javax.persistence.MapsId;
20
import javax.persistence.Table;
20
import javax.persistence.Table;
21
21
22
import static javax.persistence.CascadeType.PERSIST;
23
22
/**
24
/**
23
 * This model tests Example #1 of the mapsId cases.
25
 * This model tests Example #1 of the mapsId cases.
24
 * 
26
 * 
Lines 30-36 Link Here
30
    @EmbeddedId 
32
    @EmbeddedId 
31
    MasterCorporalId id;
33
    MasterCorporalId id;
32
    
34
    
33
    @ManyToOne // join column default to SARGEANT_ID
35
    @ManyToOne(cascade=PERSIST) // join column default to SARGEANT_ID
34
    @MapsId("sargeantPK")
36
    @MapsId("sargeantPK")
35
    Sargeant sargeant;
37
    Sargeant sargeant;
36
    
38
    
Lines 48-54 Link Here
48
50
49
    public void setSargeant(Sargeant sargeant) {
51
    public void setSargeant(Sargeant sargeant) {
50
        this.sargeant = sargeant;
52
        this.sargeant = sargeant;
51
        id.setSargeantPK(sargeant.getSargeantId());
52
    }
53
    }
53
}
54
}
54
55
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/derivedid/Private.java (-1 lines)
Lines 53-58 Link Here
53
53
54
    public void setCorporal(Corporal corporal) {
54
    public void setCorporal(Corporal corporal) {
55
        this.corporal = corporal;
55
        this.corporal = corporal;
56
        privateId.setCorporalPK(corporal.getCorporalId());
57
    }
56
    }
58
}
57
}
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/derivedid/SecondLieutenant.java (-1 lines)
Lines 48-53 Link Here
48
48
49
    public void setLieutenant(Lieutenant lieutenant) {
49
    public void setLieutenant(Lieutenant lieutenant) {
50
        this.lieutenant = lieutenant;
50
        this.lieutenant = lieutenant;
51
        id = lieutenant.getId();
52
    }
51
    }
53
}
52
}
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/PartnerLink.java (-4 / +4 lines)
Lines 24-35 Link Here
24
    private Woman woman;
24
    private Woman woman;
25
25
26
	public PartnerLink() {}
26
	public PartnerLink() {}
27
	
27
	@Id
28
	@Id
28
    @OneToOne(cascade=PERSIST)
29
    @OneToOne(cascade=PERSIST)
29
	@JoinColumn(name="M")
30
	@JoinColumn(name="M")
30
	public Man getMan() { 
31
	public Man getMan() { 
31
        return man; 
32
        return man; 
32
    }
33
    }
34
	
33
    @Column(name="M", insertable=false, updatable=false)
35
    @Column(name="M", insertable=false, updatable=false)
34
	public Integer getManId() {
36
	public Integer getManId() {
35
        return (getMan() == null) ? null : getMan().getId();
37
        return (getMan() == null) ? null : getMan().getId();
Lines 51-63 Link Here
51
        this.man = man; 
53
        this.man = man; 
52
    }
54
    }
53
    
55
    
54
    public void setManId(Integer manId) {  
56
    public void setManId(Integer manId) {}
55
    }
56
    
57
    
57
    public void setWoman(Woman woman) { 
58
    public void setWoman(Woman woman) { 
58
        this.woman = woman; 
59
        this.woman = woman; 
59
    }
60
    }
60
    
61
    
61
    public void setWomanId(Integer womanId) { 
62
    public void setWomanId(Integer womanId) {}
62
    }
63
}
63
}
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/cacheable/CacheableTrueEntity.java (-1 / +1 lines)
Lines 36-42 Link Here
36
@Inheritance(strategy=SINGLE_TABLE)
36
@Inheritance(strategy=SINGLE_TABLE)
37
@DiscriminatorColumn(name="DTYPE")
37
@DiscriminatorColumn(name="DTYPE")
38
@DiscriminatorValue("CTE")
38
@DiscriminatorValue("CTE")
39
@Cacheable(true)
39
@Cacheable // defaults to true
40
@NamedQueries({
40
@NamedQueries({
41
    @NamedQuery(
41
    @NamedQuery(
42
        name="findCacheableTrueEntityByPK_RETRIEVE_BYPASS_STORE_USE",
42
        name="findCacheableTrueEntityByPK_RETRIEVE_BYPASS_STORE_USE",
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/advanced/compositepk/AdvancedCompositePKJunitTest.java (-3 / +53 lines)
Lines 53-58 Link Here
53
import org.eclipse.persistence.testing.models.jpa.advanced.derivedid.MajorId;
53
import org.eclipse.persistence.testing.models.jpa.advanced.derivedid.MajorId;
54
import org.eclipse.persistence.testing.models.jpa.advanced.derivedid.MasterCorporal;
54
import org.eclipse.persistence.testing.models.jpa.advanced.derivedid.MasterCorporal;
55
import org.eclipse.persistence.testing.models.jpa.advanced.derivedid.MasterCorporalId;
55
import org.eclipse.persistence.testing.models.jpa.advanced.derivedid.MasterCorporalId;
56
import org.eclipse.persistence.testing.models.jpa.advanced.derivedid.OfficerCadet;
56
import org.eclipse.persistence.testing.models.jpa.advanced.derivedid.Private;
57
import org.eclipse.persistence.testing.models.jpa.advanced.derivedid.Private;
57
import org.eclipse.persistence.testing.models.jpa.advanced.derivedid.PrivateId;
58
import org.eclipse.persistence.testing.models.jpa.advanced.derivedid.PrivateId;
58
import org.eclipse.persistence.testing.models.jpa.advanced.derivedid.Sargeant;
59
import org.eclipse.persistence.testing.models.jpa.advanced.derivedid.Sargeant;
Lines 92-97 Link Here
92
        suite.addTest(new AdvancedCompositePKJunitTest("testMapsIdExample5"));
93
        suite.addTest(new AdvancedCompositePKJunitTest("testMapsIdExample5"));
93
        suite.addTest(new AdvancedCompositePKJunitTest("testMapsIdExample5a"));
94
        suite.addTest(new AdvancedCompositePKJunitTest("testMapsIdExample5a"));
94
        suite.addTest(new AdvancedCompositePKJunitTest("testMapsIdExample6"));
95
        suite.addTest(new AdvancedCompositePKJunitTest("testMapsIdExample6"));
96
        suite.addTest(new AdvancedCompositePKJunitTest("testMapsIdExample6MultiLevel"));
95
        
97
        
96
        suite.addTest(new AdvancedCompositePKJunitTest("testGetIdentifier"));
98
        suite.addTest(new AdvancedCompositePKJunitTest("testGetIdentifier"));
97
        
99
        
Lines 233-239 Link Here
233
235
234
            em.persist(depAdmin);
236
            em.persist(depAdmin);
235
            commitTransaction(em);
237
            commitTransaction(em);
236
            //org.eclipse.persistence.internal.jpa.EntityManagerImpl emImpl = (org.eclipse.persistence.internal.jpa.EntityManagerImpl) em;
238
            org.eclipse.persistence.internal.jpa.EntityManagerImpl emImpl = (org.eclipse.persistence.internal.jpa.EntityManagerImpl) em;
237
            DepartmentAdminRolePK depAdminPk= new DepartmentAdminRolePK(depName, depRole, location, adminEmp.getEmployee().getId()); 
239
            DepartmentAdminRolePK depAdminPk= new DepartmentAdminRolePK(depName, depRole, location, adminEmp.getEmployee().getId()); 
238
 
240
 
239
            DepartmentAdminRole cacheObject = em.find(DepartmentAdminRole.class, depAdminPk);
241
            DepartmentAdminRole cacheObject = em.find(DepartmentAdminRole.class, depAdminPk);
Lines 332-342 Link Here
332
        
334
        
333
        try {    
335
        try {    
334
            sargeant.setName("Sarge");
336
            sargeant.setName("Sarge");
335
            em.persist(sargeant);
336
            
337
            
337
            masterCorporalId.setName("Corpie");
338
            masterCorporalId.setName("Corpie");
338
            masterCorporal.setId(masterCorporalId);
339
            masterCorporal.setId(masterCorporalId);
339
            masterCorporal.setSargeant(sargeant);
340
            masterCorporal.setSargeant(sargeant);
341
            
342
            // Sargeant is cascade persist.
340
            em.persist(masterCorporal);
343
            em.persist(masterCorporal);
341
            
344
            
342
            commitTransaction(em);
345
            commitTransaction(em);
Lines 570-577 Link Here
570
            lieutenant.setId(lieutenantId);
573
            lieutenant.setId(lieutenantId);
571
            em.persist(lieutenant);
574
            em.persist(lieutenant);
572
            
575
            
576
            em.persist(secondLieutenant);
573
            secondLieutenant.setLieutenant(lieutenant);
577
            secondLieutenant.setLieutenant(lieutenant);
574
            em.persist(secondLieutenant);
578
            em.flush();
575
            
579
            
576
            commitTransaction(em);
580
            commitTransaction(em);
577
        } catch (RuntimeException e) {
581
        } catch (RuntimeException e) {
Lines 593-598 Link Here
593
        assertTrue("The second lieutenant read back did not match the original", getServerSession().compareObjects(secondLieutenant, refreshedSecondLieutenant));  
597
        assertTrue("The second lieutenant read back did not match the original", getServerSession().compareObjects(secondLieutenant, refreshedSecondLieutenant));  
594
    }
598
    }
595
    
599
    
600
    public void testMapsIdExample6MultiLevel() {
601
        EntityManager em = createEntityManager();
602
        beginTransaction(em);
603
        
604
        Lieutenant lieutenant = new Lieutenant();
605
        LieutenantId lieutenantId = new LieutenantId();
606
        SecondLieutenant secondLieutenant = new SecondLieutenant();
607
        OfficerCadet officerCadet = new OfficerCadet();
608
        
609
        try {
610
            lieutenantId.setFirstName("Lieutenant");
611
            lieutenantId.setLastName("Daniel");
612
            lieutenant.setId(lieutenantId);
613
            em.persist(lieutenant);
614
            
615
            em.persist(secondLieutenant);
616
            secondLieutenant.setLieutenant(lieutenant);
617
            
618
            officerCadet.setSecondLieutenant(secondLieutenant);
619
            em.persist(officerCadet);
620
            
621
            em.flush();
622
            
623
            commitTransaction(em);
624
        } catch (RuntimeException e) {
625
            if (isTransactionActive(em)){
626
                rollbackTransaction(em);
627
            }
628
            
629
            closeEntityManager(em);
630
            throw e;
631
        }
632
        
633
        clearCache();
634
        em = createEntityManager();        
635
        
636
        Lieutenant refreshedLieutenant = em.find(Lieutenant.class, lieutenant.getId());
637
        assertTrue("The lieutenant read back did not match the original", getServerSession().compareObjects(lieutenant, refreshedLieutenant));
638
639
        SecondLieutenant refreshedSecondLieutenant = em.find(SecondLieutenant.class, secondLieutenant.getId());
640
        assertTrue("The second lieutenant read back did not match the original", getServerSession().compareObjects(secondLieutenant, refreshedSecondLieutenant));
641
        
642
        OfficerCadet refreshedOfficerCadet = em.find(OfficerCadet.class, officerCadet.getId());
643
        assertTrue("The officer cadet read back did not match the original", getServerSession().compareObjects(officerCadet, refreshedOfficerCadet));
644
    }
645
    
596
    public void testGetIdentifier(){
646
    public void testGetIdentifier(){
597
        // Don't run this test in a JPA 1.0 environment.
647
        // Don't run this test in a JPA 1.0 environment.
598
        if (! isJPA10()) {
648
        if (! isJPA10()) {
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/CMP3Policy.java (-5 / +5 lines)
Lines 329-339 Link Here
329
                
329
                
330
                // So here is the ugly check to see if we want to further look at this mapping as part of 
330
                // So here is the ugly check to see if we want to further look at this mapping as part of 
331
                // the id or not.
331
                // the id or not.
332
                if (descriptor.hasDerivedId() && ! mapping.isDerivedIdMapping()) {
332
                if (descriptor.hasDerivedId() && ! mapping.derivesId()) {
333
                    // If the mapping is not a derived id, then we need to keep looking for the mapping that 
333
                    // If the mapping is not a derived id, then we need to keep looking for the mapping that 
334
                    // is marked as the derived id mapping. However, in a mapped by id case, we may have 
334
                    // is marked as the derived id mapping. However, in a mapped by id case, we may have 
335
                    // 'extra' non-derived id fields within the embeddable class (and the writable mapping 
335
                    // 'extra' non-derived id fields within the embeddable class (and the writable mapping 
336
                    // that we care about at this point will be defined on the embeddable descritor). Therefore, 
336
                    // that we care about at this point will be defined on the embeddable descriptor). Therefore, 
337
                    // we can't bail at this point and must drill down further into the embeddable to make sure
337
                    // we can't bail at this point and must drill down further into the embeddable to make sure
338
                    // we initialize this portion of the composite id.
338
                    // we initialize this portion of the composite id.
339
                    if (mapping.isAggregateMapping() && allMappings.size() > 1) {
339
                    if (mapping.isAggregateMapping() && allMappings.size() > 1) {
Lines 362-370 Link Here
362
                    // Update the index to parse the next mapping correctly.
362
                    // Update the index to parse the next mapping correctly.
363
                    index = allMappings.size();                        
363
                    index = allMappings.size();                        
364
                } else {
364
                } else {
365
                    String fieldName = (mapping.hasMappedByIdValue()) ? mapping.getMappedByIdValue() : mapping.getAttributeName();
365
                    String fieldName = (mapping.hasMapsIdValue()) ? mapping.getMapsIdValue() : mapping.getAttributeName();
366
                
366
                
367
                    if (keyClass == null){
367
                    if (keyClass == null){                        
368
                        // must be a primitive since key class was not set
368
                        // must be a primitive since key class was not set
369
                        pkAttributes[i] = new KeyIsElementAccessor(fieldName, field, mapping);
369
                        pkAttributes[i] = new KeyIsElementAccessor(fieldName, field, mapping);
370
                        if (mapping.isDirectToFieldMapping()){
370
                        if (mapping.isDirectToFieldMapping()){
Lines 436-442 Link Here
436
                        }
436
                        }
437
                    }
437
                    }
438
                 
438
                 
439
                    if (mapping.isDerivedIdMapping() || noSuchElementException == null) {
439
                    if (mapping.derivesId() || noSuchElementException == null) {
440
                        // Break out of the loop as we do not need to look for
440
                        // Break out of the loop as we do not need to look for
441
                        // any more mappings
441
                        // any more mappings
442
                        break;
442
                        break;
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/EntityManagerSetupImpl.java (+5 lines)
Lines 383-388 Link Here
383
                descriptor.setCMPPolicy(new CMP3Policy());
383
                descriptor.setCMPPolicy(new CMP3Policy());
384
            }
384
            }
385
        }
385
        }
386
387
        // TODO: Look into setting a CMPPolicy on the MappedSuperclass descriptors.
388
        // Will require some tweaking however to ensure the primary key fields are
389
        // set/initialized correctly. Currently rely on the descriptor initialized
390
        // object builder which is not available to mapped superclass descriptors.
386
    }
391
    }
387
392
388
    /**
393
    /**
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/accessors/classes/ClassAccessor.java (-11 / +27 lines)
Lines 610-617 Link Here
610
    /**
610
    /**
611
     * INTERNAL:
611
     * INTERNAL:
612
     */
612
     */
613
    public boolean hasDerivedId(){
613
    public boolean hasDerivedId() {
614
        return ! getDescriptor().getDerivedIDAccessors().isEmpty();
614
        return ! getDescriptor().getDerivedIdAccessors().isEmpty();
615
    }
615
    }
616
    
616
    
617
    /**
617
    /**
Lines 900-922 Link Here
900
900
901
    /**
901
    /**
902
     * INTERNAL:
902
     * INTERNAL:
903
     * Allows for processing DerivedIds. All referenced accessors are processed
903
     * Allows for processing derived ids, either from an Id or MapsId
904
     * first to ensure the necessary fields are set before this derivedId is 
904
     * specification. All referenced accessors are processed first to ensure 
905
     * processed 
905
     * the necessary fields are set before the derived id is processed and
906
     * circular references are checked. 
906
     */
907
     */
907
    public void processDerivedIDs(HashSet<ClassAccessor> processing, HashSet<ClassAccessor> processed) {
908
    public void processDerivedId(HashSet<ClassAccessor> processing, HashSet<ClassAccessor> processed) {
908
        if (hasDerivedId() && ! processed.contains(this)) {
909
        // Process only if we haven't already done so (inheritance case)
909
            if (processing.contains(this)){
910
        if (! processed.contains(this)) {            
910
                //we have a circular pk reference problem
911
            // If we appear in the processing list, through the chain of derived
912
            // id we have come back to ourself. We have a circular reference,
913
            // throw an exception.
914
            if (processing.contains(this)) {
911
                throw ValidationException.idRelationshipCircularReference(processing);
915
                throw ValidationException.idRelationshipCircularReference(processing);
912
            }
916
            }
913
            
917
            
914
            processing.add(this);
918
            processing.add(this);
915
            
919
            
916
            for (ObjectAccessor accessor : getDescriptor().getDerivedIDAccessors()) {
920
            for (ObjectAccessor accessor : getDescriptor().getDerivedIdAccessors()) {
917
                accessor.processKey(processing, processed);
921
                // Check the reference accessor for a derived id and fast
922
                // track its processing if need be.
923
                MetadataDescriptor referenceDescriptor = accessor.getReferenceDescriptor();
924
                ClassAccessor referenceAccessor = referenceDescriptor.getClassAccessor();
925
                
926
                if (referenceAccessor.hasDerivedId()) {    
927
                    referenceAccessor.processDerivedId(processing, processed);
928
                }
929
                
930
                // Now process the relationship, and the derived id.
931
                accessor.processRelationship();
918
            }
932
            }
919
            
933
            
934
            // Once we're done, we'll move ourselves from the processing to 
935
            // processed step.
920
            processing.remove(this);
936
            processing.remove(this);
921
            processed.add(this);
937
            processed.add(this);
922
        }
938
        }
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/accessors/classes/EntityAccessor.java (-3 / +3 lines)
Lines 795-803 Link Here
795
     * first to ensure the necessary fields are set before this derivedId is processed 
795
     * first to ensure the necessary fields are set before this derivedId is processed 
796
     */
796
     */
797
    @Override
797
    @Override
798
    public void processDerivedIDs(HashSet<ClassAccessor> processing, HashSet<ClassAccessor> processed) {
798
    public void processDerivedId(HashSet<ClassAccessor> processing, HashSet<ClassAccessor> processed) {
799
        if (hasDerivedId() && !processed.contains(this)){
799
        if (! processed.contains(this)) {
800
            super.processDerivedIDs(processing, processed);
800
            super.processDerivedId(processing, processed);
801
            
801
            
802
            // Validate we found a primary key.
802
            // Validate we found a primary key.
803
            validatePrimaryKey();
803
            validatePrimaryKey();
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/accessors/classes/MappedSuperclassAccessor.java (-1 / +1 lines)
Lines 609-615 Link Here
609
            } else {
609
            } else {
610
                // Set the cacheable setting on the descriptor.
610
                // Set the cacheable setting on the descriptor.
611
                if (m_cacheable == null) {
611
                if (m_cacheable == null) {
612
                    m_cacheable = (Boolean) getAnnotation(Cacheable.class).getAttribute("value");
612
                    m_cacheable = (Boolean) getAnnotation(Cacheable.class).getAttributeBooleanDefaultTrue("value");
613
                } 
613
                } 
614
                
614
                
615
                getDescriptor().setCacheable(m_cacheable);
615
                getDescriptor().setCacheable(m_cacheable);
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/accessors/mappings/BasicAccessor.java (-7 / +1 lines)
Lines 113-122 Link Here
113
        // Set the mutable value if one is present.
113
        // Set the mutable value if one is present.
114
        MetadataAnnotation mutable = getAnnotation(Mutable.class);
114
        MetadataAnnotation mutable = getAnnotation(Mutable.class);
115
        if (mutable != null) {
115
        if (mutable != null) {
116
            m_mutable = (Boolean) mutable.getAttribute("value");
116
            m_mutable = (Boolean) mutable.getAttributeBooleanDefaultTrue("value");
117
            if (m_mutable == null) {
118
                m_mutable = true;
119
            }
120
        }
117
        }
121
        
118
        
122
        // Set the generated value if one is present.
119
        // Set the generated value if one is present.
Lines 289-297 Link Here
289
        mapping.setAttributeName(getAttributeName());
286
        mapping.setAttributeName(getAttributeName());
290
        mapping.setIsOptional(isOptional());
287
        mapping.setIsOptional(isOptional());
291
        mapping.setIsLazy(usesIndirection());
288
        mapping.setIsLazy(usesIndirection());
292
        
293
        // Derived ID: set if this mapping has been marked as an ID.
294
        mapping.setIsDerivedIdMapping(isId());
295
289
296
        // Will check for PROPERTY access.
290
        // Will check for PROPERTY access.
297
        setAccessorMethods(mapping);
291
        setAccessorMethods(mapping);
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/accessors/mappings/IdAccessor.java (+3 lines)
Lines 80-84 Link Here
80
80
81
        // Add the primary key field to the descriptor.            
81
        // Add the primary key field to the descriptor.            
82
        getOwningDescriptor().addPrimaryKeyField(getField(), this);
82
        getOwningDescriptor().addPrimaryKeyField(getField(), this);
83
        
84
        // Flag this id accessor as a JPA id mapping.
85
        getMapping().setIsJPAId();
83
    }
86
    }
84
}
87
}
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/accessors/mappings/MappingAccessor.java (-9 / +9 lines)
Lines 143-148 Link Here
143
    
143
    
144
    /**
144
    /**
145
     * INTERNAL:
145
     * INTERNAL:
146
     * Return true is this accessor is a derived id accessor.
147
     * @see ObjectAccessor
148
     */
149
    public boolean derivesId() {
150
        return false;
151
    }
152
    
153
    /**
154
     * INTERNAL:
146
     * Process an attribute override for either an embedded object mapping, or
155
     * Process an attribute override for either an embedded object mapping, or
147
     * an element collection mapping containing embeddable objects.
156
     * an element collection mapping containing embeddable objects.
148
     */
157
     */
Lines 804-818 Link Here
804
    
813
    
805
    /**
814
    /**
806
     * INTERNAL:
815
     * INTERNAL:
807
     * Return true is this accessor is a derived id accessor.
808
     * @see ObjectAccessor
809
     */
810
    public boolean isDerivedId() {
811
        return false;
812
    }
813
    
814
    /**
815
     * INTERNAL:
816
     * Return true if this accessor is a derived id class accessor.
816
     * Return true if this accessor is a derived id class accessor.
817
     */
817
     */
818
    public boolean isDerivedIdClass(){
818
    public boolean isDerivedIdClass(){
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/accessors/mappings/ObjectAccessor.java (-75 / +84 lines)
Lines 33-39 Link Here
33
package org.eclipse.persistence.internal.jpa.metadata.accessors.mappings;
33
package org.eclipse.persistence.internal.jpa.metadata.accessors.mappings;
34
34
35
import java.util.ArrayList;
35
import java.util.ArrayList;
36
import java.util.HashSet;
37
import java.util.List;
36
import java.util.List;
38
37
39
import javax.persistence.FetchType;
38
import javax.persistence.FetchType;
Lines 119-125 Link Here
119
        if (isAnnotationPresent(MapsId.class)) {
118
        if (isAnnotationPresent(MapsId.class)) {
120
            // Call getAttributeString in this case because we rely on the
119
            // Call getAttributeString in this case because we rely on the
121
            // mapsId not being null and it's value of "" means we need to
120
            // mapsId not being null and it's value of "" means we need to
122
            // default. getAttribute returns null which kills (hasMapsId())
121
            // default. getAttribute returns null which kills hasMapsId() logic
123
            m_mapsId = (String) getAnnotation(MapsId.class).getAttributeString("value");
122
            m_mapsId = (String) getAnnotation(MapsId.class).getAttributeString("value");
124
        }
123
        }
125
        
124
        
Lines 129-134 Link Here
129
    
128
    
130
    /**
129
    /**
131
     * INTERNAL:
130
     * INTERNAL:
131
     * Return true is this accessor is a derived id accessor.
132
     */
133
    @Override
134
    public boolean derivesId() {
135
        return hasId() || hasMapsId();
136
    }
137
    
138
    /**
139
     * INTERNAL:
132
     * Return the default fetch type for an object mapping.
140
     * Return the default fetch type for an object mapping.
133
     */
141
     */
134
    public String getDefaultFetchType() {
142
    public String getDefaultFetchType() {
Lines 208-213 Link Here
208
    /**
216
    /**
209
     * INTERNAL:
217
     * INTERNAL:
210
     */
218
     */
219
    protected boolean hasId() {
220
        return m_id != null && m_id;
221
    }
222
    
223
    /**
224
     * INTERNAL:
225
     */
211
    protected boolean hasMapsId() {
226
    protected boolean hasMapsId() {
212
        return m_mapsId != null;
227
        return m_mapsId != null;
213
    }
228
    }
Lines 223-229 Link Here
223
        mapping.setIsOptional(isOptional());
238
        mapping.setIsOptional(isOptional());
224
        mapping.setAttributeName(getAttributeName());
239
        mapping.setAttributeName(getAttributeName());
225
        mapping.setReferenceClassName(getReferenceClassName());
240
        mapping.setReferenceClassName(getReferenceClassName());
226
        mapping.setIsDerivedIdMapping(isDerivedId());
241
        mapping.setDerivesId(derivesId());
227
        
242
        
228
        // Process the orphanRemoval or PrivateOwned
243
        // Process the orphanRemoval or PrivateOwned
229
        processOrphanRemoval(mapping);
244
        processOrphanRemoval(mapping);
Lines 256-270 Link Here
256
    
271
    
257
    /**
272
    /**
258
     * INTERNAL:
273
     * INTERNAL:
259
     * Return true is this accessor is a derived id accessor.
260
     */
261
    @Override
262
    public boolean isDerivedId() {
263
        return m_id != null && m_id;
264
    }
265
    
266
    /**
267
     * INTERNAL:
268
     * Return true if this accessor represents a 1-1 primary key relationship.
274
     * Return true if this accessor represents a 1-1 primary key relationship.
269
     */
275
     */
270
    public boolean isOneToOnePrimaryKeyRelationship() {
276
    public boolean isOneToOnePrimaryKeyRelationship() {
Lines 329-390 Link Here
329
    
335
    
330
    /**
336
    /**
331
     * INTERNAL:
337
     * INTERNAL:
332
     * Process the indirection (aka fetch type)
333
     */
334
    protected void processIndirection(ObjectReferenceMapping mapping) {
335
        boolean usesIndirection = usesIndirection();
336
        
337
        // If weaving was disabled, and the class was not static weaved,
338
        // then disable indirection.
339
        if (usesIndirection && (!getProject().isWeavingEnabled())
340
                && (!ClassConstants.PersistenceWeavedLazy_Class.isAssignableFrom(getJavaClass(getDescriptor().getJavaClass())))) {
341
            usesIndirection = false;
342
        }
343
        
344
        if (usesIndirection && usesPropertyAccess(getDescriptor())) {
345
            mapping.setIndirectionPolicy(new WeavedObjectBasicIndirectionPolicy(getSetMethodName()));
346
        } else {
347
            mapping.setUsesIndirection(usesIndirection);
348
        }
349
        
350
        mapping.setIsLazy(isLazy());
351
    }
352
    
353
    /**
354
     * INTERNAL:
355
     * Used to process primary keys and DerivedIds.
338
     * Used to process primary keys and DerivedIds.
356
     */
339
     */
357
    public void processKey(HashSet<ClassAccessor> processing, HashSet<ClassAccessor> processed){
340
    protected void processId(OneToOneMapping mapping) {
341
        // If this entity has a pk class, we need to validate our ids.
358
        MetadataDescriptor referenceDescriptor = getReferenceDescriptor();
342
        MetadataDescriptor referenceDescriptor = getReferenceDescriptor();
359
        ClassAccessor referenceAccessor = referenceDescriptor.getClassAccessor();
360
        
361
        if (!processed.contains(referenceAccessor)){
362
            referenceAccessor.processDerivedIDs(processing, processed);
363
        }
364
365
        processRelationship();
366
        String attributeName = getAttributeName();
367
368
        // If this entity has a pk class, we need to validate our ids. 
369
        String keyname = referenceDescriptor.getPKClassName();
343
        String keyname = referenceDescriptor.getPKClassName();
370
344
371
        if (keyname != null) {
345
        if (keyname != null) {
372
            // They have a pk class
346
            // They have a pk class
373
            String ourpkname = this.getDescriptor().getPKClassName();
347
            String ourpkname = getDescriptor().getPKClassName();
374
            if (ourpkname == null){
348
            if (ourpkname == null){
375
                throw ValidationException.invalidCompositePKSpecification(getJavaClass(), ourpkname);
349
                throw ValidationException.invalidCompositePKSpecification(getJavaClass(), ourpkname);
376
            }
350
            }
377
            
351
            
378
            if (! ourpkname.equals(keyname)){
352
            if (! ourpkname.equals(keyname)){
379
                // Validate our pk contains their pk.
353
                // Validate our pk contains their pk.
380
                getOwningDescriptor().validatePKClassId(attributeName, referenceDescriptor.getPKClass());
354
                getOwningDescriptor().validatePKClassId(getAttributeName(), referenceDescriptor.getPKClass());
381
            } else {
355
            } else {
382
                // This pk is the reference pk, so all pk attributes are accounted through this relationship
356
                // This pk is the reference pk, so all pk attributes are accounted through this relationship
383
                getOwningDescriptor().getPKClassIDs().clear();
357
                getOwningDescriptor().getPKClassIDs().clear();
384
            }
358
            }
385
        } else {
359
        } else {
386
            MetadataClass type = null;
360
            MetadataClass type = null;
387
            if (referenceAccessor.hasDerivedId()){
361
            if (referenceDescriptor.getClassAccessor().hasDerivedId()){
388
                // Referenced object has a derived ID but no PK class defined,
362
                // Referenced object has a derived ID but no PK class defined,
389
                // so it must be a simple pk type. Recurse through to get the 
363
                // so it must be a simple pk type. Recurse through to get the 
390
                // simple type
364
                // simple type
Lines 394-407 Link Here
394
                type = referenceDescriptor.getAccessorFor(referenceDescriptor.getIdAttributeName()).getRawClass();
368
                type = referenceDescriptor.getAccessorFor(referenceDescriptor.getIdAttributeName()).getRawClass();
395
            }
369
            }
396
            
370
            
397
            getOwningDescriptor().validatePKClassId(attributeName, type);
371
            getOwningDescriptor().validatePKClassId(getAttributeName(), type);
398
        }
372
        }
399
373
400
        // Store the Id attribute name. Used with validation and OrderBy.
374
        // Store the Id attribute name. Used with validation and OrderBy.
401
        getOwningDescriptor().addIdAttributeName(attributeName);
375
        getOwningDescriptor().addIdAttributeName(getAttributeName());
402
376
403
        // Add the primary key fields to the descriptor.  
377
        // Add the primary key fields to the descriptor.  
404
        ObjectReferenceMapping mapping = (ObjectReferenceMapping) getMapping();
405
        for (DatabaseField pkField : mapping.getForeignKeyFields()) {
378
        for (DatabaseField pkField : mapping.getForeignKeyFields()) {
406
            getOwningDescriptor().addPrimaryKeyField(pkField, null);
379
            getOwningDescriptor().addPrimaryKeyField(pkField, null);
407
        }
380
        }
Lines 409-414 Link Here
409
    
382
    
410
    /**
383
    /**
411
     * INTERNAL:
384
     * INTERNAL:
385
     * Process the indirection (aka fetch type)
386
     */
387
    protected void processIndirection(ObjectReferenceMapping mapping) {
388
        boolean usesIndirection = usesIndirection();
389
        
390
        // If weaving was disabled, and the class was not static weaved,
391
        // then disable indirection.
392
        if (usesIndirection && (!getProject().isWeavingEnabled())
393
                && (!ClassConstants.PersistenceWeavedLazy_Class.isAssignableFrom(getJavaClass(getDescriptor().getJavaClass())))) {
394
            usesIndirection = false;
395
        }
396
        
397
        if (usesIndirection && usesPropertyAccess(getDescriptor())) {
398
            mapping.setIndirectionPolicy(new WeavedObjectBasicIndirectionPolicy(getSetMethodName()));
399
        } else {
400
            mapping.setUsesIndirection(usesIndirection);
401
        }
402
        
403
        mapping.setIsLazy(isLazy());
404
    }
405
    
406
    /**
407
     * INTERNAL:
412
     * Process the mapping keys from the maps id value.
408
     * Process the mapping keys from the maps id value.
413
     */
409
     */
414
    protected void processMapsId(OneToOneMapping oneToOneMapping) {
410
    protected void processMapsId(OneToOneMapping oneToOneMapping) {
Lines 428-464 Link Here
428
            
424
            
429
            // Set the primary key mapping as read only.
425
            // Set the primary key mapping as read only.
430
            primaryKeyMapping.setIsReadOnly(true);
426
            primaryKeyMapping.setIsReadOnly(true);
431
        } else if (embeddedIdAccessor.getReferenceClassName().equals(getReferenceDescriptor().getPKClassName())) {
427
            
432
            // Embedded id class is the same as the parents parents id class.
428
            // Set the maps id mapping.
433
            // Case #5: Parent uses id class == to dependent's embedded id class
429
            oneToOneMapping.setDerivedIdMapping(primaryKeyMapping);
434
            // Case #6: Both parent and dependent use same embedded id class.            
435
            processMapsIdFields(oneToOneMapping, embeddedIdAccessor, null);
436
        } else {
430
        } else {
437
            if (m_mapsId.equals("")) {
431
            if (embeddedIdAccessor.getReferenceClassName().equals(getReferenceDescriptor().getPKClassName())) {
438
                // User didn't specify a mapsId value. By default the attribute name from this object accessor is used.
432
                // Embedded id class is the same as the parents parents id class.
439
                m_mapsId = getAttributeName();
433
                // Case #5: Parent uses id class == to dependent's embedded id class
440
            }
434
                // Case #6: Both parent and dependent use same embedded id class.            
435
                processMapsIdFields(oneToOneMapping, embeddedIdAccessor, null);
436
            } else {
437
                if (m_mapsId.equals("")) {
438
                    // User didn't specify a mapsId value. By default the attribute name from this object accessor is used.
439
                    m_mapsId = getAttributeName();
440
                }
441
                
441
                
442
            MappingAccessor mappingAccessor = embeddedIdAccessor.getReferenceDescriptor().getAccessorFor(m_mapsId);
442
                MappingAccessor mappingAccessor = embeddedIdAccessor.getReferenceDescriptor().getAccessorFor(m_mapsId);
443
        
443
        
444
            if (mappingAccessor == null) {
444
                if (mappingAccessor == null) {
445
                throw ValidationException.invalidMappedByIdValue(m_mapsId, getAnnotatedElementName(), embeddedIdAccessor.getReferenceClass());
445
                    throw ValidationException.invalidMappedByIdValue(m_mapsId, getAnnotatedElementName(), embeddedIdAccessor.getReferenceClass());
446
            } else if (mappingAccessor.isBasic()) {
446
                } else if (mappingAccessor.isBasic()) {
447
                // Case #1: basic mapping from embedded id to parent entity.
447
                    // Case #1: basic mapping from embedded id to parent entity.
448
                processMapsIdFields(oneToOneMapping, embeddedIdAccessor, mappingAccessor);
448
                    processMapsIdFields(oneToOneMapping, embeddedIdAccessor, mappingAccessor);
449
            } else if (mappingAccessor.isDerivedIdClass()) {
449
                } else if (mappingAccessor.isDerivedIdClass()) {
450
                // Case #2 and case #3 (Id class or embedded id used as the derived id)
450
                    // Case #2 and case #3 (Id class or embedded id used as the derived id)
451
                processMapsIdFields(oneToOneMapping, (DerivedIdClassAccessor) mappingAccessor, null);
451
                    processMapsIdFields(oneToOneMapping, (DerivedIdClassAccessor) mappingAccessor, null);
452
                }
453
            
454
                // Set the maps id value on the mapping.
455
                oneToOneMapping.setMapsIdValue(m_mapsId);
452
            }
456
            }
453
            
457
            
454
            // This will also set the isDerivedIdMapping flag to true.
458
            // Set the maps id mapping.
455
            oneToOneMapping.setMappedByIdValue(m_mapsId);
459
            oneToOneMapping.setDerivedIdMapping(embeddedIdAccessor.getMapping());
456
        }
460
        }
457
    }
461
    }
458
    
462
    
459
    /**
463
    /**
460
     * INTERNAL:
464
     * INTERNAL:
461
     * We're going to field name translations where necessary. If the user
465
     * We're going to add field name translations where necessary. If the user
462
     * specified (erroneously that is) attribute overrides this will override
466
     * specified (erroneously that is) attribute overrides this will override
463
     * them.
467
     * them.
464
     * The embedded accessor passed in is either the root embedded id accessor
468
     * The embedded accessor passed in is either the root embedded id accessor
Lines 571-581 Link Here
571
     * a mapsId first.
575
     * a mapsId first.
572
     */
576
     */
573
    protected void processOwningMappingKeys(OneToOneMapping mapping) {
577
    protected void processOwningMappingKeys(OneToOneMapping mapping) {
574
        if (hasMapsId()) {
578
        if (derivesId()) {
575
            // We need to process the join columns as we normally would.
579
            // We need to process the join columns as we normally would.
576
            // Then we must update the fields from our derived id accessor.
580
            // Then we must update the fields from our derived id accessor.
577
            processOneToOneForeignKeyRelationship(mapping);
581
            processOneToOneForeignKeyRelationship(mapping);
578
            processMapsId(mapping);
582
            
583
            if (hasMapsId()) {
584
                processMapsId(mapping);
585
            } else {
586
                processId(mapping);
587
            }
579
        } else if (isOneToOnePrimaryKeyRelationship()) {
588
        } else if (isOneToOnePrimaryKeyRelationship()) {
580
            processOneToOnePrimaryKeyRelationship(mapping);
589
            processOneToOnePrimaryKeyRelationship(mapping);
581
        } else if (hasJoinTable()) {
590
        } else if (hasJoinTable()) {
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/accessors/mappings/RelationshipAccessor.java (-5 / +2 lines)
Lines 101-111 Link Here
101
        // Set the join fetch if one is present.           
101
        // Set the join fetch if one is present.           
102
        MetadataAnnotation joinFetch = getAnnotation(JoinFetch.class);            
102
        MetadataAnnotation joinFetch = getAnnotation(JoinFetch.class);            
103
        if (joinFetch != null) {
103
        if (joinFetch != null) {
104
            m_joinFetch = (String) joinFetch.getAttribute("value");
104
            // Get attribute string will return the default ""
105
            // If the value is null a value still must be set, otherwise it will not be known to be there.
105
            m_joinFetch = (String) joinFetch.getAttributeString("value");
106
            if (m_joinFetch == null) {
107
                m_joinFetch = "";
108
            }
109
        }
106
        }
110
        
107
        
111
        // Set the private owned if one is present.
108
        // Set the private owned if one is present.
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/accessors/objects/MetadataAnnotation.java (-11 / +37 lines)
Lines 37-43 Link Here
37
    
37
    
38
    /**
38
    /**
39
     * INTERNAL:
39
     * INTERNAL:
40
     * Return the attribute value, or null if not set.
40
     * Return the attribute value, or null if not set. Callers to this method
41
     * should only use it if the annotation requires the attribute. Otherwise,
42
     * you should call one of the more specific getAttribute calls that will
43
     * return the annotation default value.
44
     * @see getAttributeArray
45
     * @see getAttributeString
46
     * @see getAttributeBooleanDefaultFalse
47
     * @see getAttributeBooleanDefaultTrue
41
     */
48
     */
42
    public Object getAttribute(String name) {
49
    public Object getAttribute(String name) {
43
        return m_attributes.get(name);
50
        return m_attributes.get(name);
Lines 49-77 Link Here
49
     */
56
     */
50
    public Object getAttributeArray(String name) {
57
    public Object getAttributeArray(String name) {
51
        Object value = getAttribute(name);
58
        Object value = getAttribute(name);
52
        if (value == null) {
59
        return (value == null) ? new Object[0] : value;
53
            return new Object[0];
54
        }
55
        return value;
56
    }
60
    }
57
    
61
    
58
    /**
62
    /**
59
     * INTERNAL:
63
     * INTERNAL:
64
     * Return the boolean attribute value, or the default value if not set.
60
     */
65
     */
66
    public Object getAttributeBoolean(String name, Boolean defaultValue) {
67
        Object value = getAttribute(name);
68
        return (value == null) ? defaultValue : value;
69
    }
70
    
71
    /**
72
     * INTERNAL:
73
     * Return the boolean attribute value, or FALSE if not set.
74
     */
75
    public Object getAttributeBooleanDefaultFalse(String name) {
76
        return getAttributeBoolean(name, Boolean.FALSE);
77
    }
78
    
79
    /**
80
     * INTERNAL:
81
     * Return the boolean attribute value, or TRUE if not set.
82
     */
83
    public Object getAttributeBooleanDefaultTrue(String name) {
84
        return getAttributeBoolean(name, Boolean.TRUE);
85
    }
86
    
87
    /**
88
     * INTERNAL:
89
     */
61
    public Map<String, Object> getAttributes() {
90
    public Map<String, Object> getAttributes() {
62
        return m_attributes;
91
        return m_attributes;
63
    }
92
    }
64
93
    
65
    /**
94
    /**
66
     * INTERNAL:
95
     * INTERNAL:
67
     * Return the attribute value, or "" if not set.
96
     * Return the attribute value, or "" if not set.
68
     */
97
     */
69
    public Object getAttributeString(String name) {
98
    public Object getAttributeString(String name) {
70
        Object value = getAttribute(name);
99
        Object value = getAttribute(name);
71
        if (value == null) {
100
        return (value == null) ? "" : value;
72
            return "";
73
        }
74
        return value;
75
    }
101
    }
76
    
102
    
77
    /**
103
    /**
Lines 98-105 Link Here
98
    /**
124
    /**
99
     * INTERNAL:
125
     * INTERNAL:
100
     */
126
     */
127
    @Override
101
    public String toString() {
128
    public String toString() {
102
        return "@" + getName() + "(" + m_attributes + ")";
129
        return "@" + getName() + "(" + m_attributes + ")";
103
        //return "@" + getName();
104
    }
130
    }
105
}
131
}
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/changetracking/ChangeTrackingMetadata.java (-9 / +5 lines)
Lines 20-26 Link Here
20
20
21
import org.eclipse.persistence.descriptors.changetracking.AttributeChangeTrackingPolicy;
21
import org.eclipse.persistence.descriptors.changetracking.AttributeChangeTrackingPolicy;
22
import org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy;
22
import org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy;
23
import org.eclipse.persistence.descriptors.changetracking.ObjectChangePolicy;
24
import org.eclipse.persistence.descriptors.changetracking.ObjectChangeTrackingPolicy;
23
import org.eclipse.persistence.descriptors.changetracking.ObjectChangeTrackingPolicy;
25
24
26
import org.eclipse.persistence.internal.jpa.metadata.MetadataDescriptor;
25
import org.eclipse.persistence.internal.jpa.metadata.MetadataDescriptor;
Lines 70-91 Link Here
70
        
69
        
71
        // Process the change tracking metadata.
70
        // Process the change tracking metadata.
72
        ClassDescriptor classDescriptor = descriptor.getClassDescriptor();
71
        ClassDescriptor classDescriptor = descriptor.getClassDescriptor();
73
        ObjectChangePolicy policy = null;
74
                   
72
                   
75
        if (m_type.equals(ChangeTrackingType.ATTRIBUTE.name())) {
73
        if (m_type.equals(ChangeTrackingType.ATTRIBUTE.name())) {
76
            policy = new AttributeChangeTrackingPolicy();
74
            classDescriptor.setObjectChangePolicy(new AttributeChangeTrackingPolicy());
77
        } else if (m_type.equals(ChangeTrackingType.OBJECT.name())) {
75
        } else if (m_type.equals(ChangeTrackingType.OBJECT.name())) {
78
            policy = new ObjectChangeTrackingPolicy();
76
            classDescriptor.setObjectChangePolicy(new ObjectChangeTrackingPolicy());
79
        } else if (m_type.equals(ChangeTrackingType.DEFERRED.name())) {
77
        } else if (m_type.equals(ChangeTrackingType.DEFERRED.name())) {
80
            policy = new DeferredChangeDetectionPolicy();
78
            classDescriptor.setObjectChangePolicy(new DeferredChangeDetectionPolicy());
81
        } else if (m_type.equals(ChangeTrackingType.AUTO.name())) {
79
        } else if (m_type.equals(ChangeTrackingType.AUTO.name())) {
82
            // By setting the policy to null, this will unset any global 
80
            // By setting the policy to null, this will unset any global 
83
            // settings. EclipseLink will then determine the change tracking 
81
            // settings. EclipseLink will then determine the change tracking 
84
            // policy at runtime.
82
            // policy at runtime.
85
            policy = null;
83
            classDescriptor.setObjectChangePolicy(null);
86
        }
84
        } 
87
               
88
        classDescriptor.setObjectChangePolicy(policy);
89
    }
85
    }
90
        
86
        
91
    /**
87
    /**
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/MetadataDescriptor.java (-19 / +14 lines)
Lines 127-134 Link Here
127
    private List<String> m_orderByAttributeNames;
127
    private List<String> m_orderByAttributeNames;
128
    private List<String> m_idOrderByAttributeNames;
128
    private List<String> m_idOrderByAttributeNames;
129
    private List<MetadataDescriptor> m_embeddableDescriptors;
129
    private List<MetadataDescriptor> m_embeddableDescriptors;
130
    private List<ObjectAccessor> m_derivedIDAccessors;
131
    
130
    
131
    // Holds a list of derived id accessors.
132
    private List<ObjectAccessor> m_derivedIdAccessors;
133
    
132
    private Map<String, String> m_pkClassIDs;
134
    private Map<String, String> m_pkClassIDs;
133
    private Map<String, String> m_genericTypes;
135
    private Map<String, String> m_genericTypes;
134
    private Map<String, MappingAccessor> m_accessors;
136
    private Map<String, MappingAccessor> m_accessors;
Lines 183-189 Link Here
183
        m_orderByAttributeNames = new ArrayList<String>();
185
        m_orderByAttributeNames = new ArrayList<String>();
184
        m_idOrderByAttributeNames = new ArrayList<String>();
186
        m_idOrderByAttributeNames = new ArrayList<String>();
185
        m_embeddableDescriptors = new ArrayList<MetadataDescriptor>();
187
        m_embeddableDescriptors = new ArrayList<MetadataDescriptor>();
186
        m_derivedIDAccessors = new ArrayList<ObjectAccessor>();
188
        m_derivedIdAccessors = new ArrayList<ObjectAccessor>();
187
        
189
        
188
        m_pkClassIDs = new HashMap<String, String>();
190
        m_pkClassIDs = new HashMap<String, String>();
189
        m_genericTypes = new HashMap<String, String>();
191
        m_genericTypes = new HashMap<String, String>();
Lines 260-272 Link Here
260
        m_descriptor.getEventManager().addDefaultEventListener(listener);
262
        m_descriptor.getEventManager().addDefaultEventListener(listener);
261
    }
263
    }
262
264
263
    /** 
264
     * INTERNAL:
265
     */
266
    public void addDerivedIDAccessor(ObjectAccessor accessor){
267
        m_derivedIDAccessors.add(accessor);
268
    }
269
270
    /**
265
    /**
271
     * INTERNAL:
266
     * INTERNAL:
272
     */
267
     */
Lines 565-572 Link Here
565
    /**
560
    /**
566
     * INTERNAL:
561
     * INTERNAL:
567
     */
562
     */
568
    public List<ObjectAccessor> getDerivedIDAccessors(){
563
    public List<ObjectAccessor> getDerivedIdAccessors(){
569
        return m_derivedIDAccessors;
564
        return m_derivedIdAccessors;
570
    }
565
    }
571
    
566
    
572
    /**
567
    /**
Lines 1224-1234 Link Here
1224
    public void processAccessors(MetadataDescriptor owningDescriptor) {
1219
    public void processAccessors(MetadataDescriptor owningDescriptor) {
1225
        for (MappingAccessor accessor : m_accessors.values()) {
1220
        for (MappingAccessor accessor : m_accessors.values()) {
1226
            if (! accessor.isProcessed()) {
1221
            if (! accessor.isProcessed()) {
1227
                if (accessor.isDerivedId()){
1228
                    m_derivedIDAccessors.add((ObjectAccessor) accessor);
1229
                    getProject().addAccessorWithDerivedIDs(m_classAccessor);
1230
                }
1231
                
1232
                // We need to defer the processing of some mappings to stage
1222
                // We need to defer the processing of some mappings to stage
1233
                // 3 processing. Accessors are added to different lists since
1223
                // 3 processing. Accessors are added to different lists since
1234
                // the order or processing of those accessors is important.
1224
                // the order or processing of those accessors is important.
Lines 1268-1274 Link Here
1268
                } else if (accessor.isDirectCollection()) {
1258
                } else if (accessor.isDirectCollection()) {
1269
                    getProject().addDirectCollectionAccessor(accessor);
1259
                    getProject().addDirectCollectionAccessor(accessor);
1270
                } else if (accessor.isRelationship()) {
1260
                } else if (accessor.isRelationship()) {
1271
                    addRelationshipAccessor(accessor);
1261
                    if (accessor.derivesId()) {
1262
                        m_derivedIdAccessors.add((ObjectAccessor) accessor);
1263
                        getProject().addAccessorWithDerivedId(m_classAccessor);
1264
                    } else {
1265
                        addRelationshipAccessor(accessor);
1266
                    }
1272
                } else {
1267
                } else {
1273
                    accessor.process();
1268
                    accessor.process();
1274
                }
1269
                }
Lines 1300-1307 Link Here
1300
     * INTERNAL:
1295
     * INTERNAL:
1301
     * Set the cacheable value of this descriptor.
1296
     * Set the cacheable value of this descriptor.
1302
     */
1297
     */
1303
    public boolean setCacheable(Boolean cacheable) {
1298
    public void setCacheable(Boolean cacheable) {
1304
        return m_cacheable = cacheable;
1299
        m_cacheable = cacheable;
1305
    }
1300
    }
1306
    
1301
    
1307
    /**
1302
    /**
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metadata/MetadataProject.java (-18 / +10 lines)
Lines 183-190 Link Here
183
    // Class accessors that have a customizer.
183
    // Class accessors that have a customizer.
184
    private HashSet<ClassAccessor> m_accessorsWithCustomizer;
184
    private HashSet<ClassAccessor> m_accessorsWithCustomizer;
185
    
185
    
186
    // Class accessors that have Ids derived from relationships.
186
    // Class accessors that have their id derived from a relationship.
187
    private HashSet<ClassAccessor> m_accessorsWithDerivedIDs;
187
    private HashSet<ClassAccessor> m_accessorsWithDerivedId;
188
    
188
    
189
    // All direct collection accessors.
189
    // All direct collection accessors.
190
    private HashSet<DirectCollectionAccessor> m_directCollectionAccessors;
190
    private HashSet<DirectCollectionAccessor> m_directCollectionAccessors;
Lines 246-254 Link Here
246
        m_sequenceGenerators = new HashMap<String, SequenceGeneratorMetadata>();
246
        m_sequenceGenerators = new HashMap<String, SequenceGeneratorMetadata>();
247
        
247
        
248
        m_converters = new HashMap<String, AbstractConverterMetadata>();
248
        m_converters = new HashMap<String, AbstractConverterMetadata>();
249
        m_accessorsWithDerivedId = new HashSet<ClassAccessor>();
249
        
250
        
250
        m_accessorsWithDerivedIDs = new HashSet<ClassAccessor>();
251
        
252
        m_metamodelMappedSuperclasses = new HashMap<String, MappedSuperclassAccessor>();
251
        m_metamodelMappedSuperclasses = new HashMap<String, MappedSuperclassAccessor>();
253
    }
252
    }
254
    
253
    
Lines 294-301 Link Here
294
    /**
293
    /**
295
     * INTERNAL:
294
     * INTERNAL:
296
     */
295
     */
297
    public void addAccessorWithDerivedIDs(ClassAccessor accessor) {
296
    public void addAccessorWithDerivedId(ClassAccessor accessor) {
298
        m_accessorsWithDerivedIDs.add(accessor);
297
        m_accessorsWithDerivedId.add(accessor);
299
    }
298
    }
300
    
299
    
301
    /**
300
    /**
Lines 625-637 Link Here
625
    /**
624
    /**
626
     * INTERNAL:
625
     * INTERNAL:
627
     */
626
     */
628
    public Set<ClassAccessor> getAccessorsWithDerivedIDs() {
629
        return m_accessorsWithDerivedIDs;
630
    }
631
    
632
    /**
633
     * INTERNAL:
634
     */
635
    public Collection<ClassAccessor> getAllAccessors() {
627
    public Collection<ClassAccessor> getAllAccessors() {
636
        return m_allAccessors.values();
628
        return m_allAccessors.values();
637
    }
629
    }
Lines 1012-1019 Link Here
1012
        HashSet<ClassAccessor> processed = new HashSet();
1004
        HashSet<ClassAccessor> processed = new HashSet();
1013
        HashSet<ClassAccessor> processing = new HashSet();
1005
        HashSet<ClassAccessor> processing = new HashSet();
1014
        
1006
        
1015
        for (ClassAccessor classAccessor : getAccessorsWithDerivedIDs()) {
1007
        for (ClassAccessor classAccessor : m_accessorsWithDerivedId) {
1016
            classAccessor.processDerivedIDs(processing, processed);
1008
            classAccessor.processDerivedId(processing, processed);
1017
        }
1009
        }
1018
    }
1010
    }
1019
    
1011
    
Lines 1303-1310 Link Here
1303
     */
1295
     */
1304
    public void processStage2() {
1296
    public void processStage2() {
1305
        // 266912: process mappedSuperclasses separately from entity descriptors
1297
        // 266912: process mappedSuperclasses separately from entity descriptors
1306
        for(MappedSuperclassAccessor msAccessor : m_metamodelMappedSuperclasses.values()) {
1298
        for (MappedSuperclassAccessor msAccessor : m_metamodelMappedSuperclasses.values()) {
1307
            if(!msAccessor.isProcessed()) {               
1299
            if (! msAccessor.isProcessed()) {               
1308
                msAccessor.processMetamodelDescriptor();    
1300
                msAccessor.processMetamodelDescriptor();    
1309
            }
1301
            }
1310
        }
1302
        }
Lines 1337-1343 Link Here
1337
1329
1338
        // 2 - Process all the direct collection accessors we found. This list
1330
        // 2 - Process all the direct collection accessors we found. This list
1339
        // does not include direct collections to an embeddable class.
1331
        // does not include direct collections to an embeddable class.
1340
         processDirectCollectionAccessors();
1332
        processDirectCollectionAccessors();
1341
        
1333
        
1342
        // 3 - Process the sequencing metadata now that every entity has a 
1334
        // 3 - Process the sequencing metadata now that every entity has a 
1343
        // validated primary key.
1335
        // validated primary key.
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/metamodel/IdentifiableTypeImpl.java (-1 / +2 lines)
Lines 32-37 Link Here
32
import org.eclipse.persistence.internal.helper.DatabaseField;
32
import org.eclipse.persistence.internal.helper.DatabaseField;
33
import org.eclipse.persistence.internal.jpa.CMP3Policy;
33
import org.eclipse.persistence.internal.jpa.CMP3Policy;
34
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
34
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
35
import org.eclipse.persistence.internal.sessions.AbstractSession;
35
import org.eclipse.persistence.mappings.DatabaseMapping;
36
import org.eclipse.persistence.mappings.DatabaseMapping;
36
37
37
/**
38
/**
Lines 213-219 Link Here
213
            if(pkMappings.isEmpty()) {
214
            if(pkMappings.isEmpty()) {
214
                // Search the mappings for Id mappings
215
                // Search the mappings for Id mappings
215
                for(DatabaseMapping aMapping : getDescriptor().getMappings()) {                    
216
                for(DatabaseMapping aMapping : getDescriptor().getMappings()) {                    
216
                    if(aMapping.isDerivedIdMapping()) {
217
                    if(aMapping.isJPAId()) {
217
                        String attributeName = aMapping.getAttributeName();
218
                        String attributeName = aMapping.getAttributeName();
218
                        // get the attribute Id (declared or not)
219
                        // get the attribute Id (declared or not)
219
                        Attribute anAttribute = this.getAttribute(attributeName);
220
                        Attribute anAttribute = this.getAttribute(attributeName);

Return to bug 290567