View | Details | Raw Unified | Return to bug 395939
Collapse All | Expand All

(-)a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/indirection/IndirectionPolicy.java (+10 lines)
Lines 248-253 public abstract class IndirectionPolicy implements Cloneable, Serializable { Link Here
248
        return true;
248
        return true;
249
    }
249
    }
250
    
250
    
251
    public boolean isAllowRefreshOfUnitOfWorkValueHolder(Object object){
252
        return true;
253
    }
254
    
251
    /**
255
    /**
252
     * INTERNAL:
256
     * INTERNAL:
253
     * Initialize the indirection policy (Do nothing by default)
257
     * Initialize the indirection policy (Do nothing by default)
Lines 352-357 public abstract class IndirectionPolicy implements Cloneable, Serializable { Link Here
352
        setRealAttributeValueInObject(target, attributeValue);
356
        setRealAttributeValueInObject(target, attributeValue);
353
    }
357
    }
354
    
358
    
359
    
360
    public void setAllowRefreshOfUnitOfWorkValueHolder(Object object, boolean refreshRequired){
361
    }
362
    
363
    
355
    /**
364
    /**
356
     * INTERNAL:
365
     * INTERNAL:
357
     * set the source object into QueryBasedValueHolder.
366
     * set the source object into QueryBasedValueHolder.
Lines 389-394 public abstract class IndirectionPolicy implements Cloneable, Serializable { Link Here
389
    public Boolean shouldUseLazyInstantiation() {
398
    public Boolean shouldUseLazyInstantiation() {
390
        return false;
399
        return false;
391
    }
400
    }
401
392
    /**
402
    /**
393
     * Reset the wrapper used to store the value.
403
     * Reset the wrapper used to store the value.
394
     * This is only required if a wrapper is used.
404
     * This is only required if a wrapper is used.
(-)a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/indirection/TransparentIndirectionPolicy.java (+22 lines)
Lines 400-405 public class TransparentIndirectionPolicy extends IndirectionPolicy { Link Here
400
        return attributeValue != null;
400
        return attributeValue != null;
401
    }
401
    }
402
402
403
    public boolean isAllowRefreshOfUnitOfWorkValueHolder(Object object){
404
        if (object instanceof IndirectContainer) {
405
            ValueHolderInterface valueHolder = ((IndirectContainer)object).getValueHolder();
406
            if (valueHolder instanceof UnitOfWorkValueHolder) {
407
                return ((UnitOfWorkValueHolder)valueHolder).isAllowRefresh();
408
            }
409
        }
410
        return true;
411
    }
412
    
403
    public Boolean getUseLazyInstantiation() {
413
    public Boolean getUseLazyInstantiation() {
404
        return useLazyInstantiation;
414
        return useLazyInstantiation;
405
    }
415
    }
Lines 440-445 public class TransparentIndirectionPolicy extends IndirectionPolicy { Link Here
440
        super.setRealAttributeValueInObject(target, attributeValue);
450
        super.setRealAttributeValueInObject(target, attributeValue);
441
    }
451
    }
442
    
452
    
453
    @Override
454
    public void setAllowRefreshOfUnitOfWorkValueHolder(Object object, boolean refreshRequired){
455
        if (object instanceof IndirectContainer) {
456
            ValueHolderInterface valueHolder = ((IndirectContainer)object).getValueHolder();
457
            if (valueHolder instanceof UnitOfWorkValueHolder) {
458
                ((UnitOfWorkValueHolder)valueHolder).setAllowRefresh(refreshRequired);
459
            }
460
        }
461
        
462
    }
463
    
443
    /**
464
    /**
444
     * INTERNAL:
465
     * INTERNAL:
445
     * set the source object into QueryBasedValueHolder.
466
     * set the source object into QueryBasedValueHolder.
Lines 552-557 public class TransparentIndirectionPolicy extends IndirectionPolicy { Link Here
552
        return objectIsInstantiated(object) || ((object instanceof IndirectCollection) && ((IndirectCollection)object).hasDeferredChanges());
573
        return objectIsInstantiated(object) || ((object instanceof IndirectCollection) && ((IndirectCollection)object).hasDeferredChanges());
553
    }
574
    }
554
575
576
    
555
    /**
577
    /**
556
     * ADVANCED:
578
     * ADVANCED:
557
     * Set the size to of container to create.  Default to using default constructor.
579
     * Set the size to of container to create.  Default to using default constructor.
(-)a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/indirection/UnitOfWorkValueHolder.java (+30 lines)
Lines 18-23 import org.eclipse.persistence.descriptors.ClassDescriptor; Link Here
18
import org.eclipse.persistence.exceptions.ValidationException;
18
import org.eclipse.persistence.exceptions.ValidationException;
19
import org.eclipse.persistence.indirection.*;
19
import org.eclipse.persistence.indirection.*;
20
import org.eclipse.persistence.mappings.*;
20
import org.eclipse.persistence.mappings.*;
21
import org.eclipse.persistence.queries.ObjectLevelReadQuery;
21
import org.eclipse.persistence.internal.sessions.remote.RemoteValueHolder;
22
import org.eclipse.persistence.internal.sessions.remote.RemoteValueHolder;
22
import org.eclipse.persistence.internal.sessions.AbstractSession;
23
import org.eclipse.persistence.internal.sessions.AbstractSession;
23
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
24
import org.eclipse.persistence.internal.sessions.UnitOfWorkImpl;
Lines 56-61 public abstract class UnitOfWorkValueHolder extends DatabaseValueHolder implemen Link Here
56
    protected transient Object relationshipSourceObject;
57
    protected transient Object relationshipSourceObject;
57
    protected String sourceAttributeName;
58
    protected String sourceAttributeName;
58
    protected ObjID wrappedValueHolderRemoteID;
59
    protected ObjID wrappedValueHolderRemoteID;
60
    
61
    /**
62
     * Determine whether a refresh should be allowed on this valueholder during a cascade.
63
     * Refresh is allowed when in the same UnitOfWork as the initial refresh was called on
64
     */
65
    protected boolean allowRefresh = false;
59
66
60
    protected UnitOfWorkValueHolder(ValueHolderInterface attributeValue, Object clone, DatabaseMapping mapping, UnitOfWorkImpl unitOfWork) {
67
    protected UnitOfWorkValueHolder(ValueHolderInterface attributeValue, Object clone, DatabaseMapping mapping, UnitOfWorkImpl unitOfWork) {
61
        this.wrappedValueHolder = attributeValue;
68
        this.wrappedValueHolder = attributeValue;
Lines 149-154 public abstract class UnitOfWorkValueHolder extends DatabaseValueHolder implemen Link Here
149
                        }
156
                        }
150
                        unitOfWork.log(SessionLog.FINEST, SessionLog.TRANSACTION, "instantiate_pl_relationship");
157
                        unitOfWork.log(SessionLog.FINEST, SessionLog.TRANSACTION, "instantiate_pl_relationship");
151
                    }
158
                    }
159
               /*     if (!isAllowRefresh() && wrapped instanceof QueryBasedValueHolder){
160
                        QueryBasedValueHolder qbvh = ((QueryBasedValueHolder)wrapped);
161
                        if (qbvh.getQuery().isObjectLevelReadQuery()){
162
                            ((ObjectLevelReadQuery)qbvh.getQuery()).setShouldRefreshIdentityMapResult(false);
163
                        }
164
                    }*/
152
                    if (unitOfWork.getCommitManager().isActive() || unitOfWork.wasTransactionBegunPrematurely()) {
165
                    if (unitOfWork.getCommitManager().isActive() || unitOfWork.wasTransactionBegunPrematurely()) {
153
                        // At this point the wrapped valueholder is not triggered,
166
                        // At this point the wrapped valueholder is not triggered,
154
                        // and we are in transaction.  So just trigger the
167
                        // and we are in transaction.  So just trigger the
Lines 162-167 public abstract class UnitOfWorkValueHolder extends DatabaseValueHolder implemen Link Here
162
    }
175
    }
163
176
164
    /**
177
    /**
178
     * Determine whether a refresh should be allowed on this valueholder during a cascade.
179
     * Refresh is allowed when in the same UnitOfWork as the initial refresh was called on
180
     */
181
    public boolean isAllowRefresh() {
182
        return allowRefresh;
183
    }
184
185
    
186
    /**
165
     * INTERNAL:
187
     * INTERNAL:
166
     * Answers if this valueholder is easy to instantiate.
188
     * Answers if this valueholder is easy to instantiate.
167
     * @return true if getValue() won't trigger a database read.
189
     * @return true if getValue() won't trigger a database read.
Lines 268-273 public abstract class UnitOfWorkValueHolder extends DatabaseValueHolder implemen Link Here
268
        //do nothing.  nothing should be reset to null;
290
        //do nothing.  nothing should be reset to null;
269
    }
291
    }
270
292
293
    /**
294
     * Set whether a refresh should be allowed on this valueholder during a cascade.
295
     * Refresh is allowed when in the same UnitOfWork as the initial refresh was called on
296
     */
297
    public void setAllowRefresh(boolean allowRefresh) {
298
        this.allowRefresh = allowRefresh;
299
    }
300
    
271
    public void setBackupValueHolder(ValueHolder backupValueHolder) {
301
    public void setBackupValueHolder(ValueHolder backupValueHolder) {
272
        this.backupValueHolder = backupValueHolder;
302
        this.backupValueHolder = backupValueHolder;
273
    }
303
    }
(-)a/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/mappings/CollectionMapping.java (-16 / +25 lines)
Lines 280-303 public abstract class CollectionMapping extends ForeignReferenceMapping implemen Link Here
280
     */
280
     */
281
    public Object buildElementUnitOfWorkClone(Object element, Object parent, Integer refreshCascade, UnitOfWorkImpl unitOfWork, boolean isExisting, boolean isFromSharedCache) {
281
    public Object buildElementUnitOfWorkClone(Object element, Object parent, Integer refreshCascade, UnitOfWorkImpl unitOfWork, boolean isExisting, boolean isFromSharedCache) {
282
        // optimize registration to knowledge of existence
282
        // optimize registration to knowledge of existence
283
        if (refreshCascade != null ){
283
        if (refreshCascade != null){
284
            switch(refreshCascade){
284
            Object attributeValue = getAttributeValueFromObject(parent);
285
            case ObjectBuildingQuery.CascadeAllParts : 
285
            if (getIndirectionPolicy().isAllowRefreshOfUnitOfWorkValueHolder(attributeValue)){
286
                return unitOfWork.mergeClone(element, MergeManager.CASCADE_ALL_PARTS, true);
286
                Object returnValue = null;
287
            case ObjectBuildingQuery.CascadePrivateParts :
287
                switch(refreshCascade){
288
                return unitOfWork.mergeClone(element, MergeManager.CASCADE_PRIVATE_PARTS, true);
288
                case ObjectBuildingQuery.CascadeAllParts : 
289
            case ObjectBuildingQuery.CascadeByMapping :
289
                    returnValue = unitOfWork.mergeClone(element, MergeManager.CASCADE_ALL_PARTS, true);
290
                return unitOfWork.mergeClone(element, MergeManager.CASCADE_BY_MAPPING, true);
290
                case ObjectBuildingQuery.CascadePrivateParts :
291
            default:
291
                    returnValue =  unitOfWork.mergeClone(element, MergeManager.CASCADE_PRIVATE_PARTS, true);
292
                return unitOfWork.mergeClone(element, MergeManager.NO_CASCADE, true);
292
                case ObjectBuildingQuery.CascadeByMapping :
293
            }
293
                    returnValue =  unitOfWork.mergeClone(element, MergeManager.CASCADE_BY_MAPPING, true);
294
        }else{
294
                default:
295
            if (isExisting) {
295
                    returnValue =  unitOfWork.mergeClone(element, MergeManager.NO_CASCADE, true);
296
                return unitOfWork.registerExistingObject(element, isFromSharedCache);
296
                }
297
            } else {// not known whether existing or not
297
                getIndirectionPolicy().setAllowRefreshOfUnitOfWorkValueHolder(attributeValue, false);
298
                return unitOfWork.registerObject(element);
298
                return returnValue;
299
            }
299
            }
300
        }
300
        }
301
        if (isExisting) {
302
            return unitOfWork.registerExistingObject(element, isFromSharedCache);
303
        } else {// not known whether existing or not
304
            return unitOfWork.registerObject(element);
305
        }
301
    }
306
    }
302
307
303
    /**
308
    /**
Lines 1456-1461 public abstract class CollectionMapping extends ForeignReferenceMapping implemen Link Here
1456
                    Object clonedAttributeValue = this.indirectionPolicy.cloneAttribute(attributeValue, source, null, target, null, mergeManager.getSession(), false); // building clone from an original not a row. 
1461
                    Object clonedAttributeValue = this.indirectionPolicy.cloneAttribute(attributeValue, source, null, target, null, mergeManager.getSession(), false); // building clone from an original not a row. 
1457
                    setAttributeValueInObject(target, clonedAttributeValue);
1462
                    setAttributeValueInObject(target, clonedAttributeValue);
1458
                }
1463
                }
1464
                if (!isAttributeValueInstantiated(target)){
1465
                    Object attributeValue = getAttributeValueFromObject(target);
1466
                    getIndirectionPolicy().setAllowRefreshOfUnitOfWorkValueHolder(attributeValue, true);
1467
                }
1459
                
1468
                
1460
                // This will occur when the clone's value has not been instantiated yet and we do not need
1469
                // This will occur when the clone's value has not been instantiated yet and we do not need
1461
                // the refresh that attribute
1470
                // the refresh that attribute
(-)a/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/models/jpa/relationships/Order.java (-1 / +1 lines)
Lines 154-160 public class Order implements java.io.Serializable { Link Here
154
        this.billedCustomer = billedCustomer; 
154
        this.billedCustomer = billedCustomer; 
155
    }
155
    }
156
    
156
    
157
    @ManyToOne(fetch=LAZY)
157
    @ManyToOne(fetch=LAZY, cascade=CascadeType.ALL)
158
    public SalesPerson getSalesPerson() {
158
    public SalesPerson getSalesPerson() {
159
        return salesPerson;
159
        return salesPerson;
160
    }
160
    }
(-)a/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/advanced/EntityManagerJUnitTestSuite.java (-32 / +33 lines)
Lines 12259-12299 public class EntityManagerJUnitTestSuite extends JUnitTestCase { Link Here
12259
    
12259
    
12260
    // Bug 384607
12260
    // Bug 384607
12261
    public void testReplaceElementCollection(){
12261
    public void testReplaceElementCollection(){
12262
    	EntityManager em = createEntityManager();
12262
        EntityManager em = createEntityManager();
12263
    	beginTransaction(em);
12263
        beginTransaction(em);
12264
    	Golfer golfer = new Golfer();
12264
        Golfer golfer = new Golfer();
12265
    	GolferPK pk = new GolferPK(102);
12265
        GolferPK pk = new GolferPK(102);
12266
    	WorldRank rank = new WorldRank();
12266
       WorldRank rank = new WorldRank();
12267
    	rank.setId(102);
12267
       rank.setId(102);
12268
    	golfer.setWorldRank(rank);
12268
       golfer.setWorldRank(rank);
12269
    	golfer.getSponsorDollars().put("Oracle", 10000);
12269
       golfer.getSponsorDollars().put("Oracle", 10000);
12270
    	golfer.setGolferPK(pk);
12270
       golfer.setGolferPK(pk);
12271
    	em.persist(golfer);
12271
       em.persist(golfer);
12272
    	em.persist(rank);
12272
       em.persist(rank);
12273
    	em.flush();
12273
       em.flush();
12274
12274
12275
    	golfer = em.find(Golfer.class, golfer.getGolferPK());
12275
       golfer = em.find(Golfer.class, golfer.getGolferPK());
12276
    	golfer.getSponsorDollars().put("Callaway", 20000);
12276
       golfer.getSponsorDollars().put("Callaway", 20000);
12277
    	em.flush();
12277
       em.flush();
12278
    	
12278
       
12279
    	clearCache();
12279
       clearCache();
12280
    	em.clear();
12280
       em.clear();
12281
    	
12281
    
12282
    	golfer = em.find(Golfer.class, golfer.getGolferPK());
12282
       golfer = em.find(Golfer.class, golfer.getGolferPK());
12283
    	assertTrue("Incorrect Number of sponsors", golfer.getSponsorDollars().size() == 2);
12283
       assertTrue("Incorrect Number of sponsors", golfer.getSponsorDollars().size() == 2);
12284
    	assertTrue("Missing Sponsor: Callaway", golfer.getSponsorDollars().get("Callaway").equals(20000));
12284
       assertTrue("Missing Sponsor: Callaway", golfer.getSponsorDollars().get("Callaway").equals(20000));
12285
    	assertTrue("Missing Sponsor: Oracle", golfer.getSponsorDollars().get("Oracle").equals(10000));
12285
       assertTrue("Missing Sponsor: Oracle", golfer.getSponsorDollars().get("Oracle").equals(10000));
12286
12286
12287
    	golfer = em.find(Golfer.class, golfer.getGolferPK());
12287
       golfer = em.find(Golfer.class, golfer.getGolferPK());
12288
    	golfer.setSponsorDollars(new HashMap<String, Integer>());
12288
       golfer.setSponsorDollars(new HashMap<String, Integer>());
12289
    	em.flush();
12289
       em.flush();
12290
    	
12290
    	
12291
    	clearCache();
12291
       clearCache();
12292
    	em.clear();
12292
       em.clear();
12293
    	
12293
    	
12294
    	golfer = em.find(Golfer.class, golfer.getGolferPK());
12294
       golfer = em.find(Golfer.class, golfer.getGolferPK());
12295
    	assertTrue("Incorrect Number of sponsors", golfer.getSponsorDollars().size() == 0);
12295
       assertTrue("Incorrect Number of sponsors", golfer.getSponsorDollars().size() == 0);
12296
    	
12296
    	
12297
    	rollbackTransaction(em);
12297
       rollbackTransaction(em);
12298
    }
12298
    }
12299
    
12299
}
12300
}
(-)a/jpa/eclipselink.jpa.test/src/org/eclipse/persistence/testing/tests/jpa/relationships/RelationshipModelJUnitTestSuite.java (-1 / +35 lines)
Lines 15-20 Link Here
15
 ******************************************************************************/
15
 ******************************************************************************/
16
package org.eclipse.persistence.testing.tests.jpa.relationships;
16
package org.eclipse.persistence.testing.tests.jpa.relationships;
17
17
18
import java.util.ArrayList;
18
import java.util.Iterator;
19
import java.util.Iterator;
19
import java.util.Collection;
20
import java.util.Collection;
20
import java.util.HashMap;
21
import java.util.HashMap;
Lines 61-70 import org.eclipse.persistence.testing.models.jpa.relationships.OrderLabel; Link Here
61
import org.eclipse.persistence.testing.models.jpa.relationships.RelationshipsExamples;
62
import org.eclipse.persistence.testing.models.jpa.relationships.RelationshipsExamples;
62
import org.eclipse.persistence.testing.models.jpa.relationships.RelationshipsTableManager;
63
import org.eclipse.persistence.testing.models.jpa.relationships.RelationshipsTableManager;
63
import org.eclipse.persistence.testing.models.jpa.relationships.Order;
64
import org.eclipse.persistence.testing.models.jpa.relationships.Order;
65
import org.eclipse.persistence.testing.models.jpa.relationships.SalesPerson;
64
import org.eclipse.persistence.testing.models.jpa.relationships.ServiceCall;
66
import org.eclipse.persistence.testing.models.jpa.relationships.ServiceCall;
65
import org.eclipse.persistence.testing.models.jpa.relationships.TestInstantiationCopyPolicy;
67
import org.eclipse.persistence.testing.models.jpa.relationships.TestInstantiationCopyPolicy;
66
68
67
import org.eclipse.persistence.testing.models.jpa.relationships.Customer;
69
import org.eclipse.persistence.testing.models.jpa.relationships.Customer;
70
import org.eclipse.persistence.testing.tests.jpa.advanced.EntityManagerJUnitTestSuite;
68
71
69
public class RelationshipModelJUnitTestSuite extends JUnitTestCase {
72
public class RelationshipModelJUnitTestSuite extends JUnitTestCase {
70
    private static Integer itemId;
73
    private static Integer itemId;
Lines 82-87 public class RelationshipModelJUnitTestSuite extends JUnitTestCase { Link Here
82
        suite.setName("RelationshipModelJUnitTestSuite");
85
        suite.setName("RelationshipModelJUnitTestSuite");
83
        
86
        
84
        suite.addTest(new RelationshipModelJUnitTestSuite("testSetup")); 
87
        suite.addTest(new RelationshipModelJUnitTestSuite("testSetup")); 
88
        suite.addTest(new RelationshipModelJUnitTestSuite("testMergeWithRefresh"));
85
        suite.addTest(new RelationshipModelJUnitTestSuite("testCreateItem")); 
89
        suite.addTest(new RelationshipModelJUnitTestSuite("testCreateItem")); 
86
        suite.addTest(new RelationshipModelJUnitTestSuite("testModifyItem"));
90
        suite.addTest(new RelationshipModelJUnitTestSuite("testModifyItem"));
87
        suite.addTest(new RelationshipModelJUnitTestSuite("testVerifyItem"));
91
        suite.addTest(new RelationshipModelJUnitTestSuite("testVerifyItem"));
Lines 99-104 public class RelationshipModelJUnitTestSuite extends JUnitTestCase { Link Here
99
        suite.addTest(new RelationshipModelJUnitTestSuite("testNamedQueryDoesNotExistTest"));
103
        suite.addTest(new RelationshipModelJUnitTestSuite("testNamedQueryDoesNotExistTest"));
100
        suite.addTest(new RelationshipModelJUnitTestSuite("testExcludeDefaultMappings"));
104
        suite.addTest(new RelationshipModelJUnitTestSuite("testExcludeDefaultMappings"));
101
        suite.addTest(new RelationshipModelJUnitTestSuite("testChangeSetForNewObject"));
105
        suite.addTest(new RelationshipModelJUnitTestSuite("testChangeSetForNewObject"));
106
        suite.addTest(new RelationshipModelJUnitTestSuite("testMergeWithRefresh"));
102
        
107
        
103
        return suite;
108
        return suite;
104
    }
109
    }
Lines 834-838 public class RelationshipModelJUnitTestSuite extends JUnitTestCase { Link Here
834
            commitTransaction(em);
839
            commitTransaction(em);
835
        }
840
        }
836
    }
841
    }
842
    
843
    // Bug 
844
    public void testMergeWithRefresh(){
845
        EntityManager em = createEntityManager();
846
        beginTransaction(em);
847
        SalesPerson sp = new SalesPerson();
848
        sp.setName("Kris");
849
        em.persist(sp);
850
        Order order = new Order();
851
        order.setQuantity(1);
852
        em.persist(order);
853
        sp.getOrders().add(order);
854
        order.setSalesPerson(sp);
855
        em.flush();
856
        
857
        em.refresh(sp);
858
        
859
        em.clear();
860
        
861
        order.setQuantity(2);
862
        sp.setOrders(new ArrayList<Order>());
863
        sp.getOrders().add(order);;
864
        order.setSalesPerson(sp);
865
        
866
        order = em.merge(order);
867
        
868
        assertTrue("Wrong quantity in Order.", order.getQuantity() == 2);
869
        
870
        rollbackTransaction(em);
871
    }
837
872
838
}
873
}
839
- 

Return to bug 395939