[ 
https://issues.apache.org/jira/browse/OPENJPA-2726?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16350704#comment-16350704
 ] 

Will Dazey commented on OPENJPA-2726:
-------------------------------------

Patch looks good to me

> Under certain conditions an Embeddable can be directly admitted into the 
> Datacache map
> --------------------------------------------------------------------------------------
>
>                 Key: OPENJPA-2726
>                 URL: https://issues.apache.org/jira/browse/OPENJPA-2726
>             Project: OpenJPA
>          Issue Type: Bug
>          Components: kernel
>    Affects Versions: 2.2.2
>            Reporter: Jody Grassel
>            Assignee: Jody Grassel
>            Priority: Major
>             Fix For: 2.2.3
>
>         Attachments: OPENJPA-2726_2.2.x.patch
>
>
> A certain sequence of events can result in an Embeddable object instance, 
> with a null identity, being admitted to the DataCache.  This has a number of 
> consequences, ranging from errors by third party datacache implementations 
> which cannot accept a null key value (which the native OpenJPA datacache impl 
> can), to possible data integrity issues since a null key can refer to any 
> kind of object type (since the regular key includes both
> identity and identity type in its information.)
> Consider the following entities:
> @Entity
> public class LeftHand {
>     @Id private long id;   
>     private String strData;
>     @OneToMany private Collection<RightHand> rhList; 
>     ...
> @Entity
> public class RightHand {
>     @Id private long id; 
>     @Basic private String strData;    
>     @Embedded private EmbeddableData emb;
>     ...
>     
> @Embeddable
> public class EmbeddableData {
>     @Basic private String embeddedString;   
>     @Basic(fetch=FetchType.LAZY) private String lazyEmbeddedString;
> After committing the above entities with filled data, the contents of the L2 
> datacache is as follows:
> this  TestDataCache  (id=42)  
> cm    ConcurrentDataCache$1  (id=43)  
>       [0]     ConcurrentHashMap$Entry  (id=68)        
>               key     LongId  (id=73) 
>               value   DataCachePCDataImpl  (id=74)    
>                       _cache  "default" (id=85)       
>                       _data   Object[4]  (id=88)      
>                               [0]     Long  (id=102)  
>                               [1]     AbstractPCData$ProxyDataList  (id=104)  
>                               [2]     "left hand" (id=110)    
>                               [3]     Long  (id=111)  
>                       _exp    -1      
>                       _fieldImpl      null    
>                       _impl   null    
>                       _loaded BitSet  (id=91) 
>                       _oid    LongId  (id=73) 
>                       _type   Class<T> 
> (org.apache.openjpa.persistence.cache.jpa.model.LeftHand) (id=94)      
>                       _version        Integer  (id=99)        
>       [1]     ConcurrentHashMap$Entry  (id=69)        
>               key     LongId  (id=116)        
>               value   DataCachePCDataImpl  (id=117)   
>                       _cache  "default" (id=85)       
>                       _data   Object[3]  (id=120)     
>                               [0]     DataCachePCDataImpl  (id=125)   
>                                       _cache  "default" (id=85)       
>                                       _data   Object[2]  (id=128)     
>                                               [0]     "Embedded String" 
> (id=130)      
>                                               [1]     "Lazy String" (id=131)  
>                                       _exp    -1      
>                                       _fieldImpl      null    
>                                       _impl   null    
>                                       _loaded BitSet  (id=129)        
>                                       _oid    BrokerImpl$StateManagerId  
> (id=3611)    
>                                       _type   Class<T> 
> (org.apache.openjpa.persistence.cache.jpa.model.EmbeddableData) (id=2336)     
>  
>                                       _version        null    
>                               [1]     Long  (id=126)  
>                               [2]     "right hand" (id=127)   
>                       _exp    -1      
>                       _fieldImpl      null    
>                       _impl   null    
>                       _loaded BitSet  (id=121)        
>                       _oid    LongId  (id=116)        
>                       _type   Class<T> 
> (org.apache.openjpa.persistence.cache.jpa.model.RightHand) (id=122)    
>                       _version        null    
> Here we see that the datacache contains two entries, one for LeftHand, one 
> for RightHand.  Completely expected, and at this point Life is Good.
> After purging the persistence context and L2 cache, a query "SELECT lh from 
> LeftHand lh" is executed, and iterating through its result list yields the 
> following L2 datacache state:
> this  TestDataCache  (id=42)  
> cm    ConcurrentDataCache$1  (id=43)  
>       [0]     ConcurrentHashMap$Entry  (id=3657)      
>               key     LongId  (id=3660)       
>               value   DataCachePCDataImpl  (id=3661)  
>                       _cache  "default" (id=85)       
>                       _data   Object[4]  (id=3662)    
>                               [0]     Long  (id=3665) 
>                               [1]     null    
>                               [2]     "left hand" (id=3666)   
>                               [3]     Long  (id=111)  
>                       _exp    -1      
>                       _fieldImpl      null    
>                       _impl   null    
>                       _loaded BitSet  (id=3667)       
>                       _oid    LongId  (id=3660)       
>                       _type   Class<T> 
> (org.apache.openjpa.persistence.cache.jpa.model.LeftHand) (id=94)      
>                       _version        Long  (id=111)  
>       [1]     ConcurrentHashMap$Entry  (id=3658)      
>               key     null    
>               value   DataCachePCDataImpl  (id=3670)  
>                       _cache  "default" (id=85)       
>                       _data   Object[2]  (id=3671)    
>                               [0]     "Embedded String" (id=3673)     
>                               [1]     "Lazy String" (id=3674) 
>                       _exp    -1      
>                       _fieldImpl      null    
>                       _impl   null    
>                       _loaded BitSet  (id=3675)       
>                       _oid    null    
>                       _type   Class<T> 
> (org.apache.openjpa.persistence.cache.jpa.model.EmbeddableData) (id=2336)     
>  
>                       _version        null    
>       [2]     ConcurrentHashMap$Entry  (id=3659)      
>               key     LongId  (id=3682)       
>               value   DataCachePCDataImpl  (id=3683)  
>                       _cache  "default" (id=85)       
>                       _data   Object[3]  (id=3686)    
>                               [0]     DataCachePCDataImpl  (id=3688)  
>                                       _cache  "default" (id=85)       
>                                       _data   Object[2]  (id=3691)    
>                                               [0]     "Embedded String" 
> (id=3673)     
>                                               [1]     "Lazy String" (id=3674) 
>                                       _exp    -1      
>                                       _fieldImpl      null    
>                                       _impl   null    
>                                       _loaded BitSet  (id=3694)       
>                                       _oid    BrokerImpl$StateManagerId  
> (id=3695)    
>                                       _type   Class<T> 
> (org.apache.openjpa.persistence.cache.jpa.model.EmbeddableData) (id=2336)     
>  
>                                       _version        null    
>                               [1]     Long  (id=3689) 
>                               [2]     "right hand" (id=3690)  
>                       _exp    -1      
>                       _fieldImpl      null    
>                       _impl   null    
>                       _loaded BitSet  (id=3687)       
>                       _oid    LongId  (id=3682)       
>                       _type   Class<T> 
> (org.apache.openjpa.persistence.cache.jpa.model.RightHand) (id=122)    
>                       _version        null    
> A specific sequence of events, requiring the embeddable to contain a lazy 
> loaded field (which forces a ROPStoreManager.load() in the 
> AbstractPCData.toEmbeddedData() path results in the 
> DataCacheStoreManager.load() operation attempting to admit the embeddable 
> into the Datacache as if it was an entity type (object 
> ConcurrentHashMap$Entry(id=3658) at index [1].)  The embeddable has no 
> identity of its own, so is inserted into the cache with a null key value.  
> The OpenJPA datacache impl replaces the null value with an object that 
> represents the null value -- while other datacache implementations attempt to 
> add the key to a regular map instance which results in a NullPointerException.
> The attached patch looks for the attempt to insert a new (embeddable) item 
> into the datacache at updateDataCache() - admission into the datacache is 
> rejected if this condition is met.  I've further modified cacheStateManager() 
> to reject any attempt to admit an entry into the datacache that has a null 
> entity to guard against other unidentified paths which could lead to a 
> similar issue, as a null key identity in a datacache is meaningless.  A unit 
> test has been added to verify that the fix corrects the issue.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to