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 301063
Collapse All | Expand All

(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/config/QueryHints.java (-2 / +2 lines)
Lines 116-122 Link Here
116
     * <p>Configures a randomization on the expiry invalidation time.
116
     * <p>Configures a randomization on the expiry invalidation time.
117
     * This can be used to avoid bottlenecks from the cached values expiring at the same time.
117
     * This can be used to avoid bottlenecks from the cached values expiring at the same time.
118
     * By default expiry is not randomized.
118
     * By default expiry is not randomized.
119
     * Valid values are number of milliseconds, Integer or Strings that can be parsed to int values.
119
     * Valid values are "true" and "false", false is the default.
120
     * @see org.eclipse.persistence.descriptors.invalidation.TimeToLiveCacheInvalidationPolicy#setInvalidationRandomized(boolean)
120
     * @see org.eclipse.persistence.descriptors.invalidation.TimeToLiveCacheInvalidationPolicy#setInvalidationRandomized(boolean)
121
     */
121
     */
122
    public static final String QUERY_RESULTS_CACHE_RANDOMIZE_EXPIRY = "eclipselink.query-results-cache.randomize-expiry";
122
    public static final String QUERY_RESULTS_CACHE_RANDOMIZE_EXPIRY = "eclipselink.query-results-cache.randomize-expiry";
Lines 126-132 Link Here
126
     * <p>Configures null results to not be cached.
126
     * <p>Configures null results to not be cached.
127
     * This can be used to use the query cache as a secondary key index, and allow inserts of new objects.
127
     * This can be used to use the query cache as a secondary key index, and allow inserts of new objects.
128
     * By default null results are cached.
128
     * By default null results are cached.
129
     * Valid values are number of milliseconds, Integer or Strings that can be parsed to int values.
129
     * Valid values are "true" and "false", false is the default.
130
     * @see org.eclipse.persistence.queries.QueryResultsCachePolicy#setIsNullIgnored(boolean)
130
     * @see org.eclipse.persistence.queries.QueryResultsCachePolicy#setIsNullIgnored(boolean)
131
     */
131
     */
132
    public static final String QUERY_RESULTS_CACHE_IGNORE_NULL = "eclipselink.query-results-cache.ignore-null";
132
    public static final String QUERY_RESULTS_CACHE_IGNORE_NULL = "eclipselink.query-results-cache.ignore-null";
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/ClassDescriptor.java (-23 / +17 lines)
Lines 2619-2636 Link Here
2619
            Vector mappings = getMappings();
2619
            Vector mappings = getMappings();
2620
            Object[] mappingsArray = new Object[mappings.size()];
2620
            Object[] mappingsArray = new Object[mappings.size()];
2621
            for (int index = 0; index < mappings.size(); index++) {
2621
            for (int index = 0; index < mappings.size(); index++) {
2622
                mappingsArray[index] = mappings.elementAt(index);
2622
                mappingsArray[index] = mappings.get(index);
2623
            }
2623
            }
2624
            Arrays.sort(mappingsArray, new MappingCompare());
2624
            Arrays.sort(mappingsArray, new MappingCompare());
2625
            mappings = NonSynchronizedVector.newInstance(mappingsArray.length);
2625
            mappings = NonSynchronizedVector.newInstance(mappingsArray.length);
2626
            for (int index = 0; index < mappingsArray.length; index++) {
2626
            for (int index = 0; index < mappingsArray.length; index++) {
2627
                mappings.addElement(mappingsArray[index]);
2627
                mappings.add(mappingsArray[index]);
2628
            }
2628
            }
2629
            setMappings(mappings);
2629
            setMappings(mappings);
2630
        }
2630
        }
2631
2631
2632
        for (Enumeration mappingsEnum = getMappings().elements(); mappingsEnum.hasMoreElements();) {
2632
        for (DatabaseMapping mapping : getMappings()) {
2633
            DatabaseMapping mapping = (DatabaseMapping)mappingsEnum.nextElement();
2634
            validateMappingType(mapping);
2633
            validateMappingType(mapping);
2635
            mapping.initialize(session);
2634
            mapping.initialize(session);
2636
            if (mapping.isLockableMapping()){
2635
            if (mapping.isLockableMapping()){
Lines 2650-2663 Link Here
2650
2649
2651
            // JPA 2.0 Derived identities - build a map of derived id mappings.
2650
            // JPA 2.0 Derived identities - build a map of derived id mappings.
2652
            if (mapping.derivesId()) {
2651
            if (mapping.derivesId()) {
2653
                derivesIdMappings.put(mapping.getAttributeName(), mapping);
2652
                this.derivesIdMappings.put(mapping.getAttributeName(), mapping);
2654
            }
2653
            }
2655
            
2654
            
2656
            // Add all the fields in the mapping to myself.
2655
            // Add all the fields in the mapping to myself.
2657
            Helper.addAllUniqueToVector(getFields(), mapping.getFields());
2656
            Helper.addAllUniqueToVector(getFields(), mapping.getFields());
2658
        }
2657
        }
2659
        
2658
        
2660
        if(hasMappingsPostCalculateChangesOnDeleted()) {
2659
        if (hasMappingsPostCalculateChangesOnDeleted()) {
2661
            session.getProject().setHasMappingsPostCalculateChangesOnDeleted(true);
2660
            session.getProject().setHasMappingsPostCalculateChangesOnDeleted(true);
2662
        }
2661
        }
2663
2662
Lines 2682-2696 Link Here
2682
        if (hasInheritance()) {
2681
        if (hasInheritance()) {
2683
            getInheritancePolicy().initialize(session);
2682
            getInheritancePolicy().initialize(session);
2684
            if (getInheritancePolicy().isChildDescriptor()) {
2683
            if (getInheritancePolicy().isChildDescriptor()) {
2685
                for (Iterator iterator = getInheritancePolicy().getParentDescriptor().getMappings().iterator();
2684
                for (DatabaseMapping mapping : getInheritancePolicy().getParentDescriptor().getMappings()) {
2686
                         iterator.hasNext();) {
2687
                    DatabaseMapping mapping = (DatabaseMapping)iterator.next();
2688
                    if (mapping.isAggregateObjectMapping() || ((mapping.isForeignReferenceMapping() && (!mapping.isDirectCollectionMapping())) && (!((ForeignReferenceMapping)mapping).usesIndirection()))) {
2685
                    if (mapping.isAggregateObjectMapping() || ((mapping.isForeignReferenceMapping() && (!mapping.isDirectCollectionMapping())) && (!((ForeignReferenceMapping)mapping).usesIndirection()))) {
2689
                        getLockableMappings().add(mapping);// add those mappings from the parent.
2686
                        getLockableMappings().add(mapping);// add those mappings from the parent.
2690
                    }
2687
                    }
2691
                    // JPA 2.0 Derived identities - build a map of derived id mappings.
2688
                    // JPA 2.0 Derived identities - build a map of derived id mappings.
2692
                    if (mapping.derivesId()) {
2689
                    if (mapping.derivesId()) {
2693
                        derivesIdMappings.put(mapping.getAttributeName(), mapping);
2690
                        this.derivesIdMappings.put(mapping.getAttributeName(), mapping);
2694
                    }
2691
                    }
2695
                }
2692
                }
2696
            }
2693
            }
Lines 2705-2716 Link Here
2705
            Vector mappings = getMappings();
2702
            Vector mappings = getMappings();
2706
            Object[] mappingsArray = new Object[mappings.size()];
2703
            Object[] mappingsArray = new Object[mappings.size()];
2707
            for (int index = 0; index < mappings.size(); index++) {
2704
            for (int index = 0; index < mappings.size(); index++) {
2708
                mappingsArray[index] = mappings.elementAt(index);
2705
                mappingsArray[index] = mappings.get(index);
2709
            }
2706
            }
2710
            Arrays.sort(mappingsArray, new MappingCompare());
2707
            Arrays.sort(mappingsArray, new MappingCompare());
2711
            mappings = NonSynchronizedVector.newInstance(mappingsArray.length);
2708
            mappings = NonSynchronizedVector.newInstance(mappingsArray.length);
2712
            for (int index = 0; index < mappingsArray.length; index++) {
2709
            for (int index = 0; index < mappingsArray.length; index++) {
2713
                mappings.addElement(mappingsArray[index]);
2710
                mappings.add(mappingsArray[index]);
2714
            }
2711
            }
2715
            setMappings(mappings);
2712
            setMappings(mappings);
2716
        }
2713
        }
Lines 3238-3244 Link Here
3238
            field.setIndex(index);
3235
            field.setIndex(index);
3239
        }        
3236
        }        
3240
        // Set cache key type.
3237
        // Set cache key type.
3241
        if (getCacheKeyType() == null) {
3238
        if (getCacheKeyType() == null || (getCacheKeyType() == CacheKeyType.AUTO)) {
3242
            if ((getPrimaryKeyFields().size() > 1) || getObjectBuilder().isXMLObjectBuilder()) {
3239
            if ((getPrimaryKeyFields().size() > 1) || getObjectBuilder().isXMLObjectBuilder()) {
3243
                setCacheKeyType(CacheKeyType.CACHE_ID);
3240
                setCacheKeyType(CacheKeyType.CACHE_ID);
3244
            } else if (getPrimaryKeyFields().size() == 1) {
3241
            } else if (getPrimaryKeyFields().size() == 1) {
Lines 3251-3256 Link Here
3251
            } else {
3248
            } else {
3252
                setCacheKeyType(CacheKeyType.CACHE_ID);                
3249
                setCacheKeyType(CacheKeyType.CACHE_ID);                
3253
            }
3250
            }
3251
        } else if ((getCacheKeyType() == CacheKeyType.ID_VALUE) && (getPrimaryKeyFields().size() > 1)) {
3252
            session.getIntegrityChecker().handleError(DescriptorException.cannotUseIdValueForCompositeId(this));
3254
        }
3253
        }
3255
        getObjectBuilder().postInitialize(session);
3254
        getObjectBuilder().postInitialize(session);
3256
3255
Lines 5255-5262 Link Here
5255
     */
5254
     */
5256
    protected void validateAfterInitialization(AbstractSession session) {
5255
    protected void validateAfterInitialization(AbstractSession session) {
5257
        selfValidationAfterInitialization(session);
5256
        selfValidationAfterInitialization(session);
5258
        for (Enumeration mappings = getMappings().elements(); mappings.hasMoreElements();) {
5257
        for (DatabaseMapping mapping : getMappings()) {
5259
            ((DatabaseMapping)mappings.nextElement()).validateAfterInitialization(session);
5258
            mapping.validateAfterInitialization(session);
5260
        }
5259
        }
5261
    }
5260
    }
5262
5261
Lines 5266-5273 Link Here
5266
     */
5265
     */
5267
    protected void validateBeforeInitialization(AbstractSession session) {
5266
    protected void validateBeforeInitialization(AbstractSession session) {
5268
        selfValidationBeforeInitialization(session);
5267
        selfValidationBeforeInitialization(session);
5269
        for (Enumeration mappings = getMappings().elements(); mappings.hasMoreElements();) {
5268
        for (DatabaseMapping mapping : getMappings()) {
5270
            ((DatabaseMapping)mappings.nextElement()).validateBeforeInitialization(session);
5269
            mapping.validateBeforeInitialization(session);
5271
        }
5270
        }
5272
    }
5271
    }
5273
5272
Lines 5276-5292 Link Here
5276
     * Check that the qualifier on the table names are properly set.
5275
     * Check that the qualifier on the table names are properly set.
5277
     */
5276
     */
5278
    protected void verifyTableQualifiers(Platform platform) {
5277
    protected void verifyTableQualifiers(Platform platform) {
5279
        DatabaseTable table;
5280
        Enumeration tableEnumeration;
5281
        String tableQualifier = platform.getTableQualifier();
5278
        String tableQualifier = platform.getTableQualifier();
5282
5283
        if (tableQualifier.length() == 0) {
5279
        if (tableQualifier.length() == 0) {
5284
            return;
5280
            return;
5285
        }
5281
        }
5286
5282
5287
        tableEnumeration = getTables().elements();
5283
        for (DatabaseTable table : getTables()) {
5288
        while (tableEnumeration.hasMoreElements()) {
5289
            table = (DatabaseTable)tableEnumeration.nextElement();
5290
            if (table.getTableQualifier().length() == 0) {
5284
            if (table.getTableQualifier().length() == 0) {
5291
                table.setTableQualifier(tableQualifier);
5285
                table.setTableQualifier(tableQualifier);
5292
            }
5286
            }
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/descriptors/CMPPolicy.java (-4 / +4 lines)
Lines 354-367 Link Here
354
354
355
    /**
355
    /**
356
     * INTERNAL:
356
     * INTERNAL:
357
     * Create an instance of the composite primary key class for the key object.
357
     * Create an instance of the Id class or value from the object.
358
     */
358
     */
359
    public Object createPrimaryKeyInstance(Object key, AbstractSession session) {
359
    public Object createPrimaryKeyInstance(Object object, AbstractSession session) {
360
        KeyElementAccessor[] pkElementArray = this.getKeyClassFields(getPKClass());
360
        KeyElementAccessor[] pkElementArray = this.getKeyClassFields(getPKClass());
361
        ObjectBuilder builder = getDescriptor().getObjectBuilder();
361
        ObjectBuilder builder = getDescriptor().getObjectBuilder();
362
        if (pkElementArray.length == 1 && pkElementArray[0] instanceof KeyIsElementAccessor){
362
        if (pkElementArray.length == 1 && pkElementArray[0] instanceof KeyIsElementAccessor){
363
            DatabaseMapping mapping = builder.getMappingForAttributeName(pkElementArray[0].getAttributeName());
363
            DatabaseMapping mapping = builder.getMappingForAttributeName(pkElementArray[0].getAttributeName());
364
            Object fieldValue = mapping.getRealAttributeValueFromObject(key, session);
364
            Object fieldValue = mapping.getRealAttributeValueFromObject(object, session);
365
            if (mapping.isObjectReferenceMapping()){
365
            if (mapping.isObjectReferenceMapping()){
366
                fieldValue = mapping.getReferenceDescriptor().getCMPPolicy().createPrimaryKeyInstance(fieldValue, session);
366
                fieldValue = mapping.getReferenceDescriptor().getCMPPolicy().createPrimaryKeyInstance(fieldValue, session);
367
            }
367
            }
Lines 371-377 Link Here
371
        Object keyInstance = getPKClassInstance();
371
        Object keyInstance = getPKClassInstance();
372
        Set<ObjectReferenceMapping> usedObjectReferenceMappings = new HashSet<ObjectReferenceMapping>();
372
        Set<ObjectReferenceMapping> usedObjectReferenceMappings = new HashSet<ObjectReferenceMapping>();
373
        for (int index = 0; index < pkElementArray.length; index++) {
373
        for (int index = 0; index < pkElementArray.length; index++) {
374
            Object keyObj = key;
374
            Object keyObj = object;
375
            KeyElementAccessor accessor = pkElementArray[index];
375
            KeyElementAccessor accessor = pkElementArray[index];
376
            DatabaseField field = accessor.getDatabaseField();
376
            DatabaseField field = accessor.getDatabaseField();
377
            DatabaseMapping mapping = builder.getMappingForField(field);
377
            DatabaseMapping mapping = builder.getMappingForField(field);
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/exceptions/DescriptorException.java (-1 / +11 lines)
Lines 230-235 Link Here
230
    public final static int MULTIPLE_TARGET_FOREIGN_KEY_TABLES = 213;
230
    public final static int MULTIPLE_TARGET_FOREIGN_KEY_TABLES = 213;
231
    public final static int ONE_TO_ONE_MAPPING_CONFLICT = 214;
231
    public final static int ONE_TO_ONE_MAPPING_CONFLICT = 214;
232
    public final static int NO_RELATION_TABLE_MECHANISM = 215;
232
    public final static int NO_RELATION_TABLE_MECHANISM = 215;
233
    public final static int CANNOT_USE_ID_VALUE_FOR_COMPOSITE_ID = 216;
233
234
234
    /**
235
    /**
235
     * INTERNAL:
236
     * INTERNAL:
Lines 1993-2003 Link Here
1993
    }
1994
    }
1994
1995
1995
    public static DescriptorException noRelationTableMechanism(DatabaseMapping mapping) {
1996
    public static DescriptorException noRelationTableMechanism(DatabaseMapping mapping) {
1996
        Object[] args = {  };
1997
        Object[] args = { mapping };
1997
1998
1998
        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_RELATION_TABLE_MECHANISM, args), mapping);
1999
        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, NO_RELATION_TABLE_MECHANISM, args), mapping);
1999
        descriptorException.setErrorCode(NO_RELATION_TABLE_MECHANISM);
2000
        descriptorException.setErrorCode(NO_RELATION_TABLE_MECHANISM);
2000
        return descriptorException;
2001
        return descriptorException;
2001
    }
2002
    }
2002
2003
2004
2005
    public static DescriptorException cannotUseIdValueForCompositeId(ClassDescriptor descriptor) {
2006
        Object[] args = {  };
2007
2008
        DescriptorException descriptorException = new DescriptorException(ExceptionMessageGenerator.buildMessage(DescriptorException.class, CANNOT_USE_ID_VALUE_FOR_COMPOSITE_ID, args), descriptor);
2009
        descriptorException.setErrorCode(CANNOT_USE_ID_VALUE_FOR_COMPOSITE_ID);
2010
        return descriptorException;
2011
    }    
2012
2003
}
2013
}
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/exceptions/i18n/DescriptorExceptionResource.java (+1 lines)
Lines 224-229 Link Here
224
                                           { "213", "{0} requires all target foreign key fields to belong to the same table, but several were found: {1}." },
224
                                           { "213", "{0} requires all target foreign key fields to belong to the same table, but several were found: {1}." },
225
                                           { "214", "{0} specifies relation table, that is not compatible with addForeignKey(Name) method, or use addSourceRelationKeyField(Name) and addTargetRelationKeyFieldName methods instead."},
225
                                           { "214", "{0} specifies relation table, that is not compatible with addForeignKey(Name) method, or use addSourceRelationKeyField(Name) and addTargetRelationKeyFieldName methods instead."},
226
                                           { "215", "{0} must have non-null RelationTableMechanism."},
226
                                           { "215", "{0} must have non-null RelationTableMechanism."},
227
                                           { "216", "CacheKeyType cannot be ID_VALUE for a composite primary key.."},
227
228
228
    };
229
    };
229
230
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/descriptors/ObjectBuilder.java (-1 / +2 lines)
Lines 570-579 Link Here
570
        CacheKey unitOfWorkCacheKey = unitOfWork.getIdentityMapAccessorInstance().acquireLock(primaryKey, concreteDescriptor.getJavaClass(), concreteDescriptor);
570
        CacheKey unitOfWorkCacheKey = unitOfWork.getIdentityMapAccessorInstance().acquireLock(primaryKey, concreteDescriptor.getJavaClass(), concreteDescriptor);
571
        Object clone = unitOfWorkCacheKey.getObject();
571
        Object clone = unitOfWorkCacheKey.getObject();
572
        boolean found = clone != null;
572
        boolean found = clone != null;
573
        Object original = null; 
573
        Object original = null;
574
        try {
574
        try {
575
            // Only check parent cache if not in unit of work, or if a refresh is required.
575
            // Only check parent cache if not in unit of work, or if a refresh is required.
576
            if (!found || query.shouldRefreshIdentityMapResult()
576
            if (!found || query.shouldRefreshIdentityMapResult()
577
                    || query.shouldCacheQueryResults() // Need to build original to cache it.
577
                    || query.shouldRetrieveBypassCache()
578
                    || query.shouldRetrieveBypassCache()
578
                    || (concreteDescriptor.hasFetchGroupManager() && concreteDescriptor.getFetchGroupManager().isPartialObject(clone))) {
579
                    || (concreteDescriptor.hasFetchGroupManager() && concreteDescriptor.getFetchGroupManager().isPartialObject(clone))) {
579
                // This is normal case when we are not in transaction.
580
                // This is normal case when we are not in transaction.
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/identitymaps/IdentityMapManager.java (-5 / +7 lines)
Lines 927-933 Link Here
927
     * values of the parameters to the query so different parameters will have
927
     * values of the parameters to the query so different parameters will have
928
     * different cached results.
928
     * different cached results.
929
     */
929
     */
930
    public Object getQueryResult(ReadQuery query, Vector parameters, boolean shouldCheckExpiry) {
930
    public Object getQueryResult(ReadQuery query, List parameters, boolean shouldCheckExpiry) {
931
        if (query.getQueryResultsCachePolicy() == null) {
931
        if (query.getQueryResultsCachePolicy() == null) {
932
            return null;
932
            return null;
933
        }
933
        }
Lines 1226-1232 Link Here
1226
     * Query results are cached based on the parameter values provided to the query
1226
     * Query results are cached based on the parameter values provided to the query
1227
     * different parameter values access different caches.
1227
     * different parameter values access different caches.
1228
     */
1228
     */
1229
    public void putQueryResult(ReadQuery query, Vector parameters, Object results) {
1229
    public void putQueryResult(ReadQuery query, List parameters, Object results) {
1230
        if ((results == null) || (results == InvalidObject.instance())) {
1231
            if (query.getQueryResultsCachePolicy().isNullIgnored()) {
1232
                return;
1233
            }
1234
        }
1230
        // PERF: use query name, unless no name.
1235
        // PERF: use query name, unless no name.
1231
        Object queryKey = query.getName();
1236
        Object queryKey = query.getName();
1232
        if ((queryKey == null) || ((String)queryKey).length() == 0) {
1237
        if ((queryKey == null) || ((String)queryKey).length() == 0) {
Lines 1257-1265 Link Here
1257
        }
1262
        }
1258
        // Bug 6138532 - store InvalidObject for "no results", do not store null
1263
        // Bug 6138532 - store InvalidObject for "no results", do not store null
1259
        if (results == null) {
1264
        if (results == null) {
1260
            if (query.getQueryResultsCachePolicy().isNullIgnored()) {
1261
                return;
1262
            }
1263
            results = InvalidObject.instance();
1265
            results = InvalidObject.instance();
1264
        }
1266
        }
1265
        map.put(lookupParameters, results, null, queryTime);
1267
        map.put(lookupParameters, results, null, queryTime);
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/sessions/IdentityMapAccessor.java (-7 / +17 lines)
Lines 511-517 Link Here
511
        if (descriptor == null) {
511
        if (descriptor == null) {
512
            throw ValidationException.missingDescriptor(theClass.toString());
512
            throw ValidationException.missingDescriptor(theClass.toString());
513
        }
513
        }
514
        return this.getIdentityMap(descriptor);
514
        return getIdentityMap(descriptor);
515
    }
515
    }
516
516
517
    /**
517
    /**
Lines 519-534 Link Here
519
     * Get the identity map for the given class from the IdentityMapManager
519
     * Get the identity map for the given class from the IdentityMapManager
520
     */
520
     */
521
    public IdentityMap getIdentityMap(ClassDescriptor descriptor) {
521
    public IdentityMap getIdentityMap(ClassDescriptor descriptor) {
522
        return getIdentityMapManager().getIdentityMap(descriptor);
522
        return getIdentityMap(descriptor, false);
523
    }
523
    }
524
524
525
    /**
525
    /**
526
     * INTERNAL:
526
     * INTERNAL:
527
     * Get the identity map for the given class from the IdentityMapManager
528
     */
529
    public IdentityMap getIdentityMap(ClassDescriptor descriptor, boolean returnNullIfMissing) {
530
        return getIdentityMapManager().getIdentityMap(descriptor, returnNullIfMissing);
531
    }
532
533
    /**
534
     * INTERNAL:
527
     * Get the cached results associated with a query.  Results are cached by the
535
     * Get the cached results associated with a query.  Results are cached by the
528
     * values of the parameters to the query so different parameters will have
536
     * values of the parameters to the query so different parameters will have
529
     * different cached results.
537
     * different cached results.
530
     */
538
     */
531
    public Object getQueryResult(ReadQuery query, Vector parameters, boolean checkExpiry) {
539
    public Object getQueryResult(ReadQuery query, List parameters, boolean checkExpiry) {
532
        return getIdentityMapManager().getQueryResult(query, parameters, checkExpiry);
540
        return getIdentityMapManager().getQueryResult(query, parameters, checkExpiry);
533
    }
541
    }
534
542
Lines 1003-1009 Link Here
1003
     * Query results are cached based on the parameter values provided to the query
1011
     * Query results are cached based on the parameter values provided to the query
1004
     * different parameter values access different caches.
1012
     * different parameter values access different caches.
1005
     */
1013
     */
1006
    public void putQueryResult(ReadQuery query, Vector parameters, Object results) {
1014
    public void putQueryResult(ReadQuery query, List parameters, Object results) {
1007
        getIdentityMapManager().putQueryResult(query, parameters, results);
1015
        getIdentityMapManager().putQueryResult(query, parameters, results);
1008
    }
1016
    }
1009
1017
Lines 1131-1139 Link Here
1131
        Iterator descriptors = getSession().getDescriptors().values().iterator();
1139
        Iterator descriptors = getSession().getDescriptors().values().iterator();
1132
        while (descriptors.hasNext()) {
1140
        while (descriptors.hasNext()) {
1133
            ClassDescriptor descriptor = (ClassDescriptor)descriptors.next();
1141
            ClassDescriptor descriptor = (ClassDescriptor)descriptors.next();
1134
            for (Enumeration mapEnum = getIdentityMap(descriptor).elements();
1142
            IdentityMap cache = getIdentityMap(descriptor, true);
1135
                     mapEnum.hasMoreElements();) {
1143
            if (cache != null) {
1136
                iterator.startIterationOn(mapEnum.nextElement());
1144
                for (Enumeration mapEnum = cache.elements(); mapEnum.hasMoreElements();) {
1145
                    iterator.startIterationOn(mapEnum.nextElement());
1146
                }
1137
            }
1147
            }
1138
        }
1148
        }
1139
    }
1149
    }
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/sessions/IsolatedClientSessionIdentityMapAccessor.java (-5 / +5 lines)
Lines 289-299 Link Here
289
     * Get the identity map for the given class from the IdentityMapManager
289
     * Get the identity map for the given class from the IdentityMapManager
290
     */
290
     */
291
    @Override
291
    @Override
292
    public IdentityMap getIdentityMap(ClassDescriptor descriptor) {
292
    public IdentityMap getIdentityMap(ClassDescriptor descriptor, boolean returnNullIfMissing) {
293
        if (descriptor.isIsolated()) {
293
        if (descriptor.isIsolated()) {
294
            return getIdentityMapManager().getIdentityMap(descriptor);
294
            return getIdentityMapManager().getIdentityMap(descriptor, returnNullIfMissing);
295
        } else {
295
        } else {
296
            return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().getIdentityMap(descriptor);
296
            return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().getIdentityMap(descriptor, returnNullIfMissing);
297
        }
297
        }
298
    }
298
    }
299
299
Lines 304-310 Link Here
304
     * different cached results.
304
     * different cached results.
305
     */
305
     */
306
    @Override
306
    @Override
307
    public Object getQueryResult(ReadQuery query, Vector parameters, boolean checkExpiry) {
307
    public Object getQueryResult(ReadQuery query, List parameters, boolean checkExpiry) {
308
        if (((IsolatedClientSession)session).isIsolatedQuery(query)) {
308
        if (((IsolatedClientSession)session).isIsolatedQuery(query)) {
309
            return getIdentityMapManager().getQueryResult(query, parameters, checkExpiry);
309
            return getIdentityMapManager().getQueryResult(query, parameters, checkExpiry);
310
        } else {
310
        } else {
Lines 412-418 Link Here
412
     * different parameter values access different caches.
412
     * different parameter values access different caches.
413
     */
413
     */
414
    @Override
414
    @Override
415
    public void putQueryResult(ReadQuery query, Vector parameters, Object results) {
415
    public void putQueryResult(ReadQuery query, List parameters, Object results) {
416
        if (((IsolatedClientSession)session).isIsolatedQuery(query)) {
416
        if (((IsolatedClientSession)session).isIsolatedQuery(query)) {
417
            getIdentityMapManager().putQueryResult(query, parameters, results);
417
            getIdentityMapManager().putQueryResult(query, parameters, results);
418
        } else {
418
        } else {
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/sessions/UnitOfWorkIdentityMapAccessor.java (-2 / +2 lines)
Lines 190-196 Link Here
190
     * results are only cached in the parent session for UnitOfWorks
190
     * results are only cached in the parent session for UnitOfWorks
191
     */
191
     */
192
    @Override
192
    @Override
193
    public Object getQueryResult(ReadQuery query, Vector parameters, boolean checkExpiry) {
193
    public Object getQueryResult(ReadQuery query, List parameters, boolean checkExpiry) {
194
        return ((UnitOfWorkImpl)this.session).getParent().getIdentityMapAccessorInstance().getQueryResult(query, parameters, checkExpiry);
194
        return ((UnitOfWorkImpl)this.session).getParent().getIdentityMapAccessorInstance().getQueryResult(query, parameters, checkExpiry);
195
    }
195
    }
196
196
Lines 203-209 Link Here
203
     *  Results are only cached in the parent session for UnitOfWorks
203
     *  Results are only cached in the parent session for UnitOfWorks
204
     */
204
     */
205
    @Override
205
    @Override
206
    public void putQueryResult(ReadQuery query, Vector parameters, Object results) {
206
    public void putQueryResult(ReadQuery query, List parameters, Object results) {
207
        ((UnitOfWorkImpl)this.session).getParent().getIdentityMapAccessorInstance().putQueryResult(query, parameters, results);
207
        ((UnitOfWorkImpl)this.session).getParent().getIdentityMapAccessorInstance().putQueryResult(query, parameters, results);
208
    }
208
    }
209
209
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/queries/DataReadQuery.java (-1 / +1 lines)
Lines 120-126 Link Here
120
                Object results = getQueryResults(session, row, true);
120
                Object results = getQueryResults(session, row, true);
121
                // Bug6138532 - if results are "cached no results", return null immediately
121
                // Bug6138532 - if results are "cached no results", return null immediately
122
                if (results == InvalidObject.instance) {
122
                if (results == InvalidObject.instance) {
123
                    return null;
123
                    return getContainerPolicy().containerInstance(0);
124
                }
124
                }
125
                if (results != null) {
125
                if (results != null) {
126
                    return results;
126
                    return results;
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/queries/ObjectLevelReadQuery.java (-14 lines)
Lines 105-116 Link Here
105
     */
105
     */
106
    protected int inMemoryQueryIndirectionPolicy;
106
    protected int inMemoryQueryIndirectionPolicy;
107
107
108
    /**
109
     * Used to set the read time on objects that use this query.
110
     * Should be set to the time the query returned from the database.
111
     */
112
    protected long executionTime = 0;
113
114
    /** Allow for a query level fetch group to be set. */
108
    /** Allow for a query level fetch group to be set. */
115
    protected FetchGroup fetchGroup;
109
    protected FetchGroup fetchGroup;
116
110
Lines 2118-2131 Link Here
2118
    }
2112
    }
2119
2113
2120
    /**
2114
    /**
2121
     * INTERNAL:
2122
     * Set the the time this query went to the database.
2123
     */
2124
    public void setExecutionTime(long executionTime) {
2125
        this.executionTime = executionTime;
2126
    }
2127
2128
    /**
2129
     * PUBLIC:
2115
     * PUBLIC:
2130
     * Set the example object of the query to be the newExampleObject.
2116
     * Set the example object of the query to be the newExampleObject.
2131
     * The example object is used for Query By Example.
2117
     * The example object is used for Query By Example.
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/queries/ReadAllQuery.java (-8 / +13 lines)
Lines 444-461 Link Here
444
    protected Object executeObjectLevelReadQuery() throws DatabaseException {
444
    protected Object executeObjectLevelReadQuery() throws DatabaseException {
445
        Object result = null;
445
        Object result = null;
446
        
446
        
447
        if (getContainerPolicy().overridesRead()) {
447
        if (this.containerPolicy.overridesRead()) {
448
            return getContainerPolicy().execute();
448
            return this.containerPolicy.execute();
449
        }
449
        }
450
450
451
        if (this.descriptor.isDescriptorForInterface()) {
451
        if (this.descriptor.isDescriptorForInterface()) {
452
            Object returnValue = this.descriptor.getInterfacePolicy().selectAllObjectsUsingMultipleTableSubclassRead(this);
452
            Object returnValue = this.descriptor.getInterfacePolicy().selectAllObjectsUsingMultipleTableSubclassRead(this);
453
            setExecutionTime(System.currentTimeMillis());
453
            this.executionTime = System.currentTimeMillis();
454
            return returnValue;
454
            return returnValue;
455
        }
455
        }
456
456
457
        List rows = getQueryMechanism().selectAllRows();
457
        List rows = getQueryMechanism().selectAllRows();
458
        setExecutionTime(System.currentTimeMillis());
458
        this.executionTime = System.currentTimeMillis();
459
        
459
        
460
        // If using 1-m joins, must set all rows.
460
        // If using 1-m joins, must set all rows.
461
        if (hasJoining() && this.joinedAttributeManager.isToManyJoin()) {
461
        if (hasJoining() && this.joinedAttributeManager.isToManyJoin()) {
Lines 465-471 Link Here
465
        if (this.session.isUnitOfWork()) {
465
        if (this.session.isUnitOfWork()) {
466
            result = registerResultInUnitOfWork(rows, (UnitOfWorkImpl)this.session, this.translationRow, true);// 
466
            result = registerResultInUnitOfWork(rows, (UnitOfWorkImpl)this.session, this.translationRow, true);// 
467
        } else {
467
        } else {
468
            result = getContainerPolicy().containerInstance(rows.size());
468
            result = this.containerPolicy.containerInstance(rows.size());
469
            this.descriptor.getObjectBuilder().buildObjectsInto(this, rows, result);
469
            this.descriptor.getObjectBuilder().buildObjectsInto(this, rows, result);
470
        }
470
        }
471
471
Lines 473-485 Link Here
473
            ComplexQueryResult complexResult = new ComplexQueryResult();
473
            ComplexQueryResult complexResult = new ComplexQueryResult();
474
            complexResult.setResult(result);
474
            complexResult.setResult(result);
475
            complexResult.setData(rows);
475
            complexResult.setData(rows);
476
            return complexResult;
476
            result = complexResult;
477
        }
477
        }
478
478
479
        // Add the other (already registered) results and return them.
479
        // Add the other (already registered) results and return them.
480
        if (getDescriptor().hasTablePerClassPolicy()) {
480
        if (this.descriptor.hasTablePerClassPolicy()) {
481
            result = containerPolicy.concatenateContainers(result, getDescriptor().getTablePerClassPolicy().selectAllObjectsUsingMultipleTableSubclassRead(this));
481
            result = this.containerPolicy.concatenateContainers(result, this.descriptor.getTablePerClassPolicy().selectAllObjectsUsingMultipleTableSubclassRead(this));
482
        }
482
        }
483
484
        // If the results were empty, then ensure they get cached still.
485
        if (shouldCacheQueryResults() && this.containerPolicy.isEmpty(result)) {
486
            this.temporaryCachedQueryResults = InvalidObject.instance();
487
        }
483
        
488
        
484
        return result;
489
        return result;
485
    }
490
    }
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/queries/ReadObjectQuery.java (-5 / +9 lines)
Lines 156-167 Link Here
156
     * It will cause the original to be cached in the query results if the query
156
     * It will cause the original to be cached in the query results if the query
157
     * is set to do so.
157
     * is set to do so.
158
     */
158
     */
159
    public void cacheResult(Object unwrappedOriginal) {
159
    public void cacheResult(Object object) {
160
        Object cachableObject = unwrappedOriginal;
160
        Object cachableObject = object;
161
        if (shouldUseWrapperPolicy()){
161
        if (object == null) {
162
            cachableObject = getSession().wrapObject(unwrappedOriginal);
162
            this.temporaryCachedQueryResults = InvalidObject.instance();
163
        } else {
164
            if (this.shouldUseWrapperPolicy) {
165
                cachableObject = this.session.wrapObject(object);
166
            }
167
            this.temporaryCachedQueryResults = cachableObject;
163
        }
168
        }
164
        setTemporaryCachedQueryResults(cachableObject);
165
    }
169
    }
166
170
167
171
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/queries/ReadQuery.java (-6 / +9 lines)
Lines 12-17 Link Here
12
 ******************************************************************************/  
12
 ******************************************************************************/  
13
package org.eclipse.persistence.queries;
13
package org.eclipse.persistence.queries;
14
14
15
import java.util.List;
15
import java.util.Vector;
16
import java.util.Vector;
16
import org.eclipse.persistence.internal.helper.NonSynchronizedVector;
17
import org.eclipse.persistence.internal.helper.NonSynchronizedVector;
17
import org.eclipse.persistence.internal.sessions.AbstractRecord;
18
import org.eclipse.persistence.internal.sessions.AbstractRecord;
Lines 107-114 Link Here
107
     */
108
     */
108
    protected void clonedQueryExecutionComplete(DatabaseQuery query, AbstractSession session) {
109
    protected void clonedQueryExecutionComplete(DatabaseQuery query, AbstractSession session) {
109
        if (shouldCacheQueryResults()) {
110
        if (shouldCacheQueryResults()) {
110
            // Cached query results must exist on the original query rather than the cloned one
111
            Object result = ((ReadQuery)query).getTemporaryCachedQueryResults();
111
            setQueryResults(((ReadQuery)query).getTemporaryCachedQueryResults(), query.getTranslationRow(), query.getSession());
112
            // If the temporary results were never set, then don't cache null.
113
            if (result != null) {
114
                // Cached query results must exist on the original query rather than the cloned one.
115
                setQueryResults(result, query.getTranslationRow(), query.getSession());
116
            }
112
        }
117
        }
113
    }
118
    }
114
119
Lines 216-225 Link Here
216
     */
221
     */
217
    protected Object getQueryResults(AbstractSession session, AbstractRecord row, boolean checkExpiry) {
222
    protected Object getQueryResults(AbstractSession session, AbstractRecord row, boolean checkExpiry) {
218
        // Check for null translation row.
223
        // Check for null translation row.
219
        Vector arguments = null;
224
        List arguments = null;
220
        if (row == null) {
225
        if (row != null) {
221
            arguments =  new NonSynchronizedVector(1);
222
        } else {
223
            arguments =  row.getValues();
226
            arguments =  row.getValues();
224
        }
227
        }
225
        return session.getIdentityMapAccessorInstance().getQueryResult(this, arguments, checkExpiry);
228
        return session.getIdentityMapAccessorInstance().getQueryResult(this, arguments, checkExpiry);
(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/sessions/IdentityMapAccessor.java (-1 / +1 lines)
Lines 273-279 Link Here
273
    /**
273
    /**
274
     * ADVANCED:
274
     * ADVANCED:
275
     * Returns the remaining life of the given Object.  This method is associated with use of
275
     * Returns the remaining life of the given Object.  This method is associated with use of
276
     * TopLink's cache invalidation feature and returns the difference between the next expiry
276
     * cache invalidation feature and returns the difference between the next expiry
277
     * time of the Object and its read time.  The method will return 0 for invalidated Objects.
277
     * time of the Object and its read time.  The method will return 0 for invalidated Objects.
278
     * @param object Object under consideration
278
     * @param object Object under consideration
279
     * @return long time in milliseconds
279
     * @return long time in milliseconds
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/advanced/Employee.java (-3 / +10 lines)
Lines 115-128 Link Here
115
        query="SELECT e FROM Employee e",
115
        query="SELECT e FROM Employee e",
116
        hints={
116
        hints={
117
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE, value="true"),
117
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE, value="true"),
118
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_TYPE, value="SOFT"),
118
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_TYPE, value="FULL"),
119
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_IGNORE_NULL, value="true"),
119
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_IGNORE_NULL, value="false"),
120
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_RANDOMIZE_EXPIRY, value="true"),
120
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_RANDOMIZE_EXPIRY, value="true"),
121
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_SIZE, value="200"),
121
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_SIZE, value="200"),
122
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_EXPIRY, value="5000")
122
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_EXPIRY, value="50000")
123
        }
123
        }
124
),
124
),
125
@NamedQuery(
125
@NamedQuery(
126
        name="CachedNoEmployees",
127
        query="SELECT e FROM Employee e where 1 <> 1",
128
        hints={
129
                @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE, value="true")
130
        }
131
),
132
@NamedQuery(
126
        name="CachedTimeOfDayAllEmployees",
133
        name="CachedTimeOfDayAllEmployees",
127
        query="SELECT e FROM Employee e",
134
        query="SELECT e FROM Employee e",
128
        hints={
135
        hints={
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/advanced/CacheImplJUnitTest.java (-21 / +38 lines)
Lines 17-22 Link Here
17
import junit.framework.TestSuite;
17
import junit.framework.TestSuite;
18
import org.eclipse.persistence.testing.models.jpa.advanced.*;
18
import org.eclipse.persistence.testing.models.jpa.advanced.*;
19
import org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl;
19
import org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl;
20
import org.eclipse.persistence.jpa.JpaCache;
20
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
21
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
21
22
22
/**
23
/**
Lines 33-46 Link Here
33
        super(name);
34
        super(name);
34
    }
35
    }
35
36
36
    public static void setUpClass() throws Exception {
37
    }
38
39
    public static void tearDownClass() throws Exception {
40
    }
41
42
    public void setUp() {
37
    public void setUp() {
43
44
        super.setUp();
38
        super.setUp();
45
        clearCache();
39
        clearCache();
46
    }
40
    }
Lines 55-60 Link Here
55
        suite.addTest(new CacheImplJUnitTest("testEvictClass"));
49
        suite.addTest(new CacheImplJUnitTest("testEvictClass"));
56
        suite.addTest(new CacheImplJUnitTest("testEvictAll"));
50
        suite.addTest(new CacheImplJUnitTest("testEvictAll"));
57
        suite.addTest(new CacheImplJUnitTest("testEvictContains"));
51
        suite.addTest(new CacheImplJUnitTest("testEvictContains"));
52
        suite.addTest(new CacheImplJUnitTest("testCacheAPI"));
58
        
53
        
59
        return suite;
54
        return suite;
60
    }
55
    }
Lines 79-91 Link Here
79
        em1.persist(e1);
74
        em1.persist(e1);
80
        commitTransaction(em1);
75
        commitTransaction(em1);
81
        closeEntityManager(em1);
76
        closeEntityManager(em1);
82
        try {
77
        boolean result = getEntityManagerFactory("default1").getCache().contains(Employee.class, 101);
83
            boolean result = getEntityManagerFactory("default1").getCache().contains(Employee.class, 101);
78
        assertTrue("Employee not found in cache", result);
84
            assertTrue("Assertion Error",result);
85
        } catch (Exception e) {
86
            e.printStackTrace();
87
        }
88
    }
79
    }
80
    
81
    /**
82
     * Test cache API.
83
     */
84
    public void testCacheAPI() {
85
        EntityManager em = createEntityManager("default1");
86
        beginTransaction(em);
87
        Employee employee = new Employee();
88
        employee.setFirstName("testCacheAPI");
89
        em.persist(employee);
90
        commitTransaction(em);
91
        closeEntityManager(em);
92
        JpaCache cache = (JpaCache)getEntityManagerFactory("default1").getCache();
93
        assertTrue("Employee not valid in cache", cache.isValid(employee));
94
        assertTrue("Employee not valid in cache", cache.isValid(Employee.class, employee.getId()));
95
        cache.timeToLive(employee);
96
        assertTrue("Employee not found in cache", cache.getObject(Employee.class, employee.getId()) != null);
97
        assertTrue("Employee not found in cache", cache.contains(employee));
98
        cache.evict(employee);
99
        cache.putObject(employee);
100
        cache.removeObject(employee);
101
        cache.removeObject(Employee.class, employee.getId());
102
        cache.clear();
103
        cache.clear(Employee.class);
104
        cache.clearQueryCache();
105
        cache.clearQueryCache("findAllEmployeesByIdAndFirstName");
106
        assertTrue("Employee id not correct", employee.getId().equals(cache.getId(employee)));
107
        cache.print();
108
        cache.print(Employee.class);
109
        cache.printLocks();
110
        cache.validate();
111
    }
89
112
90
    /**
113
    /**
91
     * Test of evict method, of class CacheImpl.
114
     * Test of evict method, of class CacheImpl.
Lines 111-118 Link Here
111
            Employee e3 = em4.find(Employee.class, 121);
134
            Employee e3 = em4.find(Employee.class, 121);
112
            afterCache = e3.getFirstName();
135
            afterCache = e3.getFirstName();
113
            assertNotSame("Assertion Error", beforeCache, afterCache);
136
            assertNotSame("Assertion Error", beforeCache, afterCache);
114
        } catch (Exception e) {
115
            e.printStackTrace();
116
        } finally {
137
        } finally {
117
            closeEntityManager(em3);
138
            closeEntityManager(em3);
118
            closeEntityManager(em4);
139
            closeEntityManager(em4);
Lines 141-148 Link Here
141
            Employee e5 = em7.find(Employee.class, 131);
162
            Employee e5 = em7.find(Employee.class, 131);
142
            String actual = e5.getFirstName();
163
            String actual = e5.getFirstName();
143
            assertNotSame("Assertion Error", expected, actual);
164
            assertNotSame("Assertion Error", expected, actual);
144
        } catch (Exception e) {
145
            e.printStackTrace();
146
        } finally {
165
        } finally {
147
            closeEntityManager(em6);
166
            closeEntityManager(em6);
148
            closeEntityManager(em7);
167
            closeEntityManager(em7);
Lines 180-187 Link Here
180
            String actualDept = d2.getName();
199
            String actualDept = d2.getName();
181
            assertEquals("Assertion Error", expectedEmp, actualEmp);
200
            assertEquals("Assertion Error", expectedEmp, actualEmp);
182
            assertEquals("Assertion Error", expectedDept, actualDept);
201
            assertEquals("Assertion Error", expectedDept, actualDept);
183
        } catch (Exception e) {
184
            e.printStackTrace();
185
        } finally {
202
        } finally {
186
            closeEntityManager(em9);
203
            closeEntityManager(em9);
187
        }
204
        }
Lines 196-202 Link Here
196
        em.persist(emp);
213
        em.persist(emp);
197
        commitTransaction(em);
214
        commitTransaction(em);
198
215
199
        try{
216
        try {
200
            assertTrue(em.getEntityManagerFactory().getCache().contains(Employee.class, emp.getId()));
217
            assertTrue(em.getEntityManagerFactory().getCache().contains(Employee.class, emp.getId()));
201
    
218
    
202
            em.clear();
219
            em.clear();
Lines 206-212 Link Here
206
            em.getEntityManagerFactory().getCache().evict(Employee.class, emp.getId());
223
            em.getEntityManagerFactory().getCache().evict(Employee.class, emp.getId());
207
            assertFalse(em.getEntityManagerFactory().getCache().contains(Employee.class, emp.getId()));
224
            assertFalse(em.getEntityManagerFactory().getCache().contains(Employee.class, emp.getId()));
208
        } finally {
225
        } finally {
209
            this.closeEntityManager(em);
226
            closeEntityManager(em);
210
        }
227
        }
211
228
212
    }
229
    }
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/jpql/AdvancedQueryTestSuite.java (-8 / +32 lines)
Lines 26-32 Link Here
26
import javax.persistence.EntityManager;
26
import javax.persistence.EntityManager;
27
import javax.persistence.RollbackException;
27
import javax.persistence.RollbackException;
28
28
29
import junit.framework.Assert;
30
import junit.framework.Test;
29
import junit.framework.Test;
31
import junit.framework.TestSuite;
30
import junit.framework.TestSuite;
32
31
Lines 39-44 Link Here
39
import org.eclipse.persistence.descriptors.invalidation.DailyCacheInvalidationPolicy;
38
import org.eclipse.persistence.descriptors.invalidation.DailyCacheInvalidationPolicy;
40
import org.eclipse.persistence.descriptors.invalidation.TimeToLiveCacheInvalidationPolicy;
39
import org.eclipse.persistence.descriptors.invalidation.TimeToLiveCacheInvalidationPolicy;
41
import org.eclipse.persistence.internal.sessions.AbstractSession;
40
import org.eclipse.persistence.internal.sessions.AbstractSession;
41
import org.eclipse.persistence.jpa.JpaCache;
42
import org.eclipse.persistence.jpa.JpaQuery;
42
import org.eclipse.persistence.jpa.JpaQuery;
43
import org.eclipse.persistence.queries.Cursor;
43
import org.eclipse.persistence.queries.Cursor;
44
import org.eclipse.persistence.queries.ReadQuery;
44
import org.eclipse.persistence.queries.ReadQuery;
Lines 49-54 Link Here
49
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
49
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
50
import org.eclipse.persistence.testing.framework.QuerySQLTracker;
50
import org.eclipse.persistence.testing.framework.QuerySQLTracker;
51
import org.eclipse.persistence.testing.models.jpa.advanced.Employee;
51
import org.eclipse.persistence.testing.models.jpa.advanced.Employee;
52
import org.eclipse.persistence.testing.models.jpa.advanced.Address;
52
import org.eclipse.persistence.testing.models.jpa.advanced.EmployeePopulator;
53
import org.eclipse.persistence.testing.models.jpa.advanced.EmployeePopulator;
53
import org.eclipse.persistence.testing.models.jpa.advanced.AdvancedTableCreator;
54
import org.eclipse.persistence.testing.models.jpa.advanced.AdvancedTableCreator;
54
55
Lines 745-751 Link Here
745
            if (!(readQuery.getQueryResultsCachePolicy().getCacheInvalidationPolicy() instanceof TimeToLiveCacheInvalidationPolicy)) {
746
            if (!(readQuery.getQueryResultsCachePolicy().getCacheInvalidationPolicy() instanceof TimeToLiveCacheInvalidationPolicy)) {
746
                fail("Query cache invalidation not set.");
747
                fail("Query cache invalidation not set.");
747
            }
748
            }
748
            if (((TimeToLiveCacheInvalidationPolicy)readQuery.getQueryResultsCachePolicy().getCacheInvalidationPolicy()).getTimeToLive() != 5000) {
749
            if (((TimeToLiveCacheInvalidationPolicy)readQuery.getQueryResultsCachePolicy().getCacheInvalidationPolicy()).getTimeToLive() != 50000) {
749
                fail("Query cache invalidation time not set.");
750
                fail("Query cache invalidation time not set.");
750
            }
751
            }
751
            
752
            
Lines 772-779 Link Here
772
            // Query by primary key.
773
            // Query by primary key.
773
            Query query = em.createNamedQuery("CachedAllEmployees");
774
            Query query = em.createNamedQuery("CachedAllEmployees");
774
            if (result.size() != query.getResultList().size()) {
775
            if (result.size() != query.getResultList().size()) {
776
                fail("List result size is not correct on 2nd cached query.");
777
            }
778
            if (counter.getSqlStatements().size() > 0) {
779
                fail("Query cache was not used: " + counter.getSqlStatements());
780
            }
781
            ((JpaCache)getEntityManagerFactory().getCache()).clearQueryCache();
782
            // Preload uow to test query cache in uow.
783
            em.createQuery("Select e from Employee e").getResultList();
784
            query.getResultList();
785
            if (result.size() != query.getResultList().size()) {
786
                fail("List result size is not correct on cached query in unit of work.");
787
            }
788
            ((JpaCache)getEntityManagerFactory().getCache()).clearQueryCache();
789
            // Also test query cache in early transaction.
790
            em.persist(new Address());
791
            em.flush();
792
            query.getResultList();
793
            if (result.size() != query.getResultList().size()) {
794
                fail("List result size is not correct on cached query in transaction.");
795
            }
796
            // Query by primary key.
797
            query = em.createNamedQuery("CachedNoEmployees");
798
            if (!query.getResultList().isEmpty()) {
775
                fail("List result size is not correct.");
799
                fail("List result size is not correct.");
776
            }
800
            }
801
            // Also test empty query cache.
802
            counter.remove();
803
            counter = new QuerySQLTracker(getServerSession());
804
            if (!query.getResultList().isEmpty()) {
805
                fail("List result size is not correct.");
806
            }
777
            if (counter.getSqlStatements().size() > 0) {
807
            if (counter.getSqlStatements().size() > 0) {
778
                fail("Query cache was not used: " + counter.getSqlStatements());
808
                fail("Query cache was not used: " + counter.getSqlStatements());
779
            }
809
            }
Lines 1310-1317 Link Here
1310
    }
1340
    }
1311
1341
1312
    public void testLockWithSecondaryTable() {
1342
    public void testLockWithSecondaryTable() {
1313
        ServerSession session = JUnitTestCase.getServerSession();
1314
1315
        // Cannot create parallel entity managers in the server.
1343
        // Cannot create parallel entity managers in the server.
1316
        if (! isOnServer() && isSelectForUpateSupported()) {
1344
        if (! isOnServer() && isSelectForUpateSupported()) {
1317
            EntityManager em = createEntityManager();
1345
            EntityManager em = createEntityManager();
Lines 1361-1368 Link Here
1361
    }
1389
    }
1362
1390
1363
    public void testVersionChangeWithReadLock() {
1391
    public void testVersionChangeWithReadLock() {
1364
        ServerSession session = JUnitTestCase.getServerSession();
1365
1366
        // It's a JPA2.0 feature.
1392
        // It's a JPA2.0 feature.
1367
        if (! isJPA10() && isSelectForUpateNoWaitSupported()){
1393
        if (! isJPA10() && isSelectForUpateNoWaitSupported()){
1368
            Employee employee = null;
1394
            Employee employee = null;
Lines 1440-1447 Link Here
1440
    }
1466
    }
1441
1467
1442
    public void testVersionChangeWithWriteLock() {
1468
    public void testVersionChangeWithWriteLock() {
1443
        ServerSession session = JUnitTestCase.getServerSession();
1444
1445
        // It's a JPA2.0 feature
1469
        // It's a JPA2.0 feature
1446
        if (! isJPA10() && isSelectForUpateNoWaitSupported()) {
1470
        if (! isJPA10() && isSelectForUpateNoWaitSupported()) {
1447
            Employee employee = null;
1471
            Employee employee = null;
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/CacheImpl.java (-11 / +201 lines)
Lines 12-20 Link Here
12
 ******************************************************************************/
12
 ******************************************************************************/
13
package org.eclipse.persistence.internal.jpa;
13
package org.eclipse.persistence.internal.jpa;
14
14
15
import javax.persistence.Cache;
16
import org.eclipse.persistence.descriptors.ClassDescriptor;
15
import org.eclipse.persistence.descriptors.ClassDescriptor;
17
import org.eclipse.persistence.internal.identitymaps.CacheKey;
16
import org.eclipse.persistence.internal.identitymaps.CacheKey;
17
import org.eclipse.persistence.jpa.JpaCache;
18
import org.eclipse.persistence.sessions.IdentityMapAccessor;
18
import org.eclipse.persistence.sessions.IdentityMapAccessor;
19
import org.eclipse.persistence.sessions.server.ServerSession;
19
import org.eclipse.persistence.sessions.server.ServerSession;
20
20
Lines 22-28 Link Here
22
 * Implements the JPA Cache interface using the EclipseLink cache API through IdentityMapAccessor.
22
 * Implements the JPA Cache interface using the EclipseLink cache API through IdentityMapAccessor.
23
 * @author DaraniY
23
 * @author DaraniY
24
 */
24
 */
25
public class CacheImpl implements Cache {
25
public class CacheImpl implements JpaCache {
26
26
27
    private IdentityMapAccessor accessor;
27
    private IdentityMapAccessor accessor;
28
    private EntityManagerFactoryImpl emf;
28
    private EntityManagerFactoryImpl emf;
Lines 34-67 Link Here
34
        this.serversession = emf.getServerSession();
34
        this.serversession = emf.getServerSession();
35
    }
35
    }
36
36
37
    public boolean contains(Class cls, Object primaryKey) {
37
    /**
38
     * Returns true if the cache contains an Object with the id and Class type, and is valid.
39
     */
40
    public boolean contains(Class cls, Object id) {
38
        this.emf.verifyOpen();
41
        this.emf.verifyOpen();
39
        Object pk =  createPrimaryKeyFromId(cls, primaryKey);
42
        Object pk =  createPrimaryKeyFromId(cls, id);
40
        ClassDescriptor descriptor = this.serversession.getDescriptor(cls);
43
        ClassDescriptor descriptor = this.serversession.getDescriptor(cls);
41
        CacheKey key = ((org.eclipse.persistence.internal.sessions.IdentityMapAccessor)this.accessor).getCacheKeyForObject(pk, cls, descriptor);
44
        CacheKey key = ((org.eclipse.persistence.internal.sessions.IdentityMapAccessor)this.accessor).getCacheKeyForObject(pk, cls, descriptor);
42
45
43
        return (key != null) && (key.getObject() != null) && (!descriptor.getCacheInvalidationPolicy().isInvalidated(key)); 
46
        return (key != null) && (key.getObject() != null) && (!descriptor.getCacheInvalidationPolicy().isInvalidated(key)); 
44
    }
47
    }
45
48
46
    public void evict(Class cls, Object primaryKey) {
49
    /**
50
     * Sets an Object with the id and Class type to be invalid in the cache.
51
     */
52
    public void evict(Class cls, Object id) {
47
        this.emf.verifyOpen();
53
        this.emf.verifyOpen();
48
        this.accessor.invalidateObject(createPrimaryKeyFromId(cls, primaryKey), cls);
54
        this.accessor.invalidateObject(createPrimaryKeyFromId(cls, id), cls);
49
    }
55
    }
50
56
57
    /**
58
     * Sets all instances of the class to be invalid.
59
     */
51
    public void evict(Class cls) {
60
    public void evict(Class cls) {
52
        this.emf.verifyOpen();
61
        this.emf.verifyOpen();
53
        this.accessor.invalidateClass(cls);
62
        this.accessor.invalidateClass(cls);
54
    }
63
    }
55
64
65
    /**
66
     * Sets all instances in the cache to be invalid.
67
     */
56
    public void evictAll() {
68
    public void evictAll() {
57
        this.emf.verifyOpen();
69
        this.emf.verifyOpen();
58
        this.accessor.invalidateAll();
70
        this.accessor.invalidateAll();
59
    }
71
    }
60
72
61
    private Object createPrimaryKeyFromId(Class cls, Object primaryKey){
73
    /**
62
        ClassDescriptor cdesc = this.serversession.getDescriptor(cls);
74
     * Return the EclipseLink cache key object from the JPA Id object.
63
        CMP3Policy cmp = (CMP3Policy) (cdesc.getCMPPolicy());
75
     */
64
        Object pk = cmp.createPrimaryKeyFromId(primaryKey, this.serversession);
76
    private Object createPrimaryKeyFromId(Class cls, Object id) {
65
        return pk;
77
        CMP3Policy policy = (CMP3Policy)this.serversession.getDescriptor(cls).getCMPPolicy();
78
        Object primaryKey = policy.createPrimaryKeyFromId(id, this.serversession);
79
        return primaryKey;
66
    }
80
    }
81
82
    /**
83
     * ADVANCED:
84
     * Resets the entire Object cache, and the Query cache.
85
     * <p> NOTE: Be careful using this method. This method blows away both this session's and its parent's caches.
86
     * This includes the server cache or any other cache. This throws away any Objects that have been read in.
87
     * Extreme caution should be used before doing this because Object identity will no longer
88
     * be maintained for any Objects currently read in.  This should only be called
89
     * if the application knows that it no longer has references to Objects held in the cache.
90
     */
91
    public void clear() {
92
        this.emf.verifyOpen();
93
        this.accessor.initializeAllIdentityMaps();
94
    }
95
96
    /**
97
     * ADVANCED:
98
     * Resets the cache for only the instances of the given Class type.
99
     * For inheritance the user must make sure that they only use the root class,
100
     * clearing a subclass cache is not allowed (as they share their parents cache).
101
     * <p> NOTE: Caution must be used in doing this to ensure that the Objects within the cache
102
     * are not referenced from other Objects of other classes or from the application.
103
     */
104
    public void clear(Class cls) {
105
        this.emf.verifyOpen();
106
        this.accessor.initializeIdentityMap(cls);
107
    }
108
109
    /**
110
     * Clear all the query caches.
111
     */
112
    public void clearQueryCache() {
113
        this.emf.verifyOpen();
114
        this.accessor.clearQueryCache();
115
    }
116
117
    /**
118
     * Clear the named query cache associated with the query name.
119
     */
120
    public void clearQueryCache(String queryName) {
121
        this.emf.verifyOpen();
122
        this.accessor.clearQueryCache(queryName);
123
    }
124
125
    /**
126
     * Returns the remaining life of the given Object (in milliseconds).  This method is associated with use of
127
     * cache invalidation feature and returns the difference between the next expiry
128
     * time of the Object and its read time.  The method will return 0 for invalidated Objects.
129
     */
130
    public long timeToLive(Object object) {
131
        this.emf.verifyOpen();
132
        return this.accessor.getRemainingValidTime(object);
133
    }
134
135
    /**
136
     * Returns true if the Object with the same id and Class type of the
137
     * the given Object is valid in the cache.
138
     */
139
    public boolean isValid(Object object) {
140
        this.emf.verifyOpen();
141
        return this.accessor.isValid(object);
142
    }
143
144
    /**
145
     * Returns true if the Object with the id and Class type is valid in the cache.
146
     */
147
    public boolean isValid(Class cls, Object id) {
148
        this.emf.verifyOpen();
149
        return this.accessor.isValid(createPrimaryKeyFromId(cls, id), cls);
150
    }
151
152
    /**
153
     * Used to print all the Objects in the cache.
154
     * The output of this method will be logged to this persistence unit's SessionLog at SEVERE level.
155
     */
156
    public void print() {
157
        this.emf.verifyOpen();
158
        this.accessor.printIdentityMaps();
159
    }
160
161
    /**
162
     * Used to print all the Objects in the cache of the Class type.
163
     * The output of this method will be logged to this persistence unit's SessionLog at SEVERE level.
164
     */
165
    public void print(Class cls) {
166
        this.emf.verifyOpen();
167
        this.accessor.printIdentityMap(cls);
168
    }
169
170
    /**
171
     * Used to print all the currently locked cache keys in the cache.
172
     * The output of this method will be logged to this persistence unit's SessionLog at SEVERE level.
173
     */
174
    public void printLocks() {
175
        this.emf.verifyOpen();
176
        this.accessor.printIdentityMapLocks();
177
    }
178
179
    /**
180
     * This can be used to help debugging an Object identity problem.
181
     * An Object identity problem is when an Object in the cache references an 
182
     * Object that is not in the cache. This method will validate that all cached 
183
     * Objects are in a correct state.
184
     */
185
    public void validate() {
186
        this.emf.verifyOpen();
187
        this.accessor.validateCache();
188
    }
189
190
    /**
191
     * Returns the Object from the cache map with the id 
192
     * and Class type.
193
     */
194
    public Object getObject(Class cls, Object id) {
195
        this.emf.verifyOpen();
196
        return this.accessor.getFromIdentityMap(createPrimaryKeyFromId(cls, id), cls);
197
    }
198
199
    /**
200
     * ADVANCED:
201
     * Puts the given Object into the cache.
202
     * This is a very advanced method, and caution should be used in adding objects to the cache
203
     * as other objects may have relationships to previous object, or this object may have
204
     * relationships to other objects.
205
     */
206
    public Object putObject(Object object) {
207
        this.emf.verifyOpen();
208
        return this.accessor.putInIdentityMap(object);
209
    }
210
211
    /**
212
     * ADVANCED:
213
     * Removes the Object from the cache.
214
     * <p> NOTE: Caution should be used when calling to avoid violating Object identity.
215
     * The application should only call this if its known that no references to the Object exist.
216
     */
217
    public Object removeObject(Object object) {
218
        this.emf.verifyOpen();
219
        return this.accessor.removeFromIdentityMap(object);
220
    }
221
222
    /**
223
     * ADVANCED:
224
     * Removes the Object with the id and Class type from the cache.
225
     * <p> NOTE: Caution should be used when calling to avoid violating Object identity.
226
     * The application should only call this if its known that no references to the Object exist.
227
     */
228
    public Object removeObject(Class cls, Object id) {
229
        this.emf.verifyOpen();
230
        return this.accessor.removeFromIdentityMap(createPrimaryKeyFromId(cls, id), cls);
231
    }
232
233
    /**
234
     * Returns true if the cache contains an Object with the same id and Class type of the given object.
235
     */
236
    public boolean contains(Object object) {
237
        return contains(object.getClass(), getId(object));
238
    }
239
240
    /**
241
     * Sets the object to be invalid in the cache.
242
     */
243
    public void evict(Object object) {
244
        this.emf.verifyOpen();
245
        this.accessor.invalidateObject(object);
246
    }
247
248
    /**
249
     * Returns the object's Id.
250
     */
251
    public Object getId(Object object) {
252
        this.emf.verifyOpen();
253
        ClassDescriptor cdesc = this.serversession.getDescriptor(object.getClass());
254
        CMP3Policy policy = (CMP3Policy) (cdesc.getCMPPolicy());
255
        return policy.createPrimaryKeyInstance(object, this.serversession);
256
    }
67
}
257
}
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/EntityManagerFactoryImpl.java (-434 / +449 lines)
Lines 52-637 Link Here
52
 * 
52
 * 
53
 * @author gyorke
53
 * @author gyorke
54
 * @since TopLink Essentials - JPA 1.0
54
 * @since TopLink Essentials - JPA 1.0
55
 *  
55
 * 
56
 *     03/19/2009-2.0 Michael O'Brien  
56
 *        03/19/2009-2.0 Michael O'Brien - 266912: JPA 2.0 Metamodel API (part
57
 *       - 266912: JPA 2.0 Metamodel API (part of the JSR-317 EJB 3.1 Criteria API)  
57
 *        of the JSR-317 EJB 3.1 Criteria API)
58
 */ 
58
 */
59
public class EntityManagerFactoryImpl implements EntityManagerFactory, PersistenceUnitUtil {
59
public class EntityManagerFactoryImpl implements EntityManagerFactory, PersistenceUnitUtil {
60
	/** Reference to Cache Interface. */
60
    /** Reference to Cache Interface. */
61
	protected Cache myCache;
61
    protected Cache myCache;
62
	/** Reference to the ServerSession for this deployment. */
62
    /** Reference to the ServerSession for this deployment. */
63
	protected volatile ServerSession serverSession;
63
    protected volatile ServerSession serverSession;
64
	/** EntityManagerSetupImpl that deployed this factory. */
64
    /** EntityManagerSetupImpl that deployed this factory. */
65
	protected EntityManagerSetupImpl setupImpl;
65
    protected EntityManagerSetupImpl setupImpl;
66
	/** Stores if closed has been called. */
66
    /** Stores if closed has been called. */
67
	protected boolean isOpen = true;
67
    protected boolean isOpen = true;
68
	/** Persistence unit properties from create factory. */
68
    /** Persistence unit properties from create factory. */
69
	protected Map properties;
69
    protected Map properties;
70
70
71
    /** 
71
    /**
72
     * INTERNAL: 
72
     * INTERNAL: The following properties passed to createEMF cached and
73
     * The following properties passed to createEMF cached and processed on the emf directly. 
73
     * processed on the emf directly. None of these properties processed during
74
     * None of these properties processed during predeploy or deploy. 
74
     * predeploy or deploy.
75
     **/
75
     **/
76
	protected static final Set<String> supportedNonServerSessionProperties = PersistenceUnitProperties.getSupportedNonServerSessionProperties();
76
    protected static final Set<String> supportedNonServerSessionProperties = PersistenceUnitProperties.getSupportedNonServerSessionProperties();
77
    
78
	/**
79
	 * Default join existing transaction property, allows reading through write
80
	 * connection.
81
	 */
82
	protected boolean beginEarlyTransaction;
83
77
84
	/** Default property, allows flush before query to be avoided. */
78
    /**
85
	protected FlushModeType flushMode = FlushModeType.AUTO;
79
     * Default join existing transaction property, allows reading through write
80
     * connection.
81
     */
82
    protected boolean beginEarlyTransaction;
86
83
87
	/** Default property, allows weak unit of work references. */
84
    /** Default property, allows flush before query to be avoided. */
88
	protected ReferenceMode referenceMode = ReferenceMode.HARD;
85
    protected FlushModeType flushMode = FlushModeType.AUTO;
89
86
90
	/**
87
    /** Default property, allows weak unit of work references. */
91
	 * Default property to avoid resuming unit of work if going to be closed on
88
    protected ReferenceMode referenceMode = ReferenceMode.HARD;
92
	 * commit anyway.
93
	 */
94
	protected boolean closeOnCommit;
95
89
96
	/**
90
    /**
97
	 * Default property to avoid discover new objects in unit of work if
91
     * Default property to avoid resuming unit of work if going to be closed on
98
	 * application always uses persist.
92
     * commit anyway.
99
	 */
93
     */
100
	protected boolean persistOnCommit = true;
94
    protected boolean closeOnCommit;
101
95
102
	/**
96
    /**
103
	 * Default FlashClearCache mode to be used. Relevant only in case call to
97
     * Default property to avoid discover new objects in unit of work if
104
	 * flush method followed by call to clear method.
98
     * application always uses persist.
105
	 * 
99
     */
106
	 * @see org.eclipse.persistence.config.FlushClearCache
100
    protected boolean persistOnCommit = true;
107
	 */
108
	protected String flushClearCache = FlushClearCache.DEFAULT;
109
101
110
	/** Default to determine if does-exist should be performed on persist. */
102
    /**
111
	protected boolean shouldValidateExistence;
103
     * Default FlashClearCache mode to be used. Relevant only in case call to
112
	protected boolean commitWithoutPersistRules;
104
     * flush method followed by call to clear method.
105
     * 
106
     * @see org.eclipse.persistence.config.FlushClearCache
107
     */
108
    protected String flushClearCache = FlushClearCache.DEFAULT;
113
109
114
	/**
110
    /** Default to determine if does-exist should be performed on persist. */
115
	 * Will return an instance of the Factory. Should only be called by
111
    protected boolean shouldValidateExistence;
116
	 * EclipseLink.
112
    protected boolean commitWithoutPersistRules;
117
	 * 
118
	 * @param serverSession
119
	 */
120
	public EntityManagerFactoryImpl(ServerSession serverSession) {
121
		this.serverSession = serverSession;
122
		processProperties(serverSession.getProperties());
123
	}
124
113
125
	public EntityManagerFactoryImpl(EntityManagerSetupImpl setupImpl, Map properties) {
114
    /**
126
		this.setupImpl = setupImpl;
115
     * Will return an instance of the Factory. Should only be called by
127
		this.properties = properties;
116
     * EclipseLink.
128
	}
117
     * 
118
     * @param serverSession
119
     */
120
    public EntityManagerFactoryImpl(ServerSession serverSession) {
121
        this.serverSession = serverSession;
122
        processProperties(serverSession.getProperties());
123
    }
129
124
130
	/**
125
    public EntityManagerFactoryImpl(EntityManagerSetupImpl setupImpl, Map properties) {
131
	 * INTERNAL: Returns the ServerSession that the Factory will be using and
126
        this.setupImpl = setupImpl;
132
	 * initializes it if it is not available. This method makes use of the
127
        this.properties = properties;
133
	 * partially constructed session stored in our setupImpl and completes its
128
    }
134
	 * construction
135
	 */
136
	public ServerSession getServerSession() {
137
		if (this.serverSession == null) {
138
			// PERF: Avoid synchronization.
139
			synchronized (this) {
140
				// DCL ok as isLoggedIn is volatile boolean, set after login is
141
				// complete.
142
				if (this.serverSession == null) {
143
					ClassLoader realLoader = setupImpl.getPersistenceUnitInfo().getClassLoader();
144
					// splitProperties[0] contains supportedNonServerSessionProperties; [1] - all the rest.
145
					Map[] splitProperties = EntityManagerFactoryProvider.splitSpecifiedProperties(properties, supportedNonServerSessionProperties);
146
					// keep only non server session properties - the rest will be either cached in the server session or ignored
147
					properties = splitProperties[0];
148
					Map serverSessionProperties = splitProperties[1];
149
					// the call top setupImpl.deploy() finishes the session
150
					// creation
151
					ServerSession tempServerSession = setupImpl.deploy(realLoader, serverSessionProperties);
152
					// discard all but non server session properties from server session properties.
153
					Map tempProperties = EntityManagerFactoryProvider.keepSpecifiedProperties(tempServerSession.getProperties(), supportedNonServerSessionProperties);
154
					// properties override server session properties 
155
					Map propertiesToProcess = EntityManagerFactoryProvider.mergeMaps(properties, tempProperties);
156
					processProperties(propertiesToProcess);
157
					this.serverSession = tempServerSession;
158
				}
159
			}
160
		}
161
		return this.serverSession;
162
	}
163
129
164
	/**
130
    /**
165
	 * Closes this factory, releasing any resources that might be held by this
131
     * INTERNAL: Returns the ServerSession that the Factory will be using and
166
	 * factory. After invoking this method, all methods on the instance will
132
     * initializes it if it is not available. This method makes use of the
167
	 * throw an {@link IllegalStateException}, except for {@link #isOpen}, which
133
     * partially constructed session stored in our setupImpl and completes its
168
	 * will return <code>false</code>.
134
     * construction
169
	 */
135
     */
170
	public synchronized void close() {
136
    public ServerSession getServerSession() {
171
		verifyOpen();
137
        if (this.serverSession == null) {
172
		isOpen = false;
138
            // PERF: Avoid synchronization.
173
        // Do not invalidate the metaModel field 
139
            synchronized (this) {
140
                // DCL ok as isLoggedIn is volatile boolean, set after login is
141
                // complete.
142
                if (this.serverSession == null) {
143
                    ClassLoader realLoader = setupImpl.getPersistenceUnitInfo().getClassLoader();
144
                    // splitProperties[0] contains
145
                    // supportedNonServerSessionProperties; [1] - all the rest.
146
                    Map[] splitProperties = EntityManagerFactoryProvider.splitSpecifiedProperties(properties, supportedNonServerSessionProperties);
147
                    // keep only non server session properties - the rest will
148
                    // be either cached in the server session or ignored
149
                    properties = splitProperties[0];
150
                    Map serverSessionProperties = splitProperties[1];
151
                    // the call top setupImpl.deploy() finishes the session
152
                    // creation
153
                    ServerSession tempServerSession = setupImpl.deploy(realLoader, serverSessionProperties);
154
                    // discard all but non server session properties from server
155
                    // session properties.
156
                    Map tempProperties = EntityManagerFactoryProvider.keepSpecifiedProperties(tempServerSession.getProperties(), supportedNonServerSessionProperties);
157
                    // properties override server session properties
158
                    Map propertiesToProcess = EntityManagerFactoryProvider.mergeMaps(properties, tempProperties);
159
                    processProperties(propertiesToProcess);
160
                    this.serverSession = tempServerSession;
161
                }
162
            }
163
        }
164
        return this.serverSession;
165
    }
166
167
    /**
168
     * Closes this factory, releasing any resources that might be held by this
169
     * factory. After invoking this method, all methods on the instance will
170
     * throw an {@link IllegalStateException}, except for {@link #isOpen}, which
171
     * will return <code>false</code>.
172
     */
173
    public synchronized void close() {
174
        verifyOpen();
175
        isOpen = false;
176
        // Do not invalidate the metaModel field
174
        // (a reopened emf will re-populate the same metaModel)
177
        // (a reopened emf will re-populate the same metaModel)
175
        // (a new persistence unit will generate a new metaModel)
178
        // (a new persistence unit will generate a new metaModel)
176
		if (setupImpl != null) {
179
        if (setupImpl != null) {
177
			// 260511 null check so that closing a EM
180
            // 260511 null check so that closing a EM
178
			// created from the constructor no longer throws a NPE
181
            // created from the constructor no longer throws a NPE
179
			setupImpl.undeploy();
182
            setupImpl.undeploy();
180
		}
183
        }
181
	}
184
    }
182
185
183
	/**
186
    /**
184
	 * Indicates whether or not this factory is open. Returns <code>true</code>
187
     * Indicates whether or not this factory is open. Returns <code>true</code>
185
	 * until a call to {@link #close} is made.
188
     * until a call to {@link #close} is made.
186
	 */
189
     */
187
	public boolean isOpen() {
190
    public boolean isOpen() {
188
		return isOpen;
191
        return isOpen;
189
	}
192
    }
190
193
191
	/**
194
    /**
192
	 * PUBLIC: Returns an EntityManager for this deployment.
195
     * PUBLIC: Returns an EntityManager for this deployment.
193
	 */
196
     */
194
	public EntityManager createEntityManager() {
197
    public EntityManager createEntityManager() {
195
		return createEntityManagerImpl(null);
198
        return createEntityManagerImpl(null);
196
	}
199
    }
197
200
198
	/**
201
    /**
199
	 * PUBLIC: Returns an EntityManager for this deployment.
202
     * PUBLIC: Returns an EntityManager for this deployment.
200
	 */
203
     */
201
	public EntityManager createEntityManager(Map properties) {
204
    public EntityManager createEntityManager(Map properties) {
202
		return createEntityManagerImpl(properties);
205
        return createEntityManagerImpl(properties);
203
	}
206
    }
204
207
205
	protected EntityManagerImpl createEntityManagerImpl(Map properties) {
208
    protected EntityManagerImpl createEntityManagerImpl(Map properties) {
206
		verifyOpen();
209
        verifyOpen();
207
		ServerSession session = getServerSession();
210
        ServerSession session = getServerSession();
208
		if (!session.isLoggedIn()) {
211
        if (!session.isLoggedIn()) {
209
			// PERF: Avoid synchronization.
212
            // PERF: Avoid synchronization.
210
			synchronized (session) {
213
            synchronized (session) {
211
				// DCL ok as isLoggedIn is volatile boolean, set after login is
214
                // DCL ok as isLoggedIn is volatile boolean, set after login is
212
				// complete.
215
                // complete.
213
				if (!session.isLoggedIn()) {
216
                if (!session.isLoggedIn()) {
214
					session.login();
217
                    session.login();
215
				}
218
                }
216
			}
219
            }
217
		}
220
        }
218
		return new EntityManagerImpl(this, properties);
221
        return new EntityManagerImpl(this, properties);
219
	}
222
    }
220
223
221
	protected void verifyOpen() {
224
    protected void verifyOpen() {
222
		if (!this.isOpen) {
225
        if (!this.isOpen) {
223
			throw new IllegalStateException(ExceptionLocalization.buildMessage("operation_on_closed_entity_manager_factory"));
226
            throw new IllegalStateException(ExceptionLocalization.buildMessage("operation_on_closed_entity_manager_factory"));
224
		}
227
        }
225
	}
228
    }
226
229
227
	protected void finalize() throws Throwable {
230
    protected void finalize() throws Throwable {
228
		if (isOpen()) {
231
        if (isOpen()) {
229
			close();
232
            close();
230
		}
233
        }
231
	}
234
    }
232
235
233
	/**
236
    /**
234
	 * The method return user defined property passed in from
237
     * The method return user defined property passed in from
235
	 * EntityManagerFactory.
238
     * EntityManagerFactory.
236
	 */
239
     */
237
	public Object getProperty(String name) {
240
    public Object getProperty(String name) {
238
		if (name == null) {
241
        if (name == null) {
239
			return null;
242
            return null;
240
		}
243
        }
241
		if(properties != null) {
244
        if (properties != null) {
242
		    Object value = properties.get(name);
245
            Object value = properties.get(name);
243
		    if(value != null) {
246
            if (value != null) {
244
		        return value;
247
                return value;
245
		    }
248
            }
246
		}
249
        }
247
		return getServerSession().getProperty(name);
250
        return getServerSession().getProperty(name);
248
	}
251
    }
249
252
250
	/**
253
    /**
251
	 * Process all EntityManager properties. This allows all EntityManager
254
     * Process all EntityManager properties. This allows all EntityManager
252
	 * properties specified in the persistence.xml, factory properties, or
255
     * properties specified in the persistence.xml, factory properties, or
253
	 * System properties to be preprocessed. This save the cost of processing
256
     * System properties to be preprocessed. This save the cost of processing
254
	 * these properties each time an EntityManager is created, which can add
257
     * these properties each time an EntityManager is created, which can add
255
	 * considerable overhead to both performance and concurrency as System
258
     * considerable overhead to both performance and concurrency as System
256
	 * properties are a Hashtable and synchronized.
259
     * properties are a Hashtable and synchronized. ATTENTION: If you add a new
257
	 * ATTENTION: 
260
     * property to be processed in this method please also add the property's
258
	 * If you add a new property to be processed in this method please also add
261
     * name to PersistenceUnitProperties.supportedNonServerSessionProperties
259
	 * the property's name to PersistenceUnitProperties.supportedNonServerSessionProperties
262
     */
260
	 */
263
    protected void processProperties(Map properties) {
261
	protected void processProperties(Map properties) {
264
        String beginEarlyTransactionProperty = PropertiesHandler.getPropertyValueLogDebug(EntityManagerProperties.JOIN_EXISTING_TRANSACTION, properties, this.serverSession, true);
262
		String beginEarlyTransactionProperty = PropertiesHandler.getPropertyValueLogDebug(EntityManagerProperties.JOIN_EXISTING_TRANSACTION, properties, this.serverSession, true);
265
        if (beginEarlyTransactionProperty != null) {
263
		if (beginEarlyTransactionProperty != null) {
266
            this.beginEarlyTransaction = "true".equalsIgnoreCase(beginEarlyTransactionProperty);
264
			this.beginEarlyTransaction = "true".equalsIgnoreCase(beginEarlyTransactionProperty);
267
        }
265
		}
268
        String referenceMode = PropertiesHandler.getPropertyValueLogDebug(EntityManagerProperties.PERSISTENCE_CONTEXT_REFERENCE_MODE, properties, this.serverSession, true);
266
		String referenceMode = PropertiesHandler.getPropertyValueLogDebug(EntityManagerProperties.PERSISTENCE_CONTEXT_REFERENCE_MODE, properties, this.serverSession, true);
269
        if (referenceMode != null) {
267
		if (referenceMode != null) {
270
            this.referenceMode = ReferenceMode.valueOf(referenceMode);
268
			this.referenceMode = ReferenceMode.valueOf(referenceMode);
271
        }
269
		}
272
        String flushMode = PropertiesHandler.getPropertyValueLogDebug(EntityManagerProperties.PERSISTENCE_CONTEXT_FLUSH_MODE, properties, this.serverSession, true);
270
		String flushMode = PropertiesHandler.getPropertyValueLogDebug(EntityManagerProperties.PERSISTENCE_CONTEXT_FLUSH_MODE, properties, this.serverSession, true);
273
        if (flushMode != null) {
271
		if (flushMode != null) {
274
            this.flushMode = FlushModeType.valueOf(flushMode);
272
			this.flushMode = FlushModeType.valueOf(flushMode);
275
        }
273
		}
276
        String closeOnCommit = PropertiesHandler.getPropertyValueLogDebug(EntityManagerProperties.PERSISTENCE_CONTEXT_CLOSE_ON_COMMIT, properties, this.serverSession, true);
274
		String closeOnCommit = PropertiesHandler.getPropertyValueLogDebug(EntityManagerProperties.PERSISTENCE_CONTEXT_CLOSE_ON_COMMIT, properties, this.serverSession, true);
277
        if (closeOnCommit != null) {
275
		if (closeOnCommit != null) {
278
            this.closeOnCommit = "true".equalsIgnoreCase(closeOnCommit);
276
			this.closeOnCommit = "true".equalsIgnoreCase(closeOnCommit);
279
        }
277
		}
280
        String persistOnCommit = PropertiesHandler.getPropertyValueLogDebug(EntityManagerProperties.PERSISTENCE_CONTEXT_PERSIST_ON_COMMIT, properties, this.serverSession, true);
278
		String persistOnCommit = PropertiesHandler.getPropertyValueLogDebug(EntityManagerProperties.PERSISTENCE_CONTEXT_PERSIST_ON_COMMIT, properties, this.serverSession, true);
281
        if (persistOnCommit != null) {
279
		if (persistOnCommit != null) {
282
            this.persistOnCommit = "true".equalsIgnoreCase(persistOnCommit);
280
			this.persistOnCommit = "true".equalsIgnoreCase(persistOnCommit);
283
        }
281
		}
282
        String commitWithoutPersist = PropertiesHandler.getPropertyValueLogDebug(EntityManagerProperties.PERSISTENCE_CONTEXT_COMMIT_WITHOUT_PERSIST_RULES, properties, this.serverSession, true);
284
        String commitWithoutPersist = PropertiesHandler.getPropertyValueLogDebug(EntityManagerProperties.PERSISTENCE_CONTEXT_COMMIT_WITHOUT_PERSIST_RULES, properties, this.serverSession, true);
283
        if (commitWithoutPersist != null) {
285
        if (commitWithoutPersist != null) {
284
            this.commitWithoutPersistRules = "true".equalsIgnoreCase(commitWithoutPersist);
286
            this.commitWithoutPersistRules = "true".equalsIgnoreCase(commitWithoutPersist);
285
        }
287
        }
286
		String shouldValidateExistence = PropertiesHandler.getPropertyValueLogDebug(EntityManagerProperties.VALIDATE_EXISTENCE, properties, this.serverSession, true);
288
        String shouldValidateExistence = PropertiesHandler.getPropertyValueLogDebug(EntityManagerProperties.VALIDATE_EXISTENCE, properties, this.serverSession, true);
287
		if (shouldValidateExistence != null) {
289
        if (shouldValidateExistence != null) {
288
			this.shouldValidateExistence = "true".equalsIgnoreCase(shouldValidateExistence);
290
            this.shouldValidateExistence = "true".equalsIgnoreCase(shouldValidateExistence);
289
		}
291
        }
290
		String flushClearCache = PropertiesHandler.getPropertyValueLogDebug(EntityManagerProperties.FLUSH_CLEAR_CACHE, properties, this.serverSession, true);
292
        String flushClearCache = PropertiesHandler.getPropertyValueLogDebug(EntityManagerProperties.FLUSH_CLEAR_CACHE, properties, this.serverSession, true);
291
		if (flushClearCache != null) {
293
        if (flushClearCache != null) {
292
			this.flushClearCache = flushClearCache;
294
            this.flushClearCache = flushClearCache;
293
		}
295
        }
294
	}
296
    }
295
297
296
	/**
298
    /**
297
	 * Return default join existing transaction property, allows reading through
299
     * Return default join existing transaction property, allows reading through
298
	 * write connection.
300
     * write connection.
299
	 */
301
     */
300
	public boolean getBeginEarlyTransaction() {
302
    public boolean getBeginEarlyTransaction() {
301
		return beginEarlyTransaction;
303
        return beginEarlyTransaction;
302
	}
304
    }
303
305
304
	/**
306
    /**
305
	 * Set default join existing transaction property, allows reading through
307
     * Set default join existing transaction property, allows reading through
306
	 * write connection.
308
     * write connection.
307
	 */
309
     */
308
	public void setBeginEarlyTransaction(boolean beginEarlyTransaction) {
310
    public void setBeginEarlyTransaction(boolean beginEarlyTransaction) {
309
		this.beginEarlyTransaction = beginEarlyTransaction;
311
        this.beginEarlyTransaction = beginEarlyTransaction;
310
	}
312
    }
311
313
312
	/**
314
    /**
313
	 * Return default property, allows flush before query to be avoided.
315
     * Return default property, allows flush before query to be avoided.
314
	 */
316
     */
315
	public FlushModeType getFlushMode() {
317
    public FlushModeType getFlushMode() {
316
		return flushMode;
318
        return flushMode;
317
	}
319
    }
318
320
319
	/**
321
    /**
320
	 * Set default property, allows flush before query to be avoided.
322
     * Set default property, allows flush before query to be avoided.
321
	 */
323
     */
322
	public void setFlushMode(FlushModeType flushMode) {
324
    public void setFlushMode(FlushModeType flushMode) {
323
		this.flushMode = flushMode;
325
        this.flushMode = flushMode;
324
	}
326
    }
325
327
326
	/**
328
    /**
327
	 * Return default property, allows weak unit of work references.
329
     * Return default property, allows weak unit of work references.
328
	 */
330
     */
329
	public ReferenceMode getReferenceMode() {
331
    public ReferenceMode getReferenceMode() {
330
		return referenceMode;
332
        return referenceMode;
331
	}
333
    }
332
334
333
	/**
335
    /**
334
	 * Set default property, allows weak unit of work references.
336
     * Set default property, allows weak unit of work references.
335
	 */
337
     */
336
	public void setReferenceMode(ReferenceMode referenceMode) {
338
    public void setReferenceMode(ReferenceMode referenceMode) {
337
		this.referenceMode = referenceMode;
339
        this.referenceMode = referenceMode;
338
	}
340
    }
339
341
340
	/**
342
    /**
341
	 * Return default property to avoid resuming unit of work if going to be
343
     * Return default property to avoid resuming unit of work if going to be
342
	 * closed on commit anyway.
344
     * closed on commit anyway.
343
	 */
345
     */
344
	public boolean getCloseOnCommit() {
346
    public boolean getCloseOnCommit() {
345
		return closeOnCommit;
347
        return closeOnCommit;
346
	}
348
    }
347
349
348
	/**
350
    /**
349
	 * Set default property to avoid resuming unit of work if going to be closed
351
     * Set default property to avoid resuming unit of work if going to be closed
350
	 * on commit anyway.
352
     * on commit anyway.
351
	 */
353
     */
352
	public void setCloseOnCommit(boolean closeOnCommit) {
354
    public void setCloseOnCommit(boolean closeOnCommit) {
353
		this.closeOnCommit = closeOnCommit;
355
        this.closeOnCommit = closeOnCommit;
354
	}
356
    }
355
357
356
	/**
358
    /**
357
	 * Return default property to avoid discover new objects in unit of work if
359
     * Return default property to avoid discover new objects in unit of work if
358
	 * application always uses persist.
360
     * application always uses persist.
359
	 */
361
     */
360
	public boolean getPersistOnCommit() {
362
    public boolean getPersistOnCommit() {
361
		return persistOnCommit;
363
        return persistOnCommit;
362
	}
364
    }
363
365
364
    /**
366
    /**
365
     * Return interface providing access to utility methods
367
     * Return interface providing access to utility methods for the persistence
366
     * for the persistence unit.
368
     * unit.
369
     * 
367
     * @return PersistenceUnitUtil interface
370
     * @return PersistenceUnitUtil interface
368
     * @throws IllegalStateException if the entity manager factory
371
     * @throws IllegalStateException
369
     * has been closed.
372
     *             if the entity manager factory has been closed.
370
     */
373
     */
371
    public PersistenceUnitUtil getPersistenceUnitUtil(){
374
    public PersistenceUnitUtil getPersistenceUnitUtil() {
372
        return this;
375
        return this;
373
    }
376
    }
374
377
375
    /**
378
    /**
376
	 * Set default property to avoid discover new objects in unit of work if
379
     * Set default property to avoid discover new objects in unit of work if
377
	 * application always uses persist.
380
     * application always uses persist.
378
	 */
381
     */
379
	public void setPersistOnCommit(boolean persistOnCommit) {
382
    public void setPersistOnCommit(boolean persistOnCommit) {
380
		this.persistOnCommit = persistOnCommit;
383
        this.persistOnCommit = persistOnCommit;
381
	}
384
    }
382
385
383
    /**
386
    /**
384
     * Return default property to avoid discover new objects in unit of work if application always uses persist.
387
     * Return default property to avoid discover new objects in unit of work if
388
     * application always uses persist.
385
     */
389
     */
386
    public boolean getCommitWithoutPersistRules() {
390
    public boolean getCommitWithoutPersistRules() {
387
        return commitWithoutPersistRules;
391
        return commitWithoutPersistRules;
388
    }
392
    }
389
    
393
390
    /**
394
    /**
391
     * Set default property to avoid discover new objects in unit of work if application always uses persist.
395
     * Set default property to avoid discover new objects in unit of work if
396
     * application always uses persist.
392
     */
397
     */
393
    public void setCommitWithoutPersistRules(boolean commitWithoutPersistRules) {
398
    public void setCommitWithoutPersistRules(boolean commitWithoutPersistRules) {
394
        this.commitWithoutPersistRules = commitWithoutPersistRules;
399
        this.commitWithoutPersistRules = commitWithoutPersistRules;
395
    }
400
    }
401
396
    /**
402
    /**
397
     * Return the default FlashClearCache mode to be used.
403
     * Return the default FlashClearCache mode to be used. Relevant only in case
398
     * Relevant only in case call to flush method followed by call to clear method.
404
     * call to flush method followed by call to clear method.
399
	 * @see org.eclipse.persistence.config.FlushClearCache
405
     * 
400
	 */
406
     * @see org.eclipse.persistence.config.FlushClearCache
401
	public String getFlushClearCache() {
407
     */
402
		return flushClearCache;
408
    public String getFlushClearCache() {
403
	}
409
        return flushClearCache;
410
    }
404
411
405
	/**
412
    /**
406
	 * Set the default FlashClearCache mode to be used. Relevant only in case
413
     * Set the default FlashClearCache mode to be used. Relevant only in case
407
	 * call to flush method followed by call to clear method.
414
     * call to flush method followed by call to clear method.
408
	 * 
415
     * 
409
	 * @see org.eclipse.persistence.config.FlushClearCache
416
     * @see org.eclipse.persistence.config.FlushClearCache
410
	 */
417
     */
411
	public void setFlushClearCache(String flushClearCache) {
418
    public void setFlushClearCache(String flushClearCache) {
412
		this.flushClearCache = flushClearCache;
419
        this.flushClearCache = flushClearCache;
413
	}
420
    }
414
421
415
	/**
422
    /**
416
	 * Return the default to determine if does-exist should be performed on
423
     * Return the default to determine if does-exist should be performed on
417
	 * persist.
424
     * persist.
418
	 */
425
     */
419
	public boolean shouldValidateExistence() {
426
    public boolean shouldValidateExistence() {
420
		return shouldValidateExistence;
427
        return shouldValidateExistence;
421
	}
428
    }
422
429
423
	/**
430
    /**
424
	 * Set the default to determine if does-exist should be performed on
431
     * Set the default to determine if does-exist should be performed on
425
	 * persist.
432
     * persist.
426
	 */
433
     */
427
	public void setShouldValidateExistence(boolean shouldValidateExistence) {
434
    public void setShouldValidateExistence(boolean shouldValidateExistence) {
428
		this.shouldValidateExistence = shouldValidateExistence;
435
        this.shouldValidateExistence = shouldValidateExistence;
429
	}
436
    }
430
437
431
	public Cache getCache() {
438
    public Cache getCache() {
432
		verifyOpen();
439
        verifyOpen();
433
		if (myCache == null) {
440
        if (myCache == null) {
434
			ServerSession session = this.getServerSession();
441
            ServerSession session = this.getServerSession();
435
			myCache = new CacheImpl(this, session.getIdentityMapAccessor());
442
            myCache = new CacheImpl(this, session.getIdentityMapAccessor());
436
		}
443
        }
437
		return myCache;
444
        return myCache;
438
	}
445
    }
439
446
440
	/**
447
    /**
441
	 * @see javax.persistence.EntityManagerFactory#getProperties()
448
     * @see javax.persistence.EntityManagerFactory#getProperties()
442
	 * @since Java Persistence API 2.0
449
     * @since Java Persistence API 2.0
443
	 */
450
     */
444
	public Map<String, Object> getProperties() {
451
    public Map<String, Object> getProperties() {
445
	    if(!this.isOpen()) {
452
        if (!this.isOpen()) {
446
	        throw new IllegalStateException(ExceptionLocalization.buildMessage("operation_on_closed_entity_manager_factory"));
453
            throw new IllegalStateException(ExceptionLocalization.buildMessage("operation_on_closed_entity_manager_factory"));
447
	    }
454
        }
448
	    return Collections.unmodifiableMap(EntityManagerFactoryProvider.mergeMaps(properties, this.getServerSession().getProperties()));
455
        return Collections.unmodifiableMap(EntityManagerFactoryProvider.mergeMaps(properties, this.getServerSession().getProperties()));
449
	}
456
    }
450
457
451
	/**
458
    /**
452
	 * @see javax.persistence.EntityManagerFactory#getCriteriaBuilder()
459
     * @see javax.persistence.EntityManagerFactory#getCriteriaBuilder()
453
	 * @since Java Persistence 2.0
460
     * @since Java Persistence 2.0
454
	 */
461
     */
455
	public CriteriaBuilder getCriteriaBuilder() {
462
    public CriteriaBuilder getCriteriaBuilder() {
456
        return new CriteriaBuilderImpl(this.getMetamodel());
463
        return new CriteriaBuilderImpl(this.getMetamodel());
457
	}
464
    }
458
465
459
    /**
466
    /**
460
     * Return an instance of Metamodel interface for access to the
467
     * Return an instance of Metamodel interface for access to the metamodel of
461
     * metamodel of the persistence unit.
468
     * the persistence unit.
469
     * 
462
     * @return Metamodel instance
470
     * @return Metamodel instance
463
     * @throws IllegalStateException if the entity manager factory has
471
     * @throws IllegalStateException
464
     * been closed.
472
     *             if the entity manager factory has been closed.
465
     * @see javax.persistence.EntityManagerFactory#getMetamodel()
473
     * @see javax.persistence.EntityManagerFactory#getMetamodel()
466
     * @since Java Persistence 2.0
474
     * @since Java Persistence 2.0
467
     */
475
     */
468
    public Metamodel getMetamodel() {
476
    public Metamodel getMetamodel() {
469
        if(!this.isOpen()) {
477
        if (!this.isOpen()) {
470
            throw new IllegalStateException(ExceptionLocalization.buildMessage("operation_on_closed_entity_manager_factory"));
478
            throw new IllegalStateException(ExceptionLocalization.buildMessage("operation_on_closed_entity_manager_factory"));
471
        }
479
        }
472
        return this.setupImpl.getMetamodel();
480
        return this.setupImpl.getMetamodel();
473
    }
481
    }
474
482
475
    /**
483
    /**
476
     * INTERNAL:
484
     * INTERNAL: Convenience function to allow us to reset the Metamodel in the
477
     * Convenience function to allow us to reset the Metamodel 
485
     * possible case that we want to regenerate it. This function is outside of
478
     * in the possible case that we want to regenerate it.
486
     * the JPA 2.0 specification.
479
     * This function is outside of the JPA 2.0 specification.
487
     * 
480
     * @param aMetamodel
488
     * @param aMetamodel
481
     * @since Java Persistence 2.0 
489
     * @since Java Persistence 2.0
482
     */
490
     */
483
    public void setMetamodel(Metamodel aMetamodel) {
491
    public void setMetamodel(Metamodel aMetamodel) {
484
        if(!this.isOpen()) {
492
        if (!this.isOpen()) {
485
            throw new IllegalStateException(ExceptionLocalization.buildMessage("operation_on_closed_entity_manager_factory"));
493
            throw new IllegalStateException(ExceptionLocalization.buildMessage("operation_on_closed_entity_manager_factory"));
486
        }
494
        }
487
        this.setupImpl.setMetamodel(aMetamodel);
495
        this.setupImpl.setMetamodel(aMetamodel);
488
    }
496
    }
489
    
497
490
    /**
498
    /**
491
     * Determine the load state of a given persistent attribute
499
     * Determine the load state of a given persistent attribute of an entity
492
     * of an entity belonging to the persistence unit.
500
     * belonging to the persistence unit.
493
     * @param entity containing the attribute
501
     * 
494
     * @param attributeName name of attribute whose load state is
502
     * @param entity
495
     *    to be determined
503
     *            containing the attribute
496
     * @return false if entity's state has not been loaded or
504
     * @param attributeName
497
     *  if the attribute state has not been loaded, otherwise true
505
     *            name of attribute whose load state is to be determined
506
     * @return false if entity's state has not been loaded or if the attribute
507
     *         state has not been loaded, otherwise true
498
     */
508
     */
499
    public boolean isLoaded(Object entity, String attributeName){
509
    public boolean isLoaded(Object entity, String attributeName) {
500
        if (EntityManagerFactoryImpl.isLoaded(entity, attributeName, serverSession).equals(Boolean.valueOf(true))){
510
        if (EntityManagerFactoryImpl.isLoaded(entity, attributeName, serverSession).equals(Boolean.valueOf(true))) {
501
            return true;
511
            return true;
502
        }
512
        }
503
        return false;
513
        return false;
504
    }
514
    }
505
    
515
506
    /**
516
    /**
507
     * Determine the load state of an entity belonging to the
517
     * Determine the load state of an entity belonging to the persistence unit.
508
     * persistence unit.
518
     * This method can be used to determine the load state of an entity passed
509
     * This method can be used to determine the load state 
519
     * as a reference. An entity is considered loaded if all attributes for
510
     * of an entity passed as a reference.  An entity is
520
     * which FetchType EAGER has been specified have been loaded. The
511
     * considered loaded if all attributes for which FetchType
521
     * isLoaded(Object, String) method should be used to determine the load
512
     * EAGER has been specified have been loaded.
522
     * state of an attribute. Not doing so might lead to unintended loading of
513
     * The isLoaded(Object, String) method should be used to 
523
     * state.
514
     * determine the load state of an attribute.
524
     * 
515
     * Not doing so might lead to unintended loading of state.
525
     * @param entity
516
     * @param entity whose load state is to be determined
526
     *            whose load state is to be determined
517
     * @return false if the entity has not been loaded, else true.
527
     * @return false if the entity has not been loaded, else true.
518
     */
528
     */
519
    public boolean isLoaded(Object entity){
529
    public boolean isLoaded(Object entity) {
520
        if (EntityManagerFactoryImpl.isLoaded(entity, serverSession).equals(Boolean.valueOf(true))){
530
        if (EntityManagerFactoryImpl.isLoaded(entity, serverSession).equals(Boolean.valueOf(true))) {
521
            return true;
531
            return true;
522
        }
532
        }
523
        return false;
533
        return false;
524
    }
534
    }
525
    
535
526
    /**
536
    /**
527
     *  Returns the id of the entity.
537
     * Returns the id of the entity. A generated id is not guaranteed to be
528
     *  A generated id is not guaranteed to be available until after
538
     * available until after the database insert has occurred. Returns null if
529
     *  the database insert has occurred.
539
     * the entity does not yet have an id
530
     *  Returns null if the entity does not yet have an id
540
     * 
531
     *  @param entity
541
     * @param entity
532
     *  @return id of the entity
542
     * @return id of the entity
533
     *  @throws IllegalStateException if the entity is found not to be
543
     * @throws IllegalStateException
534
     *          an entity.
544
     *             if the entity is found not to be an entity.
535
     */
545
     */
536
    public Object getIdentifier(Object entity){
546
    public Object getIdentifier(Object entity) {
537
        return EntityManagerFactoryImpl.getIdentifier(entity, serverSession);
547
        return EntityManagerFactoryImpl.getIdentifier(entity, serverSession);
538
    }
548
    }
539
    
549
540
    /**
550
    /**
541
     * Determine the load state of a given persistent attribute
551
     * Determine the load state of a given persistent attribute of an entity
542
     * of an entity belonging to the persistence unit.
552
     * belonging to the persistence unit.
543
     * @param entity containing the attribute
553
     * 
544
     * @param attributeName name of attribute whose load state is
554
     * @param entity
545
     *    to be determined
555
     *            containing the attribute
546
     * @return false if entity's state has not been loaded or
556
     * @param attributeName
547
     *  if the attribute state has not been loaded, otherwise true
557
     *            name of attribute whose load state is to be determined
558
     * @return false if entity's state has not been loaded or if the attribute
559
     *         state has not been loaded, otherwise true
548
     */
560
     */
549
    public static Boolean isLoaded(Object entity, String attributeName, AbstractSession session){
561
    public static Boolean isLoaded(Object entity, String attributeName, AbstractSession session) {
550
        ClassDescriptor descriptor = session.getDescriptor(entity);
562
        ClassDescriptor descriptor = session.getDescriptor(entity);
551
        if (descriptor == null){
563
        if (descriptor == null) {
552
            return null;
564
            return null;
553
        }
565
        }
554
        DatabaseMapping mapping = descriptor.getMappingForAttributeName(attributeName);
566
        DatabaseMapping mapping = descriptor.getMappingForAttributeName(attributeName);
555
        if (mapping == null){
567
        if (mapping == null) {
556
            return null;
568
            return null;
557
        }
569
        }
558
        return isLoaded(entity, attributeName, mapping);
570
        return isLoaded(entity, attributeName, mapping);
559
    }
571
    }
560
    
572
561
    /**
573
    /**
562
     * Check whether a named attribute on a given entity with a given mapping has been loaded.
574
     * Check whether a named attribute on a given entity with a given mapping
575
     * has been loaded.
563
     * 
576
     * 
564
     * This method will check the valueholder or indirect collection for LAZY ForeignReferenceMappings
577
     * This method will check the valueholder or indirect collection for LAZY
565
     * to see if has been instantiated and otherwise check the fetch group.
578
     * ForeignReferenceMappings to see if has been instantiated and otherwise
579
     * check the fetch group.
580
     * 
566
     * @param entity
581
     * @param entity
567
     * @param attributeName
582
     * @param attributeName
568
     * @param mapping
583
     * @param mapping
569
     * @return
584
     * @return
570
     */
585
     */
571
    public static boolean isLoaded(Object entity, String attributeName, DatabaseMapping mapping){
586
    public static boolean isLoaded(Object entity, String attributeName, DatabaseMapping mapping) {
572
        if (mapping.isForeignReferenceMapping()){
587
        if (mapping.isForeignReferenceMapping()) {
573
            if (((ForeignReferenceMapping)mapping).isLazy()){
588
            if (((ForeignReferenceMapping) mapping).isLazy()) {
574
                Object value = mapping.getAttributeValueFromObject(entity);
589
                Object value = mapping.getAttributeValueFromObject(entity);
575
                IndirectionPolicy policy = ((ForeignReferenceMapping)mapping).getIndirectionPolicy();
590
                IndirectionPolicy policy = ((ForeignReferenceMapping) mapping).getIndirectionPolicy();
576
                return policy.objectIsInstantiated(value);
591
                return policy.objectIsInstantiated(value);
577
            }
592
            }
578
        }
593
        }
579
594
580
        if (entity instanceof FetchGroupTracker){
595
        if (entity instanceof FetchGroupTracker) {
581
            return ((FetchGroupTracker)entity)._persistence_isAttributeFetched(attributeName);
596
            return ((FetchGroupTracker) entity)._persistence_isAttributeFetched(attributeName);
582
        } else {
597
        } else {
583
            return true;
598
            return true;
584
        }
599
        }
585
    }
600
    }
586
    
601
587
    /**
602
    /**
588
     * Determine the load state of an entity belonging to the
603
     * Determine the load state of an entity belonging to the persistence unit.
589
     * persistence unit.
604
     * This method can be used to determine the load state of an entity passed
590
     * This method can be used to determine the load state 
605
     * as a reference. An entity is considered loaded if all attributes for
591
     * of an entity passed as a reference.  An entity is
606
     * which FetchType EAGER has been specified have been loaded. The
592
     * considered loaded if all attributes for which FetchType
607
     * isLoaded(Object, String) method should be used to determine the load
593
     * EAGER has been specified have been loaded.
608
     * state of an attribute. Not doing so might lead to unintended loading of
594
     * The isLoaded(Object, String) method should be used to 
609
     * state.
595
     * determine the load state of an attribute.
610
     * 
596
     * Not doing so might lead to unintended loading of state.
611
     * @param entity
597
     * @param entity whose load state is to be determined
612
     *            whose load state is to be determined
598
     * @return false if the entity has not been loaded, else true.
613
     * @return false if the entity has not been loaded, else true.
599
     */
614
     */
600
    public static Boolean isLoaded(Object entity, AbstractSession session){
615
    public static Boolean isLoaded(Object entity, AbstractSession session) {
601
        ClassDescriptor descriptor = session.getDescriptor(entity);
616
        ClassDescriptor descriptor = session.getDescriptor(entity);
602
        if (descriptor == null){
617
        if (descriptor == null) {
603
            return null;
618
            return null;
604
        }
619
        }
605
        List<DatabaseMapping> mappings = descriptor.getMappings();
620
        List<DatabaseMapping> mappings = descriptor.getMappings();
606
        Iterator<DatabaseMapping> i = mappings.iterator();
621
        Iterator<DatabaseMapping> i = mappings.iterator();
607
        while (i.hasNext()){
622
        while (i.hasNext()) {
608
            DatabaseMapping mapping = i.next();
623
            DatabaseMapping mapping = i.next();
609
            if (!mapping.isLazy() && !isLoaded(entity, mapping.getAttributeName(), mapping)){
624
            if (!mapping.isLazy() && !isLoaded(entity, mapping.getAttributeName(), mapping)) {
610
                return false;
625
                return false;
611
            }
626
            }
612
        }
627
        }
613
        return true;
628
        return true;
614
    }
629
    }
615
    
630
616
    /**
631
    /**
617
     *  Returns the id of the entity.
632
     * Returns the id of the entity. A generated id is not guaranteed to be
618
     *  A generated id is not guaranteed to be available until after
633
     * available until after the database insert has occurred. Returns null if
619
     *  the database insert has occurred.
634
     * the entity does not yet have an id
620
     *  Returns null if the entity does not yet have an id
635
     * 
621
     *  @param entity
636
     * @param entity
622
     *  @return id of the entity
637
     * @return id of the entity
623
     *  @throws IllegalStateException if the entity is found not to be
638
     * @throws IllegalStateException
624
     *          an entity.
639
     *             if the entity is found not to be an entity.
625
     */
640
     */
626
    public static Object getIdentifier(Object entity, AbstractSession session){
641
    public static Object getIdentifier(Object entity, AbstractSession session) {
627
        ClassDescriptor descriptor = session.getDescriptor(entity);
642
        ClassDescriptor descriptor = session.getDescriptor(entity);
628
        if (descriptor == null){
643
        if (descriptor == null) {
629
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_persistence_util_non_persistent_class ", new Object[]{entity}));
644
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_persistence_util_non_persistent_class ", new Object[] { entity }));
630
        }
645
        }
631
        if (descriptor.getCMPPolicy() != null){
646
        if (descriptor.getCMPPolicy() != null) {
632
            return descriptor.getCMPPolicy().createPrimaryKeyInstance(entity, session);
647
            return descriptor.getCMPPolicy().createPrimaryKeyInstance(entity, session);
633
        } else {
648
        } else {
634
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_persistence_util_non_persistent_class ", new Object[]{entity}));
649
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_persistence_util_non_persistent_class ", new Object[] { entity }));
635
        }
650
        }
636
    }
651
    }
637
652
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/jpa/JpaCache.java (+144 lines)
Line 0 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 1998, 2010 Oracle. All rights reserved.
3
 * This program and the accompanying materials are made available under the 
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 
5
 * which accompanies this distribution. 
6
 * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
7
 * and the Eclipse Distribution License is available at 
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
10
 * Contributors:
11
 *     James Sutherland  = 1.0 - Initial contribution
12
 ******************************************************************************/
13
package org.eclipse.persistence.jpa;
14
15
import javax.persistence.Cache;
16
17
/**
18
 * Extends JPA Cache interface with additional EclipseLink API.
19
 * @author James Sutherland
20
 */
21
public interface JpaCache extends Cache {
22
    
23
    /**
24
     * ADVANCED:
25
     * Resets the entire Object cache, and the Query cache.
26
     * <p> NOTE: Be careful using this method. This method blows away both this session's and its parent's caches.
27
     * This includes the server cache or any other cache. This throws away any Objects that have been read in.
28
     * Extreme caution should be used before doing this because Object identity will no longer
29
     * be maintained for any Objects currently read in.  This should only be called
30
     * if the application knows that it no longer has references to Objects held in the cache.
31
     */
32
    void clear();
33
    
34
    /**
35
     * ADVANCED:
36
     * Resets the cache for only the instances of the given Class type.
37
     * For inheritance the user must make sure that they only use the root class,
38
     * clearing a subclass cache is not allowed (as they share their parents cache).
39
     * <p> NOTE: Caution must be used in doing this to ensure that the Objects within the cache
40
     * are not referenced from other Objects of other classes or from the application.
41
     */
42
    void clear(Class cls);
43
44
    /**
45
     * Clear all the query caches.
46
     */
47
    void clearQueryCache();
48
49
    /**
50
     * Clear the named query cache associated with the query name.
51
     */
52
    void clearQueryCache(String queryName);
53
54
    /**
55
     * Returns the remaining life of the given Object (in milliseconds).  This method is associated with use of
56
     * cache invalidation feature and returns the difference between the next expiry
57
     * time of the Object and its read time.  The method will return 0 for invalidated Objects.
58
     */
59
    long timeToLive(Object object);
60
61
    /**
62
     * Returns true if the Object with the same id and Class type of the
63
     * the given Object is valid in the cache.
64
     */
65
    boolean isValid(Object object);
66
67
    /**
68
     * Returns true if the Object with the id and Class type is valid in the cache.
69
     */
70
    boolean isValid(Class cls, Object id);
71
72
    /**
73
     * Used to print all the Objects in the cache.
74
     * The output of this method will be logged to this persistence unit's SessionLog at SEVERE level.
75
     */
76
    void print();
77
78
    /**
79
     * Used to print all the Objects in the cache of the Class type.
80
     * The output of this method will be logged to this persistence unit's SessionLog at SEVERE level.
81
     */
82
    void print(Class cls);
83
84
    /**
85
     * Used to print all the currently locked cache keys in the cache.
86
     * The output of this method will be logged to this persistence unit's SessionLog at SEVERE level.
87
     */
88
    void printLocks();
89
90
    /**
91
     * This can be used to help debugging an Object identity problem.
92
     * An Object identity problem is when an Object in the cache references an 
93
     * Object that is not in the cache. This method will validate that all cached 
94
     * Objects are in a correct state.
95
     */
96
    void validate();
97
98
    /**
99
     * Returns the Object from the cache map with the id 
100
     * and Class type.
101
     */
102
    Object getObject(Class cls, Object id);
103
104
    /**
105
     * ADVANCED:
106
     * Puts the given Object into the cache.
107
     * This is a very advanced method, and caution should be used in adding objects to the cache
108
     * as other objects may have relationships to previous object, or this object may have
109
     * relationships to other objects.
110
     */
111
    Object putObject(Object object);
112
113
    /**
114
     * ADVANCED:
115
     * Removes the Object from the cache.
116
     * <p> NOTE: Caution should be used when calling to avoid violating Object identity.
117
     * The application should only call this if its known that no references to the Object exist.
118
     */
119
    Object removeObject(Object object);
120
121
    /**
122
     * ADVANCED:
123
     * Removes the Object with the id and Class type from the cache.
124
     * <p> NOTE: Caution should be used when calling to avoid violating Object identity.
125
     * The application should only call this if its known that no references to the Object exist.
126
     */
127
    Object removeObject(Class cls, Object id);
128
129
    /**
130
     * Returns true if the cache contains an Object with the same id and Class type of the given object.
131
     */
132
    boolean contains(Object object);
133
134
    /**
135
     * Sets an Object to be invalid in the cache.
136
     */
137
    void evict(Object object);
138
139
    /**
140
     * Returns the object's Id.
141
     */
142
    Object getId(Object object);
143
144
}

Return to bug 301063