You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by Paul Copeland <te...@jotobjects.com> on 2009/03/28 20:06:21 UTC

Best practice for LAZY OneToMany

Here is a naive question about a OneToMany relationship.  This is 
probably a basic question.

I have a lazily fetched List.  It might be large and I don't want to 
load it until it is accessed.

In a transaction - If I create and persist a new Entity that is a member 
of the list, I think (is this right?) the new uncommited persistent 
Entity will be loaded into that List when the list is first accessed.  
So I do not need to explicitly call List.add(newEntity) which would 
force the List to be loaded.

But if do access the List for some reason and then create and persist a 
second Entity the List will be out of date unless I explicitly add the 
new Entity to the list.

Hope that makes sense - Perhaps what I am looking for is a way to detect 
if the List has already been fetched before I explicitly call 
List.add(newEntity).

Here are my related Entities (not sure if this is correct or not).  The 
scenario is that I am creating new Members that are members of  the List 
in Master.

@Entity
public class Master implements java.io.Serializable
{
. . .

    @OrderBy
    @OneToMany(mappedBy="master", fetch=FetchType.LAZY,
               cascade={CascadeType.PERSIST,CascadeType.REMOVE})
        private List<Member> members;

    public List<Member> getMembers() { return members; }
}


@Entity
public class Member implements java.io.Serializable
{
    @ManyToOne (optional=false, fetch=FetchType.LAZY,
                cascade=CascadeType.PERSIST)
        private Master master;
}


Re: Best practice for LAZY OneToMany

Posted by Paul Copeland <te...@jotobjects.com>.
Does this sequence of calls satisfy my requirement?  Is there a better way?

Member newMember = new Member(master);
entityManager.persist(newMember);
entityManager.flush();
entityManager.refresh(master); // reloads the list if List has already 
been lazily loaded

Hopefully refresh() does not force the lazily fetched fields to be 
loaded. What is the behavior?

- Paul


On 3/28/2009 2:25 PM, Paul Copeland wrote:
> Hi Catalina -
>
> All of what you said confirms my understanding.
>
> One question I have is will a new Persistent member that has not been 
> flushed in the same transaction be returned  by getMembers()?
>
> My other question is what happens if I create a Member after calling 
> getMembers()?  Will that new Member be returned the next time I call 
> getMembers() if I do not call getMembers().add(newMember)?
>
> - Paul
>
> On 3/28/2009 1:59 PM, catalina wei wrote:
>> Paul,
>> When you get a Master entity into your persistent context, because 
>> "members"
>> is LAZY field it should not be loaded.
>> Persisting a Member entity should not affect this LAZY field unless you
>> access the list by calling getMembers().
>> You must set the "master" field in newly created Member instance  (since
>> optional = false), then persist it. The row inserted into MEMBER 
>> table will
>> have the foreign key value set to the primary key of the MASTER it 
>> belongs
>> to. This persist action should not load its master's "members" list.
>>
>> Catalina
>>
>> On Sat, Mar 28, 2009 at 12:06 PM, Paul Copeland <te...@jotobjects.com> 
>> wrote:
>>
>>  
>>> Here is a naive question about a OneToMany relationship.  This is 
>>> probably
>>> a basic question.
>>>
>>> I have a lazily fetched List.  It might be large and I don't want to 
>>> load
>>> it until it is accessed.
>>>
>>> In a transaction - If I create and persist a new Entity that is a 
>>> member of
>>> the list, I think (is this right?) the new uncommited persistent 
>>> Entity will
>>> be loaded into that List when the list is first accessed.  So I do 
>>> not need
>>> to explicitly call List.add(newEntity) which would force the List to be
>>> loaded.
>>>
>>> But if do access the List for some reason and then create and persist a
>>> second Entity the List will be out of date unless I explicitly add 
>>> the new
>>> Entity to the list.
>>>
>>> Hope that makes sense - Perhaps what I am looking for is a way to 
>>> detect if
>>> the List has already been fetched before I explicitly call
>>> List.add(newEntity).
>>>
>>> Here are my related Entities (not sure if this is correct or not).  The
>>> scenario is that I am creating new Members that are members of  the 
>>> List in
>>> Master.
>>>
>>> @Entity
>>> public class Master implements java.io.Serializable
>>> {
>>> . . .
>>>
>>>   @OrderBy
>>>   @OneToMany(mappedBy="master", fetch=FetchType.LAZY,
>>>              cascade={CascadeType.PERSIST,CascadeType.REMOVE})
>>>       private List<Member> members;
>>>
>>>   public List<Member> getMembers() { return members; }
>>> }
>>>
>>>
>>> @Entity
>>> public class Member implements java.io.Serializable
>>> {
>>>   @ManyToOne (optional=false, fetch=FetchType.LAZY,
>>>               cascade=CascadeType.PERSIST)
>>>       private Master master;
>>> }
>>>
>>>
>>>     
>>
>>   
>
>
>


Re: Best practice for LAZY OneToMany

Posted by Paul Copeland <te...@jotobjects.com>.
Hi Catalina -

All of what you said confirms my understanding.

One question I have is will a new Persistent member that has not been 
flushed in the same transaction be returned  by getMembers()?

My other question is what happens if I create a Member after calling 
getMembers()?  Will that new Member be returned the next time I call 
getMembers() if I do not call getMembers().add(newMember)?

- Paul

On 3/28/2009 1:59 PM, catalina wei wrote:
> Paul,
> When you get a Master entity into your persistent context, because "members"
> is LAZY field it should not be loaded.
> Persisting a Member entity should not affect this LAZY field unless you
> access the list by calling getMembers().
> You must set the "master" field in newly created Member instance  (since
> optional = false), then persist it. The row inserted into MEMBER table will
> have the foreign key value set to the primary key of the MASTER it belongs
> to. This persist action should not load its master's "members" list.
>
> Catalina
>
> On Sat, Mar 28, 2009 at 12:06 PM, Paul Copeland <te...@jotobjects.com> wrote:
>
>   
>> Here is a naive question about a OneToMany relationship.  This is probably
>> a basic question.
>>
>> I have a lazily fetched List.  It might be large and I don't want to load
>> it until it is accessed.
>>
>> In a transaction - If I create and persist a new Entity that is a member of
>> the list, I think (is this right?) the new uncommited persistent Entity will
>> be loaded into that List when the list is first accessed.  So I do not need
>> to explicitly call List.add(newEntity) which would force the List to be
>> loaded.
>>
>> But if do access the List for some reason and then create and persist a
>> second Entity the List will be out of date unless I explicitly add the new
>> Entity to the list.
>>
>> Hope that makes sense - Perhaps what I am looking for is a way to detect if
>> the List has already been fetched before I explicitly call
>> List.add(newEntity).
>>
>> Here are my related Entities (not sure if this is correct or not).  The
>> scenario is that I am creating new Members that are members of  the List in
>> Master.
>>
>> @Entity
>> public class Master implements java.io.Serializable
>> {
>> . . .
>>
>>   @OrderBy
>>   @OneToMany(mappedBy="master", fetch=FetchType.LAZY,
>>              cascade={CascadeType.PERSIST,CascadeType.REMOVE})
>>       private List<Member> members;
>>
>>   public List<Member> getMembers() { return members; }
>> }
>>
>>
>> @Entity
>> public class Member implements java.io.Serializable
>> {
>>   @ManyToOne (optional=false, fetch=FetchType.LAZY,
>>               cascade=CascadeType.PERSIST)
>>       private Master master;
>> }
>>
>>
>>     
>
>   


Re: Best practice for LAZY OneToMany

Posted by catalina wei <ca...@gmail.com>.
Paul,
When you get a Master entity into your persistent context, because "members"
is LAZY field it should not be loaded.
Persisting a Member entity should not affect this LAZY field unless you
access the list by calling getMembers().
You must set the "master" field in newly created Member instance  (since
optional = false), then persist it. The row inserted into MEMBER table will
have the foreign key value set to the primary key of the MASTER it belongs
to. This persist action should not load its master's "members" list.

Catalina

On Sat, Mar 28, 2009 at 12:06 PM, Paul Copeland <te...@jotobjects.com> wrote:

> Here is a naive question about a OneToMany relationship.  This is probably
> a basic question.
>
> I have a lazily fetched List.  It might be large and I don't want to load
> it until it is accessed.
>
> In a transaction - If I create and persist a new Entity that is a member of
> the list, I think (is this right?) the new uncommited persistent Entity will
> be loaded into that List when the list is first accessed.  So I do not need
> to explicitly call List.add(newEntity) which would force the List to be
> loaded.
>
> But if do access the List for some reason and then create and persist a
> second Entity the List will be out of date unless I explicitly add the new
> Entity to the list.
>
> Hope that makes sense - Perhaps what I am looking for is a way to detect if
> the List has already been fetched before I explicitly call
> List.add(newEntity).
>
> Here are my related Entities (not sure if this is correct or not).  The
> scenario is that I am creating new Members that are members of  the List in
> Master.
>
> @Entity
> public class Master implements java.io.Serializable
> {
> . . .
>
>   @OrderBy
>   @OneToMany(mappedBy="master", fetch=FetchType.LAZY,
>              cascade={CascadeType.PERSIST,CascadeType.REMOVE})
>       private List<Member> members;
>
>   public List<Member> getMembers() { return members; }
> }
>
>
> @Entity
> public class Member implements java.io.Serializable
> {
>   @ManyToOne (optional=false, fetch=FetchType.LAZY,
>               cascade=CascadeType.PERSIST)
>       private Master master;
> }
>
>