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 288972 | Differences between
and this patch

Collapse All | Expand All

(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/ClassDescriptor.java (-6 / +69 lines)
Lines 12-17 Link Here
12
 *     stardif - updates for Cacaded locking and inheritance
12
 *     stardif - updates for Cacaded locking and inheritance
13
 *     02/20/2009-1.1 Guy Pelletier 
13
 *     02/20/2009-1.1 Guy Pelletier 
14
 *       - 259829: TABLE_PER_CLASS with abstract classes does not work
14
 *       - 259829: TABLE_PER_CLASS with abstract classes does not work
15
 *     11/19/2009-2.0 Michael O'Brien 
16
 *        - 288972: skip initialization of inherited Id mappings declared on 
17
 *        MappedSuperclass RelationalDescriptors that were introduced as 
18
 *        partially initialized descriptors for 266912 in support of the JPA 2.0 implementation.
15
 ******************************************************************************/  
19
 ******************************************************************************/  
16
package org.eclipse.persistence.descriptors;
20
package org.eclipse.persistence.descriptors;
17
21
Lines 2569-2575 Link Here
2569
    public boolean hasWrapperPolicy() {
2573
    public boolean hasWrapperPolicy() {
2570
        return this.wrapperPolicy != null;
2574
        return this.wrapperPolicy != null;
2571
    }
2575
    }
2572
2576
    
2573
    /**
2577
    /**
2574
     * INTERNAL:
2578
     * INTERNAL:
2575
     * Initialize the mappings as a separate step.
2579
     * Initialize the mappings as a separate step.
Lines 2625-2634 Link Here
2625
            setMappings(mappings);
2629
            setMappings(mappings);
2626
        }
2630
        }
2627
2631
2632
        boolean skipInitializationOfIdClassMappingDeclaredOnMappedSuperclass = false;        
2628
        for (Enumeration mappingsEnum = getMappings().elements(); mappingsEnum.hasMoreElements();) {
2633
        for (Enumeration mappingsEnum = getMappings().elements(); mappingsEnum.hasMoreElements();) {
2629
            DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement();
2634
            DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement();
2630
            validateMappingType(mapping);
2635
            validateMappingType(mapping);
2631
            mapping.initialize(session);
2636
            // 288972: @Id mappings declared on MappedSuperclass chains are not initialized as part of Metamodel API processing in 266912
2637
            skipInitializationOfIdClassMappingDeclaredOnMappedSuperclass = shouldSkipInitializationForMappedSuperclassIdMapping(mapping, session);
2638
2639
            // 288972: skip initialization of id mappings on mappedSuperclasses - as the fields are not initialized on the descriptor
2640
            if(!skipInitializationOfIdClassMappingDeclaredOnMappedSuperclass) {
2641
                mapping.initialize(session);
2642
            }
2632
            if (mapping.isLockableMapping()){
2643
            if (mapping.isLockableMapping()){
2633
                getLockableMappings().add(mapping);
2644
                getLockableMappings().add(mapping);
2634
            }
2645
            }
Lines 2650-2656 Link Here
2650
            }
2661
            }
2651
            
2662
            
2652
            // Add all the fields in the mapping to myself.
2663
            // Add all the fields in the mapping to myself.
2653
            Helper.addAllUniqueToVector(getFields(), mapping.getFields());
2664
            // 288972: skip initialization of id mappings on mappedSuperclasses - as the fields are not initialized on the descriptor
2665
            if(!skipInitializationOfIdClassMappingDeclaredOnMappedSuperclass) { 
2666
                Helper.addAllUniqueToVector(getFields(), mapping.getFields());
2667
            }
2654
        }
2668
        }
2655
        
2669
        
2656
        if(hasMappingsPostCalculateChangesOnDeleted()) {
2670
        if(hasMappingsPostCalculateChangesOnDeleted()) {
Lines 2713-2721 Link Here
2713
2727
2714
        // Initialize the allFields to its fields, this can be done now because the fields have been computed.
2728
        // Initialize the allFields to its fields, this can be done now because the fields have been computed.
2715
        setAllFields((Vector)getFields().clone());
2729
        setAllFields((Vector)getFields().clone());
2730
        getObjectBuilder().initialize(session); // 288972: some initialization for Id mappings declared on mappedSuperclasses will not occur by design
2716
2731
2717
        getObjectBuilder().initialize(session);
2718
2719
        if (shouldOrderMappings()) {
2732
        if (shouldOrderMappings()) {
2720
            // PERF: Ensure direct primary key mappings are first.
2733
            // PERF: Ensure direct primary key mappings are first.
2721
            for (int index = getObjectBuilder().getPrimaryKeyMappings().size() - 1; index >= 0; index--) {
2734
            for (int index = getObjectBuilder().getPrimaryKeyMappings().size() - 1; index >= 0; index--) {
Lines 2732-2738 Link Here
2732
            }
2745
            }
2733
        }
2746
        }
2734
2747
2735
        if (usesOptimisticLocking() && (!isChildDescriptor())) {
2748
        if (usesOptimisticLocking() && (!isChildDescriptor()) ) {
2736
            getOptimisticLockingPolicy().initialize(session);
2749
            getOptimisticLockingPolicy().initialize(session);
2737
        }
2750
        }
2738
        if (hasInterfacePolicy() || isDescriptorForInterface()) {
2751
        if (hasInterfacePolicy() || isDescriptorForInterface()) {
Lines 4651-4656 Link Here
4651
    }
4664
    }
4652
4665
4653
    /**
4666
    /**
4667
     * INTERNAL:
4668
     * Return whether the mapping should skip initialization.
4669
     * The only case where this would be true would be for Id mappings that are
4670
     * declared on MappedSuperclasses - the RelationalDescriptor in this case is one that
4671
     * does not require a database table and is only partially initialized.<br>
4672
     * These descriptors were introduced as partially initialized descriptors for 266912 in support of the JPA 2.0 implementation.
4673
     * http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/metamodel_api#DI_78:_20090909:_Composite_.40IdClass_on_inherited_MappedSuperclass_chain_causes_new_ValidationException
4674
4675
     * @param mapping
4676
     * @param session
4677
     * @since Java Persistence 2.0 
4678
     * @return
4679
     */
4680
    public boolean shouldSkipInitializationForMappedSuperclassIdMapping(DatabaseMapping mapping, AbstractSession session) {
4681
        // 288972: @Id mappings defined on MappedSuperclass chains are not initialized as part of Metamodel API processing in 266912
4682
        if(mapping.isJPAId() && null != mapping.getDescriptor().getCMPPolicy()) { 
4683
            Class pkClassDefinedOnMappedSuperclassParent = mapping.getDescriptor().getCMPPolicy().getPKClass();
4684
            // if there is no pkClass then we don't need to check further
4685
            if(null != pkClassDefinedOnMappedSuperclassParent) {
4686
                Class mappingAttributeFieldClazz = null;                
4687
                if(mapping.getAttributeAccessor() instanceof MethodAttributeAccessor) {
4688
                    mappingAttributeFieldClazz = ((MethodAttributeAccessor)mapping.getAttributeAccessor()).getGetMethodReturnType();
4689
                } else if(mapping.getAttributeAccessor() instanceof InstanceVariableAttributeAccessor) {
4690
                    mappingAttributeFieldClazz = ((InstanceVariableAttributeAccessor)mapping.getAttributeAccessor())
4691
                    .getAttributeField().getDeclaringClass();
4692
                }
4693
                // 20091118:1100: This section still undergoing refactoring 
4694
                if(null != mappingAttributeFieldClazz) {
4695
                    //  msDescriptor has __METAMODEL_RESERVED_IN_MEM_ONLY_TABLE_NAME
4696
                    for(RelationalDescriptor msDescriptor : session.getProject().getMappedSuperclassDescriptors().values()) {
4697
                        // we are looking for all inherited MS descriptors for this mapping
4698
                        if(msDescriptor.getJavaClassName().equals(mappingAttributeFieldClazz.getCanonicalName())) {
4699
                            // check that the id is part of a composite key
4700
                            for (List<String> idClassNamesList : session.getProject().getMetamodelIdClassMap().values()) {
4701
                                for(String idClassName : idClassNamesList) {
4702
                                    // object identity will not work as the String class instances may be in different classLoaders
4703
                                    if(idClassName.equals(pkClassDefinedOnMappedSuperclassParent.getCanonicalName())) {                                        
4704
                                        return true;
4705
                                    }
4706
                                }                            
4707
                            }
4708
                        }
4709
                    }
4710
                }
4711
            }
4712
        }
4713
        return false;
4714
    }
4715
    
4716
    /**
4654
     * PUBLIC:
4717
     * PUBLIC:
4655
     * Return true if this descriptor is using CacheIdentityMap
4718
     * Return true if this descriptor is using CacheIdentityMap
4656
     */
4719
     */
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/descriptors/ObjectBuilder.java (-52 / +79 lines)
Lines 11-16 Link Here
11
 *     Oracle - initial API and implementation from Oracle TopLink
11
 *     Oracle - initial API and implementation from Oracle TopLink
12
 *     07/16/2009-2.0 Guy Pelletier 
12
 *     07/16/2009-2.0 Guy Pelletier 
13
 *       - 277039: JPA 2.0 Cache Usage Settings
13
 *       - 277039: JPA 2.0 Cache Usage Settings
14
 *     11/19/2009-2.0 Michael O'Brien 
15
 *        - 288972: skip initialization of inherited Id mappings declared on 
16
 *        MappedSuperclass RelationalDescriptors that were introduced as 
17
 *        partially initialized descriptors for 266912 in support of the JPA 2.0 implementation.
14
 ******************************************************************************/  
18
 ******************************************************************************/  
15
package org.eclipse.persistence.internal.descriptors;
19
package org.eclipse.persistence.internal.descriptors;
16
20
Lines 2281-2286 Link Here
2281
        getCloningMappings().clear();
2285
        getCloningMappings().clear();
2282
        getEagerMappings().clear();
2286
        getEagerMappings().clear();
2283
        getRelationshipMappings().clear();
2287
        getRelationshipMappings().clear();
2288
        // 288972: relax validation rules for descriptors representing MappedSuperclasses
2289
        boolean containsMappedSuperclassDeclaredIdMappings = false;
2284
2290
2285
        for (Enumeration mappings = this.descriptor.getMappings().elements();
2291
        for (Enumeration mappings = this.descriptor.getMappings().elements();
2286
                 mappings.hasMoreElements();) {
2292
                 mappings.hasMoreElements();) {
Lines 2312-2362 Link Here
2312
            }
2318
            }
2313
2319
2314
            // Add field to mapping association
2320
            // Add field to mapping association
2315
            for (DatabaseField field : mapping.getFields()) {
2321
            // 288972: skip initialization of id mappings declared above on mappedSuperclasses - as the fields are not initialized on the descriptor by design
2316
2322
            if(!getDescriptor().shouldSkipInitializationForMappedSuperclassIdMapping(mapping, session)) {
2317
                if (mapping.isReadOnly()) {
2323
                for (DatabaseField field : mapping.getFields()) {
2318
                    List readOnlyMappings = getReadOnlyMappingsByField().get(field);
2324
                    if (mapping.isReadOnly()) {
2325
                        List readOnlyMappings = getReadOnlyMappingsByField().get(field);
2319
    
2326
    
2320
                    if (readOnlyMappings == null) {
2327
                        if (readOnlyMappings == null) {
2321
                        readOnlyMappings = new ArrayList();
2328
                            readOnlyMappings = new ArrayList();
2322
                        getReadOnlyMappingsByField().put(field, readOnlyMappings);
2329
                            getReadOnlyMappingsByField().put(field, readOnlyMappings);
2323
                    }
2330
                        }
2324
    
2331
    
2325
                    readOnlyMappings.add(mapping);
2332
                        readOnlyMappings.add(mapping);
2326
                } else {
2333
                    } else {
2327
                    if (mapping.isAggregateObjectMapping()) {
2334
                        if (mapping.isAggregateObjectMapping()) {
2328
                        // For Embeddable class, we need to test read-only 
2335
                            // For Embeddable class, we need to test read-only 
2329
                        // status of individual fields in the embeddable.
2336
                            // status of individual fields in the embeddable.
2330
                        ObjectBuilder aggregateObjectBuilder = ((AggregateObjectMapping)mapping).getReferenceDescriptor().getObjectBuilder();
2337
                            ObjectBuilder aggregateObjectBuilder = ((AggregateObjectMapping)mapping).getReferenceDescriptor().getObjectBuilder();
2331
                        
2338
                        
2332
                        // Look in the non-read-only fields mapping
2339
                            // Look in the non-read-only fields mapping
2333
                        DatabaseMapping aggregatedFieldMapping = aggregateObjectBuilder.getMappingForField(field);
2340
                            DatabaseMapping aggregatedFieldMapping = aggregateObjectBuilder.getMappingForField(field);
2334
    
2341
    
2335
                        if (aggregatedFieldMapping == null) { // mapping must be read-only
2342
                            if (aggregatedFieldMapping == null) { // mapping must be read-only
2336
                            List readOnlyMappings = getReadOnlyMappingsByField().get(field);
2343
                                List readOnlyMappings = getReadOnlyMappingsByField().get(field);
2337
                            
2344
                            
2338
                            if (readOnlyMappings == null) {
2345
                                if (readOnlyMappings == null) {
2339
                                readOnlyMappings = new ArrayList();
2346
                                    readOnlyMappings = new ArrayList();
2340
                                getReadOnlyMappingsByField().put(field, readOnlyMappings);
2347
                                    getReadOnlyMappingsByField().put(field, readOnlyMappings);
2348
                                }
2349
    
2350
                                readOnlyMappings.add(mapping);
2351
                            } else {
2352
                                getMappingsByField().put(field, mapping);
2341
                            }
2353
                            }
2342
    
2354
                        } else { // Not an embeddable mapping
2343
                            readOnlyMappings.add(mapping);
2355
                            if (getMappingsByField().containsKey(field) || mapping.getDescriptor().getAdditionalWritableMapKeyFields().contains(field)) {  
2344
                        } else {
2356
                                session.getIntegrityChecker().handleError(DescriptorException.multipleWriteMappingsForField(field.toString(), mapping));
2345
                            getMappingsByField().put(field, mapping);
2357
                            } else {
2358
                                getMappingsByField().put(field, mapping);
2359
                            }
2346
                        }
2360
                        }
2347
                    } else { // Not an embeddable mapping
2348
                        if (getMappingsByField().containsKey(field) || mapping.getDescriptor().getAdditionalWritableMapKeyFields().contains(field)) {  
2349
                            session.getIntegrityChecker().handleError(DescriptorException.multipleWriteMappingsForField(field.toString(), mapping));
2350
                        } else {
2351
                            getMappingsByField().put(field, mapping);
2352
                        }
2353
                    }
2361
                    }
2354
                }
2362
                }
2363
            } else {
2364
                containsMappedSuperclassDeclaredIdMappings = true;
2355
            }
2365
            }
2356
        }
2366
        }
2357
        this.isSimple = getRelationshipMappings().isEmpty();
2367
        this.isSimple = getRelationshipMappings().isEmpty();
2358
2368
2359
        initializePrimaryKey(session);
2369
        initializePrimaryKey(session, containsMappedSuperclassDeclaredIdMappings);
2360
        initializeJoinedAttributes();
2370
        initializeJoinedAttributes();
2361
        
2371
        
2362
        if (this.descriptor.usesSequenceNumbers()) {
2372
        if (this.descriptor.usesSequenceNumbers()) {
Lines 2434-2441 Link Here
2434
2444
2435
    /**
2445
    /**
2436
     * Cache primary key and non primary key mappings.
2446
     * Cache primary key and non primary key mappings.
2447
     * @param session
2448
     * @throws DescriptorException
2437
     */
2449
     */
2438
    public void initializePrimaryKey(AbstractSession session) throws DescriptorException {
2450
    public void initializePrimaryKey(AbstractSession session) throws DescriptorException {
2451
        initializePrimaryKey(session, false);
2452
    }
2453
    
2454
    /**
2455
     * INTERNAL:
2456
     * Cache primary key and non primary key mappings. 
2457
     * @param session
2458
     * @param containsMappedSuperclassDeclaredIdMappings
2459
     * @throws DescriptorException
2460
     */
2461
    public void initializePrimaryKey(AbstractSession session, boolean containsMappedSuperclassDeclaredIdMappings) throws DescriptorException {
2439
        List primaryKeyFields = this.descriptor.getPrimaryKeyFields();
2462
        List primaryKeyFields = this.descriptor.getPrimaryKeyFields();
2440
        if(primaryKeyFields.isEmpty() && getDescriptor().isAggregateCollectionDescriptor()) {
2463
        if(primaryKeyFields.isEmpty() && getDescriptor().isAggregateCollectionDescriptor()) {
2441
            // populate primaryKeys with all mapped fields found in the main table.
2464
            // populate primaryKeys with all mapped fields found in the main table.
Lines 2479-2509 Link Here
2479
                if(this.descriptor.isDescriptorTypeAggregate()) {
2502
                if(this.descriptor.isDescriptorTypeAggregate()) {
2480
                    this.mayHaveNullInPrimaryKey = true;
2503
                    this.mayHaveNullInPrimaryKey = true;
2481
                } else {
2504
                } else {
2482
                    throw DescriptorException.noMappingForPrimaryKey(primaryKeyField, this.descriptor);
2505
                    // 288972: skip initialization of id mappings on mappedSuperclasses - as the fields are not initialized on the descriptor
2506
                    if(!containsMappedSuperclassDeclaredIdMappings) {
2507
                        throw DescriptorException.noMappingForPrimaryKey(primaryKeyField, this.descriptor);
2508
                    }
2483
                }
2509
                }
2484
            }
2510
            }
2511
            if(!containsMappedSuperclassDeclaredIdMappings) {
2512
                getPrimaryKeyMappings().add(mapping);
2513
                if (mapping != null) {
2514
                    mapping.setIsPrimaryKeyMapping(true);
2515
                }
2485
2516
2486
            getPrimaryKeyMappings().add(mapping);
2517
                // Use the same mapping to map the additional table primary key fields.
2487
            if (mapping != null) {
2518
                // This is required if someone tries to map to one of these fields.
2488
                mapping.setIsPrimaryKeyMapping(true);
2519
                if (this.descriptor.hasMultipleTables() && (mapping != null)) {
2489
            }
2520
                    for (Map keyMapping : this.descriptor.getAdditionalTablePrimaryKeyFields().values()) {
2521
                        DatabaseField secondaryField = (DatabaseField) keyMapping.get(primaryKeyField);
2490
2522
2491
            // Use the same mapping to map the additional table primary key fields.
2523
                        // This can be null in the custom multiple join case
2492
            // This is required if someone tries to map to one of these fields.
2524
                        if (secondaryField != null) {
2493
            if (this.descriptor.hasMultipleTables() && (mapping != null)) {
2525
                            getMappingsByField().put(secondaryField, mapping);
2494
                for (Map keyMapping : this.descriptor.getAdditionalTablePrimaryKeyFields().values()) {
2495
                    DatabaseField secondaryField = (DatabaseField) keyMapping.get(primaryKeyField);
2496
2526
2497
                    // This can be null in the custom multiple join case
2527
                            if (mapping.isAggregateObjectMapping()) {
2498
                    if (secondaryField != null) {
2528
                                // GF#1153,1391
2499
                        getMappingsByField().put(secondaryField, mapping);
2529
                                // If AggregateObjectMapping contain primary keys and the descriptor has multiple tables
2500
2530
                                // AggregateObjectMapping should know the the primary key join columns (secondaryField here)
2501
                        if (mapping.isAggregateObjectMapping()) {
2531
                                // to handle some cases properly
2502
                            // GF#1153,1391
2532
                                ((AggregateObjectMapping) mapping).addPrimaryKeyJoinField(primaryKeyField, secondaryField);
2503
                            // If AggregateObjectMapping contain primary keys and the descriptor has multiple tables
2533
                            }
2504
                            // AggregateObjectMapping should know the the primary key join columns (secondaryField here)
2505
                            // to handle some cases properly
2506
                            ((AggregateObjectMapping) mapping).addPrimaryKeyJoinField(primaryKeyField, secondaryField);
2507
                        }
2534
                        }
2508
                    }
2535
                    }
2509
                }
2536
                }
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/metamodel/MS_MS_Entity_Center.java (-7 / +7 lines)
Lines 20-38 Link Here
20
@MappedSuperclass
20
@MappedSuperclass
21
public abstract class MS_MS_Entity_Center extends MS_MS_Entity_Root {
21
public abstract class MS_MS_Entity_Center extends MS_MS_Entity_Root {
22
    
22
    
23
    //@Id // see 288972
23
    @Id // see 288972ffs
24
    // InstanceVariableAttributeAccessor testing
24
    // InstanceVariableAttributeAccessor testing
25
    @Column(name="MSMSENTITY_ID")    
25
    //@Column(name="MSMSENTITY_ID")    
26
    private Integer ident;
26
    private Integer identity;
27
27
28
    private String declaredCenterStringField;
28
    private String declaredCenterStringField;
29
    
29
    
30
    public Integer getIdent() {
30
    public Integer getIdentity() {
31
        return ident;
31
        return identity;
32
    }
32
    }
33
33
34
    public void setIdent(Integer ident) {
34
    public void setIdentity(Integer identity) {
35
        this.ident = ident;
35
        this.identity = identity;
36
    }
36
    }
37
37
38
    public String getDeclaredCenterStringField() {
38
    public String getDeclaredCenterStringField() {
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/metamodel/MetamodelTableCreator.java (-5 / +13 lines)
Lines 818-823 Link Here
818
        return table;
818
        return table;
819
    }
819
    }
820
820
821
    /**
822
     * This table defines a MappedSuperclass chain that defines a composite PK
823
     * that is distributed along the MappedSuperclass hierarchy of the form.
824
     * Root (MappedSuperclass)
825
     *   --> Center (MappedSuperclass)
826
     *             --> Leaf (Entity)
827
     */
821
    public static TableDefinition buildMS_MS_Entity_Leaf_Table() {
828
    public static TableDefinition buildMS_MS_Entity_Leaf_Table() {
822
        TableDefinition table = new TableDefinition();
829
        TableDefinition table = new TableDefinition();
823
        table.setName("CMP3_MM_MSMSENTITY_LEAF");
830
        table.setName("CMP3_MM_MSMSENTITY_LEAF");
Lines 855-869 Link Here
855
862
856
        // From MS-(MS)-Entity center
863
        // From MS-(MS)-Entity center
857
        FieldDefinition field = new FieldDefinition();
864
        FieldDefinition field = new FieldDefinition();
858
        field.setName("MSMSENTITY_ID");
865
        //field.setName("MSMSENTITY_ID");
866
        field.setName("IDENTITY");
859
        field.setTypeName("NUMERIC");
867
        field.setTypeName("NUMERIC");
860
        field.setSize(15);
868
        field.setSize(15);
861
        field.setShouldAllowNull(false);
869
        field.setShouldAllowNull(false);
862
        field.setIsPrimaryKey(false);//true);
870
        //field.setIsPrimaryKey(false);//true);
863
        //field.setIsPrimaryKey(true);
871
        field.setIsPrimaryKey(true);
864
        field.setUnique(false);
872
        field.setUnique(false);
865
        field.setIsIdentity(false);//true);
873
        //field.setIsIdentity(false);//true);
866
        //field.setIsIdentity(true);
874
        field.setIsIdentity(true);
867
        table.addField(field);
875
        table.addField(field);
868
        
876
        
869
        FieldDefinition field2 = new FieldDefinition();
877
        FieldDefinition field2 = new FieldDefinition();

Return to bug 288972