openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paul Copeland <t...@jotobjects.com>
Subject Re: Does OpenJPA replace Collections?
Date Wed, 08 Apr 2009 17:21:40 GMT
Pinaki -

I tried your suggestion of not initializing the value of myPcList and I 
get a null pointer exception when adding to an empty list.

I noticed your example was for Property access and Russell (and I) were 
talking about Field access.  Do you agree that it is necessary to 
initialize an empty list when using Field access?

On Craig's advice to always construct a new ArrayList(), why is that 
necessary instead of just constructing it in the getter when it tests to 
null?  Otherwise you are constructing an ArrayList that is unnecessary 
when the List is NOT empty (usually) and also unnecessary in the case of 
LAZY loading if the List is never accessed (perhaps also a frequent 
case).  In some applications you might create lots of these objects and 
normal optimization is to avoid calling constructors unnecessarily.  
Just want to be clear about whether it is necessary.

- Paul

On 4/8/2009 9:43 AM, Paul Copeland wrote:
> Thanks Pinaki -
>
> I think you are saying that at some point the proxy object does 
> replace the local List.  Is that right?
>
> I have seen that model - if (myPcList == null) myPcList = new 
> ArrayList() - in various examples (not sure where now).  Thanks for 
> clearing that up.  But then Craig Russell contradicts you in his reply 
> (below) where he recommends always initializing the Collection in the 
> constructor (which seems like a performance anti-pattern of wasted 
> constructor calls since usually it will be replaced by the proxy).   
> Are you and Craig saying opposite things here?
>
> In my testing when the List is empty - (myPcList == null) - does 
> indeed evaluate to true.
>
>               getMyPcList().add(new MyPcObject())
>
> Therefore I thought the above would cause a null pointer exception 
> when the List is empty.  You say that won't happen so I'll give it a try!
>
> - Paul
>
>
> On 4/8/2009 3:16 AM, Pinaki Poddar wrote:
>> Hi,
>> According to JPA spec:
>> "If there are no associated entities for a multi-valued relationship 
>> of an entity fetched from the database,
>> the persistence provider is responsible for returning an empty 
>> collection as the value of the relationship."
>>
>> That is what OpenJPA does. So the application do not need to return 
>> an empty list for a null (initialized) list.
>>
>> OpenJPA proxies all returned collections. So application code can 
>> simply do the following
>>
>> // In the domain class
>> private List<MyPcObject> myPcList = null; // never explictly initialized
>>
>> @OneToMany (mappedBy="ownerSide", fetch=FetchType.LAZY,  
>> cascade=CascadeType.PERSIST)
>> public  List<Promotion> getMyPcList()  {
>>       return myPcList; // return as it is
>> }
>>
>> // In the application
>> List<Promotion> list = owner.getMyPcList();
>> assertNotNull(list);
>> assertTrue(java.util.List.class.isInstance(list));
>> assertNotSame(java.util.ArrayList.class, list.getClass());
>> list.add(new MyPcObject());
>> owner.setMyPcList(list);
>>
>>
>>
>>
>> On Apr 7, 2009, at 11:10 PM, Paul Copeland wrote:
>>
>>  
>>> Can OpenJPA replace a Collection when it is loaded?
>>>
>>> With the code below when the list is initially empty you need to  
>>> create a List (ArrayList) so you can add elements to it. When I  
>>> persisted new objects on the ManyToOne side and added them to the  
>>> List that worked.  But the first time the List was loaded it seemed  
>>> to replace my ArrayList with the newly loaded data and made an 
>>> older  reference to the ArrayList stale (no longer updated when 
>>> more  elements were added to myPcList).  This was all in one 
>>> transaction.
>>>
>>> So now I wonder if the initial null List is a special case or if  
>>> OpenJPA might replace the Collection anytime it decides to load it  
>>> again.  Anyone know the answer?
>>>     
>>
>> If the list is persistent and the class is enhanced, the collection  
>> will always reflect what's in the database.
>>  
>>> If I don't create an initial ArrayList how can I add elements when  
>>> the List is empty?
>>>     
>>
>> I'd recommend always having a non-empty list. Initialize it in the  
>> constructor to an empty list and don't check it after that.
>>
>> Here's what it would look like:
>>  
>>>  @OneToMany (mappedBy="ownerSide", fetch=FetchType.LAZY,  
>>> cascade=CascadeType.PERSIST)
>>>  private List<MyPcObject> myPcList = new ArrayList<MyPcObject>();
>>>
>>>  List<Promotion> getMyPcList()
>>>  {
>>>      return myPcList;
>>>  }
>>>
>>>
>>>     
>> Craig
>>  
>> Craig L Russell
>> Architect, Sun Java Enterprise System http://db.apache.org/jdo
>> 408 276-5638 mailto:Craig.Russell@sun.com
>> P.S. A good JDO? O, Gasp!
>>
>>
>>  
>>
>>
>>
>> -----
>> Pinaki Poddar                      http://ppoddar.blogspot.com/
>>                                       
>> http://www.linkedin.com/in/pinakipoddar
>> OpenJPA PMC Member/Committer
>> JPA Expert Group Member
>>   
>
>
>


Mime
View raw message