Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] Lazy loading does not work

I see. It's now a little clearer to me.

Thanks for explaining this.


On Thu, Sep 16, 2010 at 5:48 PM, Tom Ware <tom.ware@xxxxxxxxxx> wrote:
> Detached Objects get the connection need to traverse the LAZY relationship
> from the EntityManagerFactory and will able able to use it as long as the
> EntityManagerFactory is open.  The connection used in not the transactional
> one and when you want to use the entity in a transaction it will have to be
> properly merged.
>
> janne postilista wrote:
>>
>> Can anyone explain how the transactions work in this case?
>>
>> The whole picture is that MDB starts it's own transaction A (default
>> transaction attributes). It calls stateless EJB
>> EmployerService.findAll() which has been defined REQUIRES_NEW, so it
>> runs in another transaction B.
>>
>> findAll() reads Employers from DB in transaction B. After findAll()
>> returns, B is committed.
>>
>> MDB then accesses the detached employers and the persons that have not
>> been loaded yet. This triggers loading of persons with SELECT ... FROM
>> PERSON. Does this happen in transaction A?
>>
>> How does this all really work?
>>
>>
>> On Wed, Sep 15, 2010 at 10:58 AM, janne postilista
>> <jannepostilistat@xxxxxxxxx> wrote:
>>>
>>> Hi,
>>>
>>>  not saying that this is feature is bad, it's just surprising initially.
>>>
>>> Can you still clarify this a bit - since I have defined
>>> EmployerService.findAll() with REQUIRES_NEW, the transaction that
>>> fetched the Employer should be committed and closed at the point where
>>> I am accessing the detached objects, correct? Does eclipseLink create
>>> a new transaction for fetching the persons - one transaction for each
>>> person, or what - how does it actually work?
>>>
>>> On Tue, Sep 14, 2010 at 6:10 PM, Tom Ware <tom.ware@xxxxxxxxxx> wrote:
>>>>
>>>> 1. We choose to allow LAZY relationships to be traversed in detached
>>>> objects
>>>> where possible because we believe this provides a higher level of
>>>> functionality.  In other words... If we have everything we need to
>>>> traverse
>>>> the LAZY relationship, why would be disable the functionality that
>>>> allows
>>>> you to traverse it.
>>>>
>>>> 2. Yes.  EclipseLink uses a 2nd level cache by default.  There are a
>>>> number
>>>> of cache config settings. The following webpage shows a list of the
>>>> caching
>>>> options that are available through JPA config.
>>>>
>>>> http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_%28ELUG%29#Using_EclipseLink_JPA_Extensions_for_Entity_Caching
>>>>
>>>> -Tom
>>>>
>>>> janne postilista wrote:
>>>>>
>>>>> Well, yes, it sure seems like that is happening. Looking at the logs,
>>>>> it seems that eclipselink first loads all Employers without the
>>>>> persons (so lazy loading works)
>>>>>
>>>>>
>>>>>
>>>>> [#|2010-09-14T17:44:32.494+0300|FINE|glassfish3.0.1|org.eclipse.persistence.session.file:/D:/projectszzz/glassfishv3-3/glassfish/domains/test-domai
>>>>>
>>>>>
>>>>> n/applications/services-ear/services-ejb_jar/zzz-pu.sql|_ThreadID=17;_ThreadName=Thread-1;ClassName=null;MethodName=null;|SELECT
>>>>> ID, ZZZ, VERSION FROM EMPLOYER|#]
>>>>>
>>>>>
>>>>>
>>>>> [#|2010-09-14T17:44:32.539+0300|FINER|glassfish3.0.1|org.eclipse.persistence.session.file:/D:/projects/zzz/sandbox/glassfishv3-3/glassfish/domains/test-doma
>>>>>
>>>>>
>>>>> in/applications/services-ear/services-ejb_jar/zzz-pu.transaction|_ThreadID=17;_ThreadName=Thread-1;ClassName=null;MethodName=null;|end
>>>>> unit of work commit|
>>>>> #]
>>>>>
>>>>> then after exiting findAll() I am mapping the entities to JAXB beans
>>>>> and accessing the person references. Eclipselink loads the person from
>>>>> db:
>>>>>
>>>>>
>>>>>
>>>>> [#|2010-09-14T17:44:32.676+0300|FINE|glassfish3.0.1|org.eclipse.persistence.session.file:/D:/projects/zzz/sandbox/glassfishv3-3/glassfish/domains/test-domai
>>>>>
>>>>>
>>>>> n/applications/services-ear/services-ejb_jar/zzz-pu.sql|_ThreadID=17;_ThreadName=Thread-1;ClassName=null;MethodName=null;|SELECT
>>>>> t1.ID, t1.LAST_NAME, t1.TI
>>>>> TLE_SE, ZZZ FROM EMPLOYER_PERSON t0, PERSON t1 WHERE ((t0.E
>>>>> MPLOYER_ID = ?) AND (t1.ID = t0.PERSON_ID))
>>>>>       bind => [20284]|#]
>>>>>
>>>>> 1. This seems counter-intuitive to me....how can Eclipselink fetch the
>>>>> lazy relationships after a) the EJB transaction has already ended and
>>>>> b) the entities have been explicitly detached? That's not at all what
>>>>> I would be assuming
>>>>> 2. If I redo the same method call, Eclipselink logs show that SQL
>>>>> queries go to database to fetch the Employers, but there's no SQL for
>>>>> the persons on the second go. Seems like the persons come from some
>>>>> 2nd level cache or something? How does this work, I haven't configured
>>>>> anything special related to caching? I have also noticed this in
>>>>> practise, in that direct SQL updates to DB are not visible throught
>>>>> the application. Does eclipseLink use 2nd level caching by default?
>>>>>
>>>>>
>>>>> On Tue, Sep 14, 2010 at 4:47 PM, Tom Ware <tom.ware@xxxxxxxxxx> wrote:
>>>>>>
>>>>>> Hi Janne,
>>>>>>
>>>>>>  Where in your code do you see the relationships traversed?  You can
>>>>>> turn
>>>>>> on
>>>>>> EclipseLink logging (persistence unit property:
>>>>>> eclipselink.logging.level=FINEST) to see all of the logging.  When do
>>>>>> you
>>>>>> see the SQL that traverses the relationship?
>>>>>>
>>>>>>  EclipseLink has some functionality that allows LAZY relationships to
>>>>>> be
>>>>>> traversable after detachment if the connection is available.  I am
>>>>>> wondering
>>>>>> if you are seeing that functionality in action.
>>>>>>
>>>>>> -Tom
>>>>>>
>>>>>> janne postilista wrote:
>>>>>>>
>>>>>>> Hi,
>>>>>>>
>>>>>>> I'm using Eclipselink to provide JPA. I'm using GlassFish 3.0.1.
>>>>>>>
>>>>>>> I have a some simple Employer and Person entities with many-to-many
>>>>>>> (using join table) and one-to-many relationships. I want to have the
>>>>>>> relationships lazy loaded, but it looks like they are always eagerly
>>>>>>> loaded. I am aware that lazy/eager is just a hint to the JPA
>>>>>>> implementation, but I'm thinking that lazy loading is probably
>>>>>>> supposed to work with Eclipselink?
>>>>>>>
>>>>>>> Entities are along the lines of (likely irrelevant lines omitted):
>>>>>>>
>>>>>>>
>>>>>>> @Entity
>>>>>>> @NamedQueries({
>>>>>>>  @NamedQuery(name = "Employer.findAllLatest2", query = "select o
>>>>>>> from Employer o"),
>>>>>>> })
>>>>>>> public class Employer implements Serializable {
>>>>>>>  @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
>>>>>>>  @JoinTable(name = "EMPLOYER_PERSON", joinColumns =
>>>>>>>  @JoinColumn(name = "EMPLOYER_ID"), inverseJoinColumns =
>>>>>>>  @JoinColumn(name = "PERSON_ID"))
>>>>>>>  private Set<Person> persons;
>>>>>>>
>>>>>>>  @ManyToOne(fetch = FetchType.LAZY)
>>>>>>>  @JoinColumn(name = "BOSS_ID")
>>>>>>>  private Person boss;
>>>>>>> }
>>>>>>>
>>>>>>> @Entity
>>>>>>> @NamedQueries({
>>>>>>>  @NamedQuery(name = "EmployerPerson.findAll", query = "select o from
>>>>>>> EmployerPerson o")
>>>>>>> })
>>>>>>> @Table(name = "EMPLOYER_PERSON")
>>>>>>> @IdClass(EmployerPersonPK.class)
>>>>>>> public class EmployerPerson implements Serializable {
>>>>>>>  @Id
>>>>>>>  @Column(name="EMPLOYER_ID", nullable = false, insertable = false,
>>>>>>>          updatable = false)
>>>>>>>  private Long employerId;
>>>>>>>  @Id
>>>>>>>  @Column(name="PERSON_ID", nullable = false, insertable = false,
>>>>>>>          updatable = false)
>>>>>>>  private Long personId;
>>>>>>>  @ManyToOne
>>>>>>>  @JoinColumn(name = "EMPLOYER_ID")
>>>>>>>  private Employer employer;
>>>>>>>  @ManyToOne
>>>>>>>  @JoinColumn(name = "PERSON_ID")
>>>>>>>  private Person person;
>>>>>>> }
>>>>>>>
>>>>>>> @Entity
>>>>>>> public class Person implements Serializable {
>>>>>>>  @ManyToMany(mappedBy="persons")
>>>>>>>  private Set<Employer> employers;
>>>>>>>
>>>>>>> @Stateless
>>>>>>> @LocalBean
>>>>>>> @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
>>>>>>> public class EmployerService {
>>>>>>>
>>>>>>>  @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
>>>>>>>  public List<Employer> findAll() {
>>>>>>>      String namedQuery = "Employer.findAllLatest2";
>>>>>>>      }
>>>>>>>      List<Employer> employers = em.createNamedQuery(namedQuery,
>>>>>>> Employer.class).getResultList();
>>>>>>>      for (Employer e: employers) {
>>>>>>>          em.detach(e);
>>>>>>>      }
>>>>>>>      return employers;
>>>>>>>  }
>>>>>>>
>>>>>>> Now, when I use findAll(), I would expect that Employer objects do
>>>>>>> not
>>>>>>> have the person references fecthed. But they are. Accessing persons
>>>>>>> succeeds even though I did add (extraneous) detach() -calls to make
>>>>>>> sure the entities are detached after returning from findAll().
>>>>>>> _______________________________________________
>>>>>>> eclipselink-users mailing list
>>>>>>> eclipselink-users@xxxxxxxxxxx
>>>>>>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>>>>>>
>>>>>> _______________________________________________
>>>>>> eclipselink-users mailing list
>>>>>> eclipselink-users@xxxxxxxxxxx
>>>>>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>>>>>>
>>>>> _______________________________________________
>>>>> eclipselink-users mailing list
>>>>> eclipselink-users@xxxxxxxxxxx
>>>>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>>>>
>>>> _______________________________________________
>>>> eclipselink-users mailing list
>>>> eclipselink-users@xxxxxxxxxxx
>>>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>>>>
>> _______________________________________________
>> eclipselink-users mailing list
>> eclipselink-users@xxxxxxxxxxx
>> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>
> _______________________________________________
> eclipselink-users mailing list
> eclipselink-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/eclipselink-users
>


Back to the top