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

Collapse All | Expand All

(-)foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/localization/i18n/ExceptionLocalizationResource.java (-1 / +6 lines)
Lines 168-174 Link Here
168
                                           { "NO_PARAMETER_WITH_INDEX", "No parameter with index : {0} was found within the query: {1}."},
168
                                           { "NO_PARAMETER_WITH_INDEX", "No parameter with index : {0} was found within the query: {1}."},
169
                                           { "PARAMETER_NILL_NOT_FOUND", "Null parameter passed to getParameterValue()"},
169
                                           { "PARAMETER_NILL_NOT_FOUND", "Null parameter passed to getParameterValue()"},
170
                                           { "NO_VALUE_BOUND", "No value was bound to parameter named: {0}"},
170
                                           { "NO_VALUE_BOUND", "No value was bound to parameter named: {0}"},
171
                                           { "NULL_PARAMETER_PASSED_TO_SET_PARAMETER", "Null parameter was passed to 'setParameter'.  Can not index parameters by 'Null'."}
171
                                           { "NULL_PARAMETER_PASSED_TO_SET_PARAMETER", "Null parameter was passed to 'setParameter'.  Can not index parameters by 'Null'."},
172
                                           { "cache_impl_class_has_no_descriptor_is_not_a_persistent_type", "The class [{0}] is not a persistent type - it has no associated descriptor."},                                           
173
                                           { "cache_impl_object_has_no_descriptor_is_not_a_persistent_type", "The object [{0}] is not of a persistent type - it has no associated descriptor."}, //
174
                                           { "cache_impl_object_descriptor_has_no_cmppolicy_set", "The object [{0}] with descriptor [{1}] does not have a CMPPolicy set, we are unable to return an Id."}, //
175
                                           { "cache_descriptor_has_no_cmppolicy_set_cannot_create_primary_key", "The class [{0}] with descriptor [{1}] does not have a CMPPolicy set, we are unable create a primary key instance for the id type [{2}]."}                                           
176
                                                                                      
172
                                        };
177
                                        };
173
178
174
    /**
179
    /**
(-)jpa/eclipselink.jpa.test/build.xml (+2 lines)
Lines 499-504 Link Here
499
            <fileset dir="${eclipselink.jpa.test}/resource/${eclipselink.annotation.model}" includes="*.xml"/>
499
            <fileset dir="${eclipselink.jpa.test}/resource/${eclipselink.annotation.model}" includes="*.xml"/>
500
        </copy>
500
        </copy>
501
        <copy todir="${eclipselink.jpa.test}/${build.dir}/${eclipselink.annotation.model}">
501
        <copy todir="${eclipselink.jpa.test}/${build.dir}/${eclipselink.annotation.model}">
502
            <!-- 248780: exclude copies of classes from this eclipselink-annotation-model.jar if weaving is disabled in any other jar -->        	
502
            <fileset dir="${eclipselink.jpa.test}/${classes.dir}"
503
            <fileset dir="${eclipselink.jpa.test}/${classes.dir}"
503
                     includes="org/eclipse/persistence/testing/models/"
504
                     includes="org/eclipse/persistence/testing/models/"
504
                     excludes="org/eclipse/persistence/testing/models/jpa/xml/**
505
                     excludes="org/eclipse/persistence/testing/models/jpa/xml/**
Lines 508-513 Link Here
508
                               org/eclipse/persistence/testing/models/jpa/fieldaccess/advanced/**
509
                               org/eclipse/persistence/testing/models/jpa/fieldaccess/advanced/**
509
                               org/eclipse/persistence/testing/models/jpa/jpaadvancedproperties/**
510
                               org/eclipse/persistence/testing/models/jpa/jpaadvancedproperties/**
510
                               org/eclipse/persistence/testing/models/jpa/fieldaccess/advanced/**
511
                               org/eclipse/persistence/testing/models/jpa/fieldaccess/advanced/**
512
                               org/eclipse/persistence/testing/models/jpa/metamodel/**            	
511
                               org/eclipse/persistence/testing/models/jpa/beanvalidation/**
513
                               org/eclipse/persistence/testing/models/jpa/beanvalidation/**
512
                               org/eclipse/persistence/testing/models/weaving/**"/>
514
                               org/eclipse/persistence/testing/models/weaving/**"/>
513
        </copy>
515
        </copy>
(-)jpa/eclipselink.jpa.test/resource/eclipselink-metamodel-model/persistence.xml (+2 lines)
Lines 20-27 Link Here
20
        <!-- 300051: added to test @EmbeddedId:CPUEmbeddedId directly on @MappedSuperclass:CPU -->
20
        <!-- 300051: added to test @EmbeddedId:CPUEmbeddedId directly on @MappedSuperclass:CPU -->
21
        <class>org.eclipse.persistence.testing.models.jpa.metamodel.MultiCoreCPU</class>
21
        <class>org.eclipse.persistence.testing.models.jpa.metamodel.MultiCoreCPU</class>
22
        <class>org.eclipse.persistence.testing.models.jpa.metamodel.Core</class>
22
        <class>org.eclipse.persistence.testing.models.jpa.metamodel.Core</class>
23
        <!-- 248780: Refactor Cache Implementation surrounding evict() and MappedSuperclass support -->        
23
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
24
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
24
        <properties>
25
        <properties>
26
             <property name="eclipselink.weaving" value="false"/>        
25
             <property name="eclipselink.session-name" value="metamodel"/>
27
             <property name="eclipselink.session-name" value="metamodel"/>
26
        </properties>
28
        </properties>
27
    </persistence-unit>
29
    </persistence-unit>
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/metamodel/Person.java (-1 / +2 lines)
Lines 31-37 Link Here
31
import javax.persistence.TableGenerator;
31
import javax.persistence.TableGenerator;
32
32
33
@MappedSuperclass
33
@MappedSuperclass
34
public abstract class Person implements Serializable {
34
//public abstract class Person implements Serializable {
35
public class Person implements Serializable { //  changed from abstract to concrete for 248780   
35
    @Id
36
    @Id
36
    @GeneratedValue(strategy=TABLE, generator="PERSON_MM_TABLE_GENERATOR")
37
    @GeneratedValue(strategy=TABLE, generator="PERSON_MM_TABLE_GENERATOR")
37
    @TableGenerator(
38
    @TableGenerator(
(-)jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/advanced/CacheImplJUnitTest.java (-4 / +408 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
* Copyright (c)  2008, Sun Microsystems, Inc. All rights reserved.
2
 * Copyright (c)  2008, Sun Microsystems, Inc. All rights reserved.
3
* This program and the accompanying materials are made available under the
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
4
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
5
* which accompanies this distribution.
5
* which accompanies this distribution.
Lines 8-22 Link Here
8
* http://www.eclipse.org/org/documents/edl-v10.php.
8
* http://www.eclipse.org/org/documents/edl-v10.php.
9
*
9
*
10
* Contributors:
10
* Contributors:
11
*     DaraniY  = 1.0 - Initialize contribution
11
 *     12/04/2008 - 2.0 Darani Yallapragada 
12
 *       - 248780: Initial contribution for JPA 2.0
13
 *     04/22/2010 - 2.1 Michael O'Brien 
14
 *       - 248780: Refactor Cache Implementation surrounding evict()
15
 *         http://wiki.eclipse.org/EclipseLink/Development/JPA_2.0/cache_api#Refactor_20100322
16
 *         Fix evict() to handle non-Entity classes
17
 *         Refactor to get IdentityMapAccessor state through EMF reference
18
 *         Refactor dependencies to use Interfaces instead of Impl subclasses
19
 *         Handle no CMPPolicy case for getId()
20
 *         Handle no associated descriptor for Class parameter
21
 *         MappedSuperclasses passed to evict() cause implementing subclasses to be evicted
22
 *         Throw an IAE for Interfaces and Embeddable classes passed to evict()
12
******************************************************************************/
23
******************************************************************************/
13
package org.eclipse.persistence.testing.tests.jpa.advanced;
24
package org.eclipse.persistence.testing.tests.jpa.advanced;
14
25
26
import javax.persistence.Cache;
15
import javax.persistence.EntityManager;
27
import javax.persistence.EntityManager;
16
import junit.framework.Test;
28
import junit.framework.Test;
17
import junit.framework.TestSuite;
29
import junit.framework.TestSuite;
18
import org.eclipse.persistence.testing.models.jpa.advanced.*;
30
import org.eclipse.persistence.testing.models.jpa.advanced.*;
31
import org.eclipse.persistence.testing.models.jpa.advanced.fetchgroup.ChestProtector;
32
import org.eclipse.persistence.testing.models.jpa.advanced.fetchgroup.GoalieGear;
33
import org.eclipse.persistence.testing.models.jpa.advanced.fetchgroup.Pads;
34
import org.eclipse.persistence.testing.models.jpa.metamodel.Manufacturer;
35
import org.eclipse.persistence.descriptors.ClassDescriptor;
36
import org.eclipse.persistence.internal.jpa.CMP3Policy;
19
import org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl;
37
import org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl;
38
import org.eclipse.persistence.internal.jpa.EntityManagerImpl;
20
import org.eclipse.persistence.jpa.JpaCache;
39
import org.eclipse.persistence.jpa.JpaCache;
21
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
40
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
22
41
Lines 25-31 Link Here
25
 */
44
 */
26
public class CacheImplJUnitTest extends JUnitTestCase {
45
public class CacheImplJUnitTest extends JUnitTestCase {
27
46
28
29
    public CacheImplJUnitTest() {
47
    public CacheImplJUnitTest() {
30
        super();
48
        super();
31
    }
49
    }
Lines 39-44 Link Here
39
        clearCache();
57
        clearCache();
40
    }
58
    }
41
59
60
    /**
61
     * Note: These tests are setup with ID generation - but it is not used.
62
     * We set the Id manually so we can test cache operations like eviction properly.
63
     * @return
64
     */
42
    public static Test suite() {
65
    public static Test suite() {
43
        TestSuite suite = new TestSuite();
66
        TestSuite suite = new TestSuite();
44
        suite.setName("CacheImplJUnitTest");
67
        suite.setName("CacheImplJUnitTest");
Lines 50-56 Link Here
50
        suite.addTest(new CacheImplJUnitTest("testEvictAll"));
73
        suite.addTest(new CacheImplJUnitTest("testEvictAll"));
51
        suite.addTest(new CacheImplJUnitTest("testEvictContains"));
74
        suite.addTest(new CacheImplJUnitTest("testEvictContains"));
52
        suite.addTest(new CacheImplJUnitTest("testCacheAPI"));
75
        suite.addTest(new CacheImplJUnitTest("testCacheAPI"));
53
        
76
        // 20100322: 248780: CacheImpl refactor for non-Entity classes
77
        suite.addTest(new CacheImplJUnitTest("testEvictClass_MappedSuperclass_RemovesAssignableSubclasses"));
78
        suite.addTest(new CacheImplJUnitTest("testEvictClassObject_MappedSuperclass_RemovesAssignableSubclasses"));
79
        suite.addTest(new CacheImplJUnitTest("testEvictClass_JavaLangClass_hasNoEffect"));
80
        suite.addTest(new CacheImplJUnitTest("testGetId_fromUnmanagedMappedSuperclass_handles_null_descriptor"));
81
        suite.addTest(new CacheImplJUnitTest("testGetId_fromUnsupportedJavaLangInteger_throwsIAE_on_null_descriptor"));
82
        // Run these tests last as they modify the state of the ClassDescriptor permanently to verify variant corner use cases
83
        suite.addTest(new CacheImplJUnitTest("testGetId_fromNativeMappedSuperclass_handles_null_cmp3policy_weaving_on"));       
84
        suite.addTest(new CacheImplJUnitTest("testGetId_fromNativeMappedSuperclass_handles_null_cmp3policy_and_null_pk_with_weaving_on"));
85
        suite.addTest(new CacheImplJUnitTest("testGetId_fromNativeMappedSuperclass_handles_null_cmp3policy_and_null_pk_with_weaving_off"));
86
        // test null descriptor on closed entityManager                
54
        return suite;
87
        return suite;
55
    }
88
    }
56
    
89
    
Lines 97-102 Link Here
97
        assertTrue("Employee not found in cache", cache.contains(employee));
130
        assertTrue("Employee not found in cache", cache.contains(employee));
98
        cache.evict(employee);
131
        cache.evict(employee);
99
        cache.putObject(employee);
132
        cache.putObject(employee);
133
        cache.print();        
100
        cache.removeObject(employee);
134
        cache.removeObject(employee);
101
        cache.removeObject(Employee.class, employee.getId());
135
        cache.removeObject(Employee.class, employee.getId());
102
        cache.clear();
136
        cache.clear();
Lines 225-230 Link Here
225
        } finally {
259
        } finally {
226
            closeEntityManager(em);
260
            closeEntityManager(em);
227
        }
261
        }
262
    }
263
    
264
    /**
265
     * In this test we attempt to remove the MappedSuperclass (superclass) from the entity cache.
266
     * The resulting action removes all implementing subclasses - which has the same effect
267
     * as just removing the implementing Entity in the first case.
268
     * 
269
     * Hierarchy:
270
     * HockeyGear (Abstract Entity)
271
     *       +----- GoalieGear (Concrete MappedSuperclass) --- (we will evict this one)
272
     *                  +----- Chest Protector (Concrete Entity) ---- cacheable (but this will actually be evicted)
273
     *                  +----- Pads (Concrete Entity) ---- cacheable (as well as this one)
274
     */
275
    public void testEvictClass_MappedSuperclass_RemovesAssignableSubclasses() {
276
        if (! isJPA10()) {        
277
            int ID_PADS = ID_TEST_BASE + 100;
278
            int ID_CHESTPROTECTOR = ID_PADS++;
279
            final EntityManager em = createEntityManager("default1");
280
            // Persist both implementing subclasses of GoalieGear
281
            beginTransaction(em);
282
            // HockeyGear(Abstract Entity) << GoalieGear (Concrete MappedSuperclass) << ChestProtector (Concrete Entity)
283
            ChestProtector e1 = new ChestProtector();
284
            e1.setDescription("chest_protector");
285
            e1.setSerialNumber(new Integer(ID_PADS));
286
            em.persist(e1);
287
            commitTransaction(em);
288
            //  closeEntityManager(em); // do not close the entityManager between transactions or you will get bug# 307445
289
            
290
            beginTransaction(em);
291
            // HockeyGear(Abstract Entity) << GoalieGear (Concrete MappedSuperclass) << ChestProtector (Concrete Entity)
292
            Pads p1 = new Pads();
293
            p1.setDescription("pads");
294
            p1.setSerialNumber(new Integer(ID_CHESTPROTECTOR));
295
            em.persist(p1);
296
            commitTransaction(em);
297
            closeEntityManager(em);
298
        
299
            EntityManager em1 = createEntityManager("default1");
300
            EntityManager em2 = createEntityManager("default1");
301
            try {
302
                ChestProtector e2 = (ChestProtector) ((EntityManagerFactoryImpl) getEntityManagerFactory("default1"))
303
                    .getServerSession().getIdentityMapAccessor().getFromIdentityMap(e1);
304
                Pads p2 = (Pads) ((EntityManagerFactoryImpl) getEntityManagerFactory("default1"))
305
                    .getServerSession().getIdentityMapAccessor().getFromIdentityMap(p1);
306
                // change the entity in the cache (only) - later a find() will get the unmodified version in the database
307
                e2.setDescription("new_chest_protector");
308
                p2.setDescription("new_pads");
309
                
310
                String expected_chestProtector = em1.find(GoalieGear.class, ID_CHESTPROTECTOR).getDescription();
311
                String expected_pads = em1.find(GoalieGear.class, ID_PADS).getDescription();
312
            
313
                // evict the inheriting entities via their MappedSuperclass
314
                getEntityManagerFactory("default1").getCache().evict(GoalieGear.class);            
315
            
316
                // read the inheriting entities directly from the database (because they are no longer in the cache - hopefully)
317
                GoalieGear g5 = em2.find(GoalieGear.class, ID_CHESTPROTECTOR);
318
                GoalieGear p5 = em2.find(GoalieGear.class, ID_PADS);            
319
            
320
                // Check that we are not actually getting the supposed "to be evicted" cached version (that was modified)
321
                String actual_chestProtector = g5.getDescription();
322
                String actual_pads = p5.getDescription();
323
                // verify that assignable subclasses (ChestProtector and Pads) are removed from the cache
324
                assertNotSame("Assertion Error - There should be no modified cached entity instance in the cache - the entity read from the database should be different. "
325
                    , expected_chestProtector, actual_chestProtector);
326
                assertNotSame("Assertion Error - There should be no modified cached entity instance in the cache - the entity read from the database should be different. "
327
                    , expected_pads, actual_pads);            
328
            } finally {
329
                closeEntityManager(em1);
330
                closeEntityManager(em2);
331
            }
332
        }
333
    }
228
334
335
    /**
336
     * In this test we attempt to remove the MappedSuperclass (superclass) from the entity cache.
337
     * The resulting action removes all implementing subclasses - which has the same effect
338
     * as just removing the implementing Entity in the first case.
339
     * 
340
     * Hierarchy:
341
     * HockeyGear (Abstract Entity)
342
     *       +----- GoalieGear (Concrete MappedSuperclass) --- (we will evict this one)
343
     *                  +----- Chest Protector (Concrete Entity) ---- cacheable (but this will actually be evicted)
344
     *                  +----- Pads (Concrete Entity) ---- cacheable (as well as this one)
345
     */
346
    public void testEvictClassObject_MappedSuperclass_RemovesAssignableSubclasses() {
347
        if (! isJPA10()) {        
348
            int ID_PADS = ID_TEST_BASE + 200;
349
            int ID_CHESTPROTECTOR = ID_PADS++;
350
            EntityManager em = createEntityManager("default1");
351
            // Persist both implementing subclasses of GoalieGear
352
            beginTransaction(em);
353
            // HockeyGear(Abstract Entity) << GoalieGear (Concrete MappedSuperclass) << ChestProtector (Concrete Entity)
354
            ChestProtector e1 = new ChestProtector();
355
            e1.setDescription("chest_protector");
356
            e1.setSerialNumber(new Integer(ID_PADS));
357
            em.persist(e1);
358
            commitTransaction(em);
359
            //  closeEntityManager(em); // do not close the entityManager between transactions or you will get bug# 307445
360
        
361
            beginTransaction(em);
362
            Pads p1 = new Pads();
363
            p1.setDescription("pads");
364
            p1.setSerialNumber(new Integer(ID_CHESTPROTECTOR));
365
            em.persist(p1);
366
            commitTransaction(em);
367
            closeEntityManager(em);
368
        
369
            EntityManager em1 = createEntityManager("default1");
370
            EntityManager em2 = createEntityManager("default1");
371
            try {
372
                GoalieGear c2 = (GoalieGear) ((EntityManagerFactoryImpl) getEntityManagerFactory("default1"))
373
                    .getServerSession().getIdentityMapAccessor().getFromIdentityMap(e1);
374
                Pads p2 = (Pads) ((EntityManagerFactoryImpl) getEntityManagerFactory("default1"))
375
                    .getServerSession().getIdentityMapAccessor().getFromIdentityMap(p1);
376
                // change the entity in the cache (only) - later a find() will get the unmodified version in the database
377
                c2.setDescription("new_chest_protector");
378
                p2.setDescription("new_pads");
379
            
380
                String expected_chestProtector = em1.find(GoalieGear.class, ID_CHESTPROTECTOR).getDescription();
381
                String expected_pads = em1.find(GoalieGear.class, ID_PADS).getDescription();
382
            
383
                // evict the inheriting entity (by Id) via its' MappedSuperclass
384
                getEntityManagerFactory("default1").getCache().evict(GoalieGear.class, c2.getSerialNumber()); // ChestProtector            
385
                getEntityManagerFactory("default1").getCache().evict(GoalieGear.class, p2.getSerialNumber()); // Pad
386
            
387
                // read the inheriting entities directly from the database (because they are no longer in the cache - hopefully)
388
                GoalieGear c5 = em2.find(GoalieGear.class, ID_CHESTPROTECTOR);
389
                GoalieGear p5 = em2.find(GoalieGear.class, ID_PADS);            
390
            
391
                // Check that we are not actually getting the supposed "to be evicted" cached version (that was modified)
392
                String actual_chestProtector = c5.getDescription();
393
                String actual_pads = p5.getDescription();
394
                // verify that assignable subclasses (ChestProtector and Pads) are removed from the cache
395
                assertNotSame("Assertion Error - There should be no modified cached entity instance in the cache - the entity read from the database should be different. "
396
                    , expected_chestProtector, actual_chestProtector);
397
                assertNotSame("Assertion Error - There should be no modified cached entity instance in the cache - the entity read from the database should be different. "
398
                    , expected_pads, actual_pads);            
399
            } finally {
400
                closeEntityManager(em1);
401
                closeEntityManager(em2);
402
            }
403
        }
229
    }
404
    }
405
    
406
    
407
    //org.eclipse.persistence.testing.models.jpa.jpaadvancedproperties.Customer
408
    
409
    public void testEvictClass_JavaLangClass_hasNoEffect() {
410
        if (! isJPA10()) {
411
            int ID = ID_TEST_BASE + 300;
412
            boolean _exceptionThrown = false;
413
            EntityManager em = createEntityManager("default1");
414
            // Persist
415
            beginTransaction(em);
416
            // HockeyGear(Abstract Entity) << GoalieGear (Concrete MappedSuperclass) << ChestProtector (Concrete Entity)
417
            ChestProtector e1 = new ChestProtector();
418
            e1.setDescription("gear");
419
            e1.setSerialNumber(new Integer(ID));
420
            em.persist(e1);
421
            commitTransaction(em);
422
            closeEntityManager(em);
423
        
424
            EntityManager em1 = createEntityManager("default1");
425
            EntityManager em2 = createEntityManager("default1");
426
            try {
427
                GoalieGear e2 = (GoalieGear) ((EntityManagerFactoryImpl) getEntityManagerFactory("default1"))
428
                    .getServerSession().getIdentityMapAccessor().getFromIdentityMap(e1);
429
                // change the entity in the cache (only) - later a find() will get the unmodified version in the database
430
                e2.setDescription("new_gear");
431
                String expected = em1.find(GoalieGear.class, ID).getDescription();
432
                // The following dows not throws an IAE on a plain java (Integer) class - it will leave the cached entities as-is in the cache
433
                getEntityManagerFactory("default1").getCache().evict(Integer.class);
434
                // read the inheriting entities directly from the cache (because they were not evicted)            
435
                GoalieGear g5 = em2.find(GoalieGear.class, ID);
436
                String actual = g5.getDescription();
437
                assertSame("Assertion Error - There should be a modified cached entity instance in the cache - the entity is not actually read from the database"
438
                    , expected, actual);
439
            } catch (IllegalArgumentException iae) {
440
                _exceptionThrown = true;
441
            } finally {
442
                closeEntityManager(em1);
443
                closeEntityManager(em2);
444
                assertFalse("IllegalArgumentException was thrown.", _exceptionThrown);            
445
            }
446
        }
447
    }
448
            
449
    // The xml model version is not managed
450
    public void testGetId_fromUnmanagedMappedSuperclass_handles_null_descriptor() {
451
        if (!isJPA10()) {        
452
            int ID = ID_TEST_BASE + 400;
453
            boolean _exceptionThrown = false;
454
            EntityManager em = createEntityManager();//"default1");
455
            // Persist both implementing subclasses of GoalieGear
456
            beginTransaction(em);
457
            // CacheableTrueMappedSuperclass (MappedSuperclass with Id) << SubCacheableFalseEntity (Entity)
458
            org.eclipse.persistence.testing.models.jpa.xml.cacheable.SubCacheableFalseEntity anEntity 
459
                = new org.eclipse.persistence.testing.models.jpa.xml.cacheable.SubCacheableFalseEntity();
460
            org.eclipse.persistence.testing.models.jpa.xml.cacheable.CacheableTrueMappedSuperclass aMappedSuperclass 
461
                = new org.eclipse.persistence.testing.models.jpa.xml.cacheable.CacheableTrueMappedSuperclass();
462
            anEntity.setId(ID);
463
            // Can we place non-persistable objects into only the cache (non-entities)?
464
            // We do not need to persist this entity for this specific test
465
            //em.persist(anEntity);
466
            commitTransaction(em);
467
            closeEntityManager(em);
468
        
469
            EntityManager em1 = createEntityManager("default1");
470
            EntityManager em2 = createEntityManager("default1");
471
            Cache aJPACache = getEntityManagerFactory("default1").getCache();
472
            JpaCache anEclipseLinkCache = (JpaCache)getEntityManagerFactory("default1").getCache();
473
            Object anId = null;
474
            try {
475
                anId = anEclipseLinkCache.getId(anEntity);
476
            } catch (IllegalArgumentException iae) {
477
                _exceptionThrown = true;
478
            } finally {
479
                closeEntityManager(em1);
480
                closeEntityManager(em2);
481
                assertTrue("IllegalArgumentException should have been thrown on the unmanaged entity lacking a descriptor.", _exceptionThrown);            
482
            }
483
        }
484
    }
485
486
    public void testGetId_fromUnsupportedJavaLangInteger_throwsIAE_on_null_descriptor() {
487
        if (!isJPA10()) {
488
            boolean _exceptionThrown = false;
489
            EntityManager em1 = createEntityManager("default1");            
490
            JpaCache anEclipseLinkCache = (JpaCache)getEntityManagerFactory("default1").getCache();
491
            try {
492
                anEclipseLinkCache.getId(new Integer(1));
493
            } catch (IllegalArgumentException iae) {
494
                _exceptionThrown = true;
495
            } finally {
496
                closeEntityManager(em1);                
497
                assertTrue("IllegalArgumentException should have been thrown on a getId() call on an Integer which obviously has no descriptor.", _exceptionThrown);                
498
            }
499
        }
500
    }
501
    
502
    /**
503
     * In order to test handling of a null CMP3Policy on the descriptor during a cache.getId() call,
504
     * we must have an Id on an abstract MappedSuperclass root that is defined via sessions.xml.
505
     * Or we can simulate a null CMP3Policy by clearing it - so that the alternate code handling is run
506
     */
507
    public void testGetId_fromNativeMappedSuperclass_handles_null_cmp3policy_weaving_on() {
508
        if (!isJPA10()) {
509
            int ID = ID_TEST_BASE + 500;
510
            Object originalId = null;
511
            EntityManager em = createEntityManager();//"default1");
512
            // Persist both implementing subclasses of GoalieGear
513
            beginTransaction(em);
514
            // CacheableTrueMappedSuperclass (MappedSuperclass with Id) << SubCacheableFalseEntity (Entity)
515
            org.eclipse.persistence.testing.models.jpa.cacheable.SubCacheableFalseEntity anEntity = new org.eclipse.persistence.testing.models.jpa.cacheable.SubCacheableFalseEntity();
516
            org.eclipse.persistence.testing.models.jpa.cacheable.CacheableTrueMappedSuperclass aMappedSuperclass = new org.eclipse.persistence.testing.models.jpa.cacheable.CacheableTrueMappedSuperclass();
517
            anEntity.setId(ID);
518
            // Can we place non-persistable objects into only the cache (non-entities)?
519
            em.persist(anEntity);
520
            commitTransaction(em);
521
            closeEntityManager(em);
522
        
523
            EntityManager em1 = createEntityManager("default1");
524
            Cache aJPACache = getEntityManagerFactory("default1").getCache();
525
            JpaCache anEclipseLinkCache = (JpaCache)getEntityManagerFactory("default1").getCache();
526
            Object anId = null;
527
            originalId = anEntity.getId();
528
        
529
            // clear the CMP3Policy to simulate a native pojo
530
            ClassDescriptor cdesc = ((EntityManagerImpl)em1).getSession().getClassDescriptor(anEntity.getClass());
531
            CMP3Policy policy = (CMP3Policy) (cdesc.getCMPPolicy());
532
            assertNotNull("CMP3Policy should exist", policy);
533
            cdesc.setCMPPolicy(null);
534
            try {
535
                // This call will test the weaving [on] section of getId()
536
                anId = anEclipseLinkCache.getId(anEntity);
537
                assertNotNull("Id instance should not be null", anId);
538
                assertTrue("Id instance should be of type Integer", anId instanceof Integer);            
539
                assertEquals(((Integer)anId).intValue(), ID);
540
                assertEquals(anId, originalId);
541
            } finally {
542
                closeEntityManager(em1);
543
            }
544
        }
545
    }
546
547
    public void testGetId_fromNativeMappedSuperclass_handles_null_cmp3policy_and_null_pk_with_weaving_on() {
548
        if (!isJPA10()) {
549
            //int ID = ID_TEST_BASE + 600;
550
            Integer ID = null; // keep object as null for unset testing
551
            Object originalId = null;
552
            EntityManager em = createEntityManager("metamodel1");
553
            beginTransaction(em);
554
            // org.eclipse.persistence.testing.models.jpa.metamodel.Person(Concrete MappedSuperclass) <-- Corporation(Abstract MappedSuperclass) <-- Manufacturer (Entity)
555
            Manufacturer anEntity = new Manufacturer();
556
            //anEntity.setId(ID);
557
            // Can we place non-persistable objects into only the cache (non-entities)?
558
            em.persist(anEntity);
559
            commitTransaction(em);
560
            closeEntityManager(em);
561
        
562
            EntityManager em1 = createEntityManager("metamodel1");
563
            Cache aJPACache = getEntityManagerFactory("metamodel1").getCache();
564
            JpaCache anEclipseLinkCache = (JpaCache)getEntityManagerFactory("metamodel1").getCache();
565
            Object anId = null;
566
            // The originalId will be set by automatic sequence generation - if we require it
567
            originalId = anEntity.getId();
568
        
569
            // clear the CMP3Policy to simulate a native pojo
570
            ClassDescriptor cdesc = ((EntityManagerImpl)em1).getSession().getClassDescriptor(anEntity.getClass());
571
            CMP3Policy policy = (CMP3Policy) (cdesc.getCMPPolicy());
572
            assertNotNull("CMP3Policy should exist prior to having been cleared manually for this test", policy);
573
            cdesc.setCMPPolicy(null);
574
            try {
575
                anId = anEclipseLinkCache.getId(anEntity);
576
                assertNotNull("Id instance should not be null", anId);
577
                assertTrue("Id instance should be of type Integer", anId instanceof Integer);            
578
                assertEquals(anId, originalId);
579
                // set the CMPPolicy back for out of order testing
580
                cdesc.setCMPPolicy(policy);
581
            } finally {
582
                closeEntityManager(em1);
583
            }
584
        }
585
    }
586
    
587
    // We need a MappedSuperclass that is defined by a persistence.xml where eclipselink.weaving="false"
588
    // This test requires that weaving is off in persistence.xml for metamodel1
589
    public void testGetId_fromNativeMappedSuperclass_handles_null_cmp3policy_and_null_pk_with_weaving_off() {
590
        if (!isJPA10()) {
591
            int ID = ID_TEST_BASE + 700;
592
            //Integer ID = null; // keep object as null for unset testing
593
            Object originalId = null;
594
            EntityManager em = createEntityManager("metamodel1");
595
            beginTransaction(em);
596
            Manufacturer anEntity = new Manufacturer();            
597
            anEntity.setName("test");
598
            anEntity.setId(ID);
599
            // Can we place non-persistable objects into only the cache (non-entities)?
600
            em.persist(anEntity);
601
            commitTransaction(em);
602
            //closeEntityManager(em); // keep the EM open
603
        
604
            EntityManager em1 = createEntityManager("metamodel1");
605
            Cache aJPACache = getEntityManagerFactory("metamodel1").getCache();
606
            JpaCache anEclipseLinkCache = (JpaCache)getEntityManagerFactory("metamodel1").getCache();
607
            Object anId = null;
608
            // The originalId will be set by automatic sequence generation - if we require it
609
            originalId = anEntity.getId();
610
        
611
            // clear the CMP3Policy to simulate a native pojo
612
            ClassDescriptor cdesc = ((EntityManagerImpl)em).getSession().getClassDescriptor(anEntity.getClass());
613
            assertNotNull("ClassDescriptor for Entity must not be null", cdesc); // check that the entityManager is not null
614
            CMP3Policy policy = (CMP3Policy) (cdesc.getCMPPolicy());
615
            assertNotNull("CMP3Policy should exist prior to having been cleared manually for this test", policy);
616
            cdesc.setCMPPolicy(null);
617
            try {
618
                anId = anEclipseLinkCache.getId(anEntity);
619
                assertNotNull("Id instance should not be null", anId);
620
                assertTrue("Id instance should be of type Integer", anId instanceof Integer);            
621
                assertEquals(anId, ID);
622
                assertEquals(anId, originalId);
623
                // set the CMPPolicy back for out of order testing
624
                cdesc.setCMPPolicy(policy);
625
            } finally {
626
                closeEntityManager(em1);
627
                closeEntityManager(em);
628
            }
629
        }
630
    }
631
632
    // 20100422: 248780: CacheImpl refactor for non-Entity classes
633
    public static int ID_TEST_BASE = 1136; // change this value during iterative testing
230
}
634
}
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/CacheImpl.java (-61 / +211 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c)  2008, Sun Microsystems, Inc. All rights reserved.
2
 * Copyright (c)  2008, Sun Microsystems, Inc. All rights reserved. 
3
 * This program and the accompanying materials are made available under the
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
4
 * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
5
 * which accompanies this distribution.
5
 * which accompanies this distribution.
Lines 8-22 Link Here
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
8
 * http://www.eclipse.org/org/documents/edl-v10.php.
9
 *
9
 *
10
 * Contributors:
10
 * Contributors:
11
 *     DaraniY  = 1.0 - Initialize contribution
11
 *     12/04/2008 - 2.0 Darani Yallapragada 
12
 *       - 248780: Initial contribution for JPA 2.0
13
 *     04/22/2010 - 2.1 Michael O'Brien 
14
 *       - 248780: Refactor Cache Implementation surrounding evict()
15
 *         Fix evict() to handle non-Entity classes
16
 *         Refactor to get IdentityMapAccessor state through EMF reference
17
 *         Refactor dependencies to use Interfaces instead of Impl subclasses
18
 *         Handle no CMPPolicy case for getId()
19
 *         Handle no associated descriptor for Class parameter
20
 *         MappedSuperclasses passed to evict() cause implementing subclasses to be evicted
21
 *         Throw an IAE for Interfaces and Embeddable classes passed to evict()
22
 *     
12
 ******************************************************************************/
23
 ******************************************************************************/
13
package org.eclipse.persistence.internal.jpa;
24
package org.eclipse.persistence.internal.jpa;
14
25
26
import java.util.Iterator;
27
15
import org.eclipse.persistence.descriptors.ClassDescriptor;
28
import org.eclipse.persistence.descriptors.ClassDescriptor;
16
import org.eclipse.persistence.internal.identitymaps.CacheKey;
29
import org.eclipse.persistence.internal.identitymaps.CacheKey;
30
import org.eclipse.persistence.internal.localization.ExceptionLocalization;
31
import org.eclipse.persistence.internal.sessions.AbstractSession;
17
import org.eclipse.persistence.jpa.JpaCache;
32
import org.eclipse.persistence.jpa.JpaCache;
18
import org.eclipse.persistence.sessions.IdentityMapAccessor;
33
import org.eclipse.persistence.sessions.IdentityMapAccessor;
19
import org.eclipse.persistence.sessions.server.ServerSession;
34
import org.eclipse.persistence.sessions.Session;
20
35
21
/**
36
/**
22
 * Implements the JPA Cache interface using the EclipseLink cache API through IdentityMapAccessor.
37
 * Implements the JPA Cache interface using the EclipseLink cache API through IdentityMapAccessor.
Lines 24-84 Link Here
24
 */
39
 */
25
public class CacheImpl implements JpaCache {
40
public class CacheImpl implements JpaCache {
26
41
27
    private IdentityMapAccessor accessor;
42
    /** The EntityManagerFactory associated with this Cache */
28
    private EntityManagerFactoryImpl emf;
43
    private EntityManagerFactoryImpl emf;
29
    private ServerSession serversession;
30
44
31
    public CacheImpl(EntityManagerFactoryImpl emf, IdentityMapAccessor accessor) {
45
    /**
32
        this.accessor = accessor;
46
     * @param emf
47
     */
48
    public CacheImpl(EntityManagerFactoryImpl emf) {
33
        this.emf = emf;
49
        this.emf = emf;
34
        this.serversession = emf.getServerSession();
35
    }
50
    }
36
51
37
    /**
52
    /**
38
     * Returns true if the cache contains an Object with the id and Class type, and is valid.
53
     * Returns true if the cache contains an Object with the id and Class type, and is valid.
54
     * @see Cache#contains(Class, Object)
39
     */
55
     */
40
    public boolean contains(Class cls, Object id) {
56
    public boolean contains(Class cls, Object id) {
41
        this.emf.verifyOpen();
57
        getEntityManagerFactory().verifyOpen();
42
        Object pk =  createPrimaryKeyFromId(cls, id);
58
        Object pk =  createPrimaryKeyFromId(cls, id);
43
        ClassDescriptor descriptor = this.serversession.getDescriptor(cls);
59
        ClassDescriptor descriptor = getSession().getClassDescriptor(cls); // getDescriptor() is the same call
44
        CacheKey key = ((org.eclipse.persistence.internal.sessions.IdentityMapAccessor)this.accessor).getCacheKeyForObject(pk, cls, descriptor);
60
        /**
61
         * Check for no descriptor associated with the class parameter.
62
         * This will occur if the class represents a MappedSuperclass (concrete or abstract class),
63
         * an interface or Embeddable class.
64
         */
65
        if(null == descriptor) {
66
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage(
67
                    "cache_impl_class_has_no_descriptor_is_not_a_persistent_type", 
68
                    new Object[] {cls}));
69
        }
45
70
46
        return (key != null) && (key.getObject() != null) && (!descriptor.getCacheInvalidationPolicy().isInvalidated(key)); 
71
        // we can assume that all implementors of IdentityMapAccessor implement getCacheKeyforObject
72
        CacheKey key = ((org.eclipse.persistence.internal.sessions.IdentityMapAccessor)getAccessor())
73
            .getCacheKeyForObject(pk, cls, descriptor);
74
        return key != null && key.getObject() != null && !descriptor.getCacheInvalidationPolicy().isInvalidated(key); //  brackets around != in 298985 not required as && has lower precedence   
47
    }
75
    }
48
76
49
    /**
77
    /**
78
     * INTERNAL:
79
     * This private method searches the map of descriptors for possible superclasses to the
80
     * passed in class parameter and invalidates only entities found in the cache.
81
     * If the class is not an Entity or MappedSuperclass (such as an Embeddable or plain java class)
82
     *  - nothing will be evicted  
83
     * @param possibleSubclass
84
     * @param id
85
     */
86
    private void evictAssignableEntitySuperclass(Class possibleSubclass, Object id) {
87
        // Check each descriptor's javaClass key in the Map of descriptors on the session
88
        // We will search all descriptors and evict all implementing subclasses
89
        Iterator<ClassDescriptor> descriptorIterator = getSession().getDescriptors().values().iterator();
90
        while(descriptorIterator.hasNext()) {
91
            ClassDescriptor candidateAssignableDescriptor = descriptorIterator.next();
92
            if(candidateAssignableDescriptor.isChildDescriptor() && 
93
                    !candidateAssignableDescriptor.isAggregateDescriptor() && 
94
                    !candidateAssignableDescriptor.isAggregateCollectionDescriptor() && // Embeddable
95
                    possibleSubclass.isAssignableFrom(candidateAssignableDescriptor.getJavaClass())) {
96
                // id will be null if this private function was called from evict(class)
97
                if(null == id) {
98
                    // set the invalidationState to -1 in the cache of a type that can be assigned to the class parameter
99
                    // this call will invalidate all assignable subclasses from the level of [cls] in the subtree
100
                    // we could either loop through each aDescriptor.getJavaClass()
101
                    // or
102
                    // let invalidateClass loop for us by passing in the higher [cls]
103
                    getAccessor().invalidateClass(candidateAssignableDescriptor.getJavaClass());
104
                } else {
105
                    // evict the class instance that corresponds to the id
106
                    // initialize the cache of a type that can be assigned to the class parameter
107
                    getAccessor().invalidateObject(createPrimaryKeyFromId(possibleSubclass, id), candidateAssignableDescriptor.getJavaClass());
108
                }
109
            }                
110
        }
111
    }
112
    
113
    /**
50
     * Sets an Object with the id and Class type to be invalid in the cache.
114
     * Sets an Object with the id and Class type to be invalid in the cache.
115
     * If the class is not an Entity or MappedSuperclass (such as an Embeddable or plain java class)
116
     *  - nothing will be evicted  
117
     * @see Cache#evict(Class, Object)
51
     */
118
     */
52
    public void evict(Class cls, Object id) {
119
    public void evict(Class cls, Object id) {
53
        this.emf.verifyOpen();
120
        getEntityManagerFactory().verifyOpen();
54
        this.accessor.invalidateObject(createPrimaryKeyFromId(cls, id), cls);
121
        // the following lookup will return a parent Entity descriptor if called on a MappedSuperclass class
122
        if(null != getSession().getClassDescriptor(cls)) {
123
            getAccessor().invalidateObject(createPrimaryKeyFromId(cls, id), cls);
124
        } else {
125
            // Check each descriptor's javaClass key in the Map of descriptors on the session
126
            // We will search all descriptors and evict all implementing subclasses
127
            evictAssignableEntitySuperclass(cls, id);
128
        }
55
    }
129
    }
56
130
57
    /**
131
    /**
58
     * Sets all instances of the class to be invalid.
132
     * Sets all instances of the class to be invalid.
133
     * Remove the data for entities of the specified class (and its
134
     * subclasses) from the cache.<p>
135
     * @see Cache#evict(Class) 
136
     * @param cls - Entity Class
59
     */
137
     */
60
    public void evict(Class cls) {
138
    public void evict(Class cls) {
61
        this.emf.verifyOpen();
139
        getEntityManagerFactory().verifyOpen();
62
        this.accessor.invalidateClass(cls);
140
        // 248780:UC6,7: MappedSuperclasses(abstract or concrete classes), VariableOneToOne(interfaces) and Embeddable classes are not supported
63
    }
141
        // the following lookup will return a parent Entity descriptor if called on a MappedSuperclass class
64
142
        if(null != getSession().getClassDescriptor(cls)) {
143
            // Invalidate the Entity
144
            getAccessor().invalidateClass(cls);
145
        } else {
146
            evictAssignableEntitySuperclass(cls, null);
147
        }
148
    }    
149
    
65
    /**
150
    /**
66
     * Sets all instances in the cache to be invalid.
151
     * Sets all instances in the cache to be invalid.
152
     * @see Cache#evict(Object)
67
     */
153
     */
68
    public void evictAll() {
154
    public void evictAll() {
69
        this.emf.verifyOpen();
155
        getEntityManagerFactory().verifyOpen();
70
        this.accessor.invalidateAll();
156
        ((Session)getEntityManagerFactory().getServerSession()).getIdentityMapAccessor().invalidateAll();
71
    }
157
    }
72
158
73
    /**
159
    /**
74
     * Return the EclipseLink cache key object from the JPA Id object.
160
     * Return the EclipseLink cache key object from the JPA Id object.
75
     */
161
     */
76
    private Object createPrimaryKeyFromId(Class cls, Object id) {
162
    private Object createPrimaryKeyFromId(Class cls, Object id) {
77
        CMP3Policy policy = (CMP3Policy)this.serversession.getDescriptor(cls).getCMPPolicy();
163
        ClassDescriptor aDescriptor = getSession().getClassDescriptor(cls);
78
        Object primaryKey = policy.createPrimaryKeyFromId(id, this.serversession);
164
        // Check that we have a descriptor associated with the class (Entity or MappedSuperclass)
165
        if(null == aDescriptor) {
166
            // No descriptor found, throw exception for Embeddable or non-persistable java class
167
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage(
168
                    "cache_impl_class_has_no_descriptor_is_not_a_persistent_type", 
169
                    new Object[] {cls}));
170
        }
171
        CMP3Policy aCMP3Policy = (CMP3Policy)aDescriptor.getCMPPolicy();
172
        // The policy is not set if the mapping is natively defined outside of JPA
173
        if(null == aCMP3Policy) {
174
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage(
175
                    "cache_descriptor_has_no_cmppolicy_set_cannot_create_primary_key", 
176
                    new Object[] {cls, aDescriptor, id}));
177
        }
178
        // The primaryKey may be the same object as the id parameter
179
        Object primaryKey = aCMP3Policy.createPrimaryKeyFromId(id, getEntityManagerFactory().getServerSession());
79
        return primaryKey;
180
        return primaryKey;
80
    }
181
    }
81
182
    
82
    /**
183
    /**
83
     * ADVANCED:
184
     * ADVANCED:
84
     * Resets the entire Object cache, and the Query cache.
185
     * Resets the entire Object cache, and the Query cache.
Lines 89-96 Link Here
89
     * if the application knows that it no longer has references to Objects held in the cache.
190
     * if the application knows that it no longer has references to Objects held in the cache.
90
     */
191
     */
91
    public void clear() {
192
    public void clear() {
92
        this.emf.verifyOpen();
193
        getEntityManagerFactory().verifyOpen();
93
        this.accessor.initializeAllIdentityMaps();
194
        getAccessor().initializeAllIdentityMaps();
94
    }
195
    }
95
196
96
    /**
197
    /**
Lines 102-125 Link Here
102
     * are not referenced from other Objects of other classes or from the application.
203
     * are not referenced from other Objects of other classes or from the application.
103
     */
204
     */
104
    public void clear(Class cls) {
205
    public void clear(Class cls) {
105
        this.emf.verifyOpen();
206
        getEntityManagerFactory().verifyOpen();
106
        this.accessor.initializeIdentityMap(cls);
207
        getAccessor().initializeIdentityMap(cls);
107
    }
208
    }
108
209
109
    /**
210
    /**
110
     * Clear all the query caches.
211
     * Clear all the query caches.
111
     */
212
     */
112
    public void clearQueryCache() {
213
    public void clearQueryCache() {
113
        this.emf.verifyOpen();
214
        getEntityManagerFactory().verifyOpen();
114
        this.accessor.clearQueryCache();
215
        getAccessor().clearQueryCache();
115
    }
216
    }
116
217
117
    /**
218
    /**
118
     * Clear the named query cache associated with the query name.
219
     * Clear the named query cache associated with the query name.
119
     */
220
     */
120
    public void clearQueryCache(String queryName) {
221
    public void clearQueryCache(String queryName) {
121
        this.emf.verifyOpen();
222
        getEntityManagerFactory().verifyOpen();
122
        this.accessor.clearQueryCache(queryName);
223
        getAccessor().clearQueryCache(queryName);
123
    }
224
    }
124
225
125
    /**
226
    /**
Lines 128-135 Link Here
128
     * time of the Object and its read time.  The method will return 0 for invalidated Objects.
229
     * time of the Object and its read time.  The method will return 0 for invalidated Objects.
129
     */
230
     */
130
    public long timeToLive(Object object) {
231
    public long timeToLive(Object object) {
131
        this.emf.verifyOpen();
232
        getEntityManagerFactory().verifyOpen();
132
        return this.accessor.getRemainingValidTime(object);
233
        return getAccessor().getRemainingValidTime(object);
133
    }
234
    }
134
235
135
    /**
236
    /**
Lines 137-152 Link Here
137
     * the given Object is valid in the cache.
238
     * the given Object is valid in the cache.
138
     */
239
     */
139
    public boolean isValid(Object object) {
240
    public boolean isValid(Object object) {
140
        this.emf.verifyOpen();
241
        getEntityManagerFactory().verifyOpen();
141
        return this.accessor.isValid(object);
242
        return getAccessor().isValid(object);
142
    }
243
    }
143
244
144
    /**
245
    /**
145
     * Returns true if the Object with the id and Class type is valid in the cache.
246
     * Returns true if the Object with the id and Class type is valid in the cache.
146
     */
247
     */
147
    public boolean isValid(Class cls, Object id) {
248
    public boolean isValid(Class cls, Object id) {
148
        this.emf.verifyOpen();
249
        getEntityManagerFactory().verifyOpen();
149
        return this.accessor.isValid(createPrimaryKeyFromId(cls, id), cls);
250
        return getAccessor().isValid(createPrimaryKeyFromId(cls, id), cls);
150
    }
251
    }
151
252
152
    /**
253
    /**
Lines 154-161 Link Here
154
     * The output of this method will be logged to this persistence unit's SessionLog at SEVERE level.
255
     * The output of this method will be logged to this persistence unit's SessionLog at SEVERE level.
155
     */
256
     */
156
    public void print() {
257
    public void print() {
157
        this.emf.verifyOpen();
258
        getEntityManagerFactory().verifyOpen();
158
        this.accessor.printIdentityMaps();
259
        getAccessor().printIdentityMaps();
159
    }
260
    }
160
261
161
    /**
262
    /**
Lines 163-170 Link Here
163
     * The output of this method will be logged to this persistence unit's SessionLog at SEVERE level.
264
     * The output of this method will be logged to this persistence unit's SessionLog at SEVERE level.
164
     */
265
     */
165
    public void print(Class cls) {
266
    public void print(Class cls) {
166
        this.emf.verifyOpen();
267
        getEntityManagerFactory().verifyOpen();
167
        this.accessor.printIdentityMap(cls);
268
        getAccessor().printIdentityMap(cls);
168
    }
269
    }
169
270
170
    /**
271
    /**
Lines 172-179 Link Here
172
     * The output of this method will be logged to this persistence unit's SessionLog at SEVERE level.
273
     * The output of this method will be logged to this persistence unit's SessionLog at SEVERE level.
173
     */
274
     */
174
    public void printLocks() {
275
    public void printLocks() {
175
        this.emf.verifyOpen();
276
        getEntityManagerFactory().verifyOpen();
176
        this.accessor.printIdentityMapLocks();
277
        getAccessor().printIdentityMapLocks();
177
    }
278
    }
178
279
179
    /**
280
    /**
Lines 183-190 Link Here
183
     * Objects are in a correct state.
284
     * Objects are in a correct state.
184
     */
285
     */
185
    public void validate() {
286
    public void validate() {
186
        this.emf.verifyOpen();
287
        getEntityManagerFactory().verifyOpen();
187
        this.accessor.validateCache();
288
        getAccessor().validateCache();
188
    }
289
    }
189
290
190
    /**
291
    /**
Lines 192-199 Link Here
192
     * and Class type.
293
     * and Class type.
193
     */
294
     */
194
    public Object getObject(Class cls, Object id) {
295
    public Object getObject(Class cls, Object id) {
195
        this.emf.verifyOpen();
296
        getEntityManagerFactory().verifyOpen();
196
        return this.accessor.getFromIdentityMap(createPrimaryKeyFromId(cls, id), cls);
297
        return getAccessor().getFromIdentityMap(createPrimaryKeyFromId(cls, id), cls);
197
    }
298
    }
198
299
199
    /**
300
    /**
Lines 204-211 Link Here
204
     * relationships to other objects.
305
     * relationships to other objects.
205
     */
306
     */
206
    public Object putObject(Object object) {
307
    public Object putObject(Object object) {
207
        this.emf.verifyOpen();
308
        getEntityManagerFactory().verifyOpen();
208
        return this.accessor.putInIdentityMap(object);
309
        return getAccessor().putInIdentityMap(object);
209
    }
310
    }
210
311
211
    /**
312
    /**
Lines 215-222 Link Here
215
     * The application should only call this if its known that no references to the Object exist.
316
     * The application should only call this if its known that no references to the Object exist.
216
     */
317
     */
217
    public Object removeObject(Object object) {
318
    public Object removeObject(Object object) {
218
        this.emf.verifyOpen();
319
        getEntityManagerFactory().verifyOpen();
219
        return this.accessor.removeFromIdentityMap(object);
320
        return getAccessor().removeFromIdentityMap(object);
220
    }
321
    }
221
322
222
    /**
323
    /**
Lines 226-233 Link Here
226
     * The application should only call this if its known that no references to the Object exist.
327
     * The application should only call this if its known that no references to the Object exist.
227
     */
328
     */
228
    public Object removeObject(Class cls, Object id) {
329
    public Object removeObject(Class cls, Object id) {
229
        this.emf.verifyOpen();
330
        getEntityManagerFactory().verifyOpen();
230
        return this.accessor.removeFromIdentityMap(createPrimaryKeyFromId(cls, id), cls);
331
        return getAccessor().removeFromIdentityMap(createPrimaryKeyFromId(cls, id), cls);
231
    }
332
    }
232
333
233
    /**
334
    /**
Lines 239-257 Link Here
239
340
240
    /**
341
    /**
241
     * Sets the object to be invalid in the cache.
342
     * Sets the object to be invalid in the cache.
343
     * @see JpaCache#evict(Object)
242
     */
344
     */
243
    public void evict(Object object) {
345
    public void evict(Object object) {
244
        this.emf.verifyOpen();
346
        getEntityManagerFactory().verifyOpen();
245
        this.accessor.invalidateObject(object);
347
        getAccessor().invalidateObject(object);
246
    }
348
    }
247
349
248
    /**
350
    /**
249
     * Returns the object's Id.
351
     * INTERNAL:
352
     * Return the EntityManagerFactory associated with this CacheImpl.
353
     * @return
250
     */
354
     */
355
    protected EntityManagerFactoryImpl getEntityManagerFactory() {
356
        return this.emf;
357
    }
358
    
359
    /**
360
     * INTERNAL:
361
     * Return the Session associated with the EntityManagerFactory.
362
     * @return
363
     */
364
    protected Session getSession() {
365
        return getEntityManagerFactory().getServerSession();
366
    }
367
368
    /**
369
     * INTERNAL:
370
     * Return the IdentityMapAccessor associated with the session on the EntityManagerFactory on this CacheImpl.
371
     * @return
372
     */
373
    protected IdentityMapAccessor getAccessor() {
374
        return getSession().getIdentityMapAccessor();
375
    }
376
377
    /**
378
     * This method will return the objects's Id.
379
     * If the descriptor associated with the domain object is null - an IllegalArgumentException is thrown.
380
     * If the CMPPolicy associated with the domain object's descriptor is null 
381
     * the Id will be determined using the ObjectBuilder on the descriptor - which may return
382
     * the Id stored in the weaved _persistence_primaryKey field.
383
     * @See {@link JpaCache#getId(Object)}
384
     */
251
    public Object getId(Object object) {
385
    public Object getId(Object object) {
252
        this.emf.verifyOpen();
386
        getEntityManagerFactory().verifyOpen();
253
        ClassDescriptor cdesc = this.serversession.getDescriptor(object.getClass());
387
        ClassDescriptor aDescriptor = getSession().getClassDescriptor(object.getClass());
254
        CMP3Policy policy = (CMP3Policy) (cdesc.getCMPPolicy());
388
        // Handle a null descriptor from a detached entity (closed EntityManager), or the entity exists in another session
255
        return policy.createPrimaryKeyInstance(object, this.serversession);
389
        if(null == aDescriptor) {
256
    }
390
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage(
391
                    "cache_impl_object_has_no_descriptor_is_not_a_persistent_type", 
392
                    new Object[] {object}));
393
        }
394
        
395
        // Handle a null CMPPolicy from a MappedSuperclass
396
        CMP3Policy policy = (CMP3Policy) (aDescriptor.getCMPPolicy());
397
        Object identifier = null;
398
        if(null == policy) {
399
            // the following code gets the key either from the weaved _persistence_primaryKey field or using valueFromObject) if not weaved
400
            identifier = aDescriptor.getObjectBuilder().extractPrimaryKeyFromObject(object, (AbstractSession)getSession());
401
        } else {
402
            // Get identifier via EMF
403
            identifier = getEntityManagerFactory().getIdentifier(object);
404
        }
405
        return identifier;
406
    }    
257
}
407
}
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/EntityManagerFactoryImpl.java (-17 / +25 lines)
Lines 443-453 Link Here
443
        this.shouldValidateExistence = shouldValidateExistence;
443
        this.shouldValidateExistence = shouldValidateExistence;
444
    }
444
    }
445
445
446
    /**
447
     * Access the cache that is associated with the entity manager 
448
     * factory (the "second level cache").
449
     * @return instance of the <code>Cache</code> interface
450
     * @throws IllegalStateException if the entity manager factory has been closed
451
     * @see javax.persistence.EntityManagerFactory#getCache()
452
     * @since Java Persistence 2.0
453
     */
446
    public Cache getCache() {
454
    public Cache getCache() {
447
        verifyOpen();
455
        verifyOpen();
448
        if (myCache == null) {
456
        if (null == myCache) {
449
            ServerSession session = this.getServerSession();
457
            myCache = new CacheImpl(this);
450
            myCache = new CacheImpl(this, session.getIdentityMapAccessor());
451
        }
458
        }
452
        return myCache;
459
        return myCache;
453
    }
460
    }
Lines 542-561 Link Here
542
    }
549
    }
543
550
544
    /**
551
    /**
545
     * Returns the id of the entity. A generated id is not guaranteed to be
546
     * available until after the database insert has occurred. Returns null if
547
     * the entity does not yet have an id
548
     * 
549
     * @param entity
550
     * @return id of the entity
551
     * @throws IllegalStateException
552
     *             if the entity is found not to be an entity.
553
     */
554
    public Object getIdentifier(Object entity) {
555
        return EntityManagerFactoryImpl.getIdentifier(entity, serverSession);
556
    }
557
558
    /**
559
     * Determine the load state of a given persistent attribute of an entity
552
     * Determine the load state of a given persistent attribute of an entity
560
     * belonging to the persistence unit.
553
     * belonging to the persistence unit.
561
     * 
554
     * 
Lines 646-651 Link Here
646
     * @throws IllegalStateException
639
     * @throws IllegalStateException
647
     *             if the entity is found not to be an entity.
640
     *             if the entity is found not to be an entity.
648
     */
641
     */
642
    public Object getIdentifier(Object entity) {
643
        return EntityManagerFactoryImpl.getIdentifier(entity, serverSession);
644
    }
645
    
646
    /**
647
     * Returns the id of the entity. A generated id is not guaranteed to be
648
     * available until after the database insert has occurred. Returns null if
649
     * the entity does not yet have an id
650
     * 
651
     * @param entity
652
     * @return id of the entity
653
     * @throws IllegalStateException
654
     *             if the entity is found not to be an entity.
655
     */
649
    public static Object getIdentifier(Object entity, AbstractSession session) {
656
    public static Object getIdentifier(Object entity, AbstractSession session) {
650
        ClassDescriptor descriptor = session.getDescriptor(entity);
657
        ClassDescriptor descriptor = session.getDescriptor(entity);
651
        if (descriptor == null) {
658
        if (descriptor == null) {
Lines 654-659 Link Here
654
        if (descriptor.getCMPPolicy() != null) {
661
        if (descriptor.getCMPPolicy() != null) {
655
            return descriptor.getCMPPolicy().createPrimaryKeyInstance(entity, session);
662
            return descriptor.getCMPPolicy().createPrimaryKeyInstance(entity, session);
656
        } else {
663
        } else {
664
            // 308950: Alternatively, CacheImpl.getId(entity) handles a null CMPPolicy case for weaved and unweaved domain object
657
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_persistence_util_non_persistent_class ", new Object[] { entity }));
665
            throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_persistence_util_non_persistent_class ", new Object[] { entity }));
658
        }
666
        }
659
    }
667
    }
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/EntityManagerImpl.java (+4 lines)
Lines 1106-1111 Link Here
1106
     * within a transaction.
1106
     * within a transaction.
1107
     */
1107
     */
1108
    public Session getSession() {
1108
    public Session getSession() {
1109
        verifyOpen(); // Throw an IAE if the entityManager is closed
1109
        if (checkForTransaction(false) == null) {
1110
        if (checkForTransaction(false) == null) {
1110
            return this.serverSession.acquireNonSynchronizedUnitOfWork(this.referenceMode);
1111
            return this.serverSession.acquireNonSynchronizedUnitOfWork(this.referenceMode);
1111
        }
1112
        }
Lines 1540-1545 Link Here
1540
    }
1541
    }
1541
1542
1542
    public RepeatableWriteUnitOfWork getActivePersistenceContext(Object txn) {
1543
    public RepeatableWriteUnitOfWork getActivePersistenceContext(Object txn) {
1544
        // Throw IllegalStateException if this entityManager is closed (serverSession is null, isOpen == false)
1545
        verifyOpen();
1546
1543
        // use local uow as it will be local to this EM and not on the txn
1547
        // use local uow as it will be local to this EM and not on the txn
1544
        if (this.extendedPersistenceContext == null || !this.extendedPersistenceContext.isActive()) {
1548
        if (this.extendedPersistenceContext == null || !this.extendedPersistenceContext.isActive()) {
1545
            if(this.connectionPolicy == null) {
1549
            if(this.connectionPolicy == null) {
(-)jpa/org.eclipse.persistence.jpa/src/org/eclipse/persistence/internal/jpa/transaction/EntityTransactionImpl.java (+3 lines)
Lines 45-50 Link Here
45
            throw new IllegalStateException(TransactionException.transactionIsActive().getMessage());
45
            throw new IllegalStateException(TransactionException.transactionIsActive().getMessage());
46
        }
46
        }
47
        
47
        
48
        // Throw IllegalStateException if entityManager is closed
49
        this.wrapper.getEntityManager().verifyOpen();
50
        
48
        // always extended 
51
        // always extended 
49
        this.wrapper.localUOW = this.wrapper.getEntityManager().getActivePersistenceContext(null);
52
        this.wrapper.localUOW = this.wrapper.getEntityManager().getActivePersistenceContext(null);
50
        this.wrapper.localUOW.setShouldTerminateTransaction(false);
53
        this.wrapper.localUOW.setShouldTerminateTransaction(false);

Return to bug 248780