Silvio Troia
Silvio Troia

Reputation: 1459

get lazy object with hibernate and JPA

how can I get a lazy object?

for example, I've got a "customer" table and the "request" table then I've build a project using hibernate and JPA.

in the customer table there's a code like this

@OneToMany(cascade = CascadeType.ALL, fetch =FetchType.LAZY , mappedBy = "customer")
public Set<Request> getRequests() {
    return this.requests;
}

so, if from the customer object call the getRequests() method, it's return a empty object because it's lazy.

How can i do to get a lazy object full without use EAGER annotation?

i've seen that my problems depends on the session, because it is close. So, in the server side I need keep open session by JPA. How can I do it?

this is a part of my applicationContext.xml but it doesn't work:

<bean class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean" id="entityManagerFactory">
       <property name="persistenceUnitName" value="gestazPU"/>
   </bean>

   <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
       <property name="entityManagerFactory" ref="entityManagerFactory"/>
   </bean>

   <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />

   <bean id="ebOpenEMinView" class="org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor">
       <property name="entityManagerFactory" ref="entityManagerFactory"/>
   </bean>

   <tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager"/>

   <bean id="TipoTicketDAO" class="it.stasbranger.gestaz.server.dao.impl.TipoTicketDAOImpl">
       <property name="entityManagerFactory" ref="entityManagerFactory" />
   </bean>

Upvotes: 4

Views: 8958

Answers (4)

zawhtut
zawhtut

Reputation: 8561

Loop the set, call getId() or any method of the object. This must be done before the session closed which mean inside a transaction.

Hibernate stand alone version

public Customer getCustomerWithRequest(Integer customerId){
    Session session = HibernateUtil.startTransaction();
    Customer = (Customer) session.get(Customer.class, customerId);
    List<Request> requests = customer.getRequests();
    for(Request rq:requests){
        rq.getId();
    }       
    session.close();
    return customer;
}

Spring/Hibernate|JPA version

@Transaction
public Customer getCustomerWithRequest(Integer customerId){        
    //get the requests and loop in here like above
}

Upvotes: 0

kalyan
kalyan

Reputation: 3106

You may need entityManager or if its a webapplication you can keep the session open by "open session in view" and lazy fetch the objects when required.

Upvotes: 0

Edwin Dalorzo
Edwin Dalorzo

Reputation: 78639

I can only assume you have this problem because you are trying to access the lazily loaded field in a detached entity, right? Otherwise, the JPA provider would have automatically loaded for you.

Only using JPA stuff (not provider-dependent functionality) I can think of two options:

1) You change the fetch type to eager. Since you seem to need the collection in a detached entity perhaps it is best if you make sure it is fully loaded by the time you detach it.

2) Make sure the collection is loaded before you detach the entity. You could simply invoke the getRequests() method in the managed entity before the entity is gotten detached, by this forcing the provider to load it, if it is not already loaded.

For this second alternative, you could use the PersistenceUtil.isLoaded() method to determine if the collection is loaded or not, and based on the state, you can decided whether or not to force the loading of lazily fetch collection.

Upvotes: 1

Bozho
Bozho

Reputation: 597382

Use Hibernate.initialize(lazyCollection) - if the current session is active, the collection will be initialized.

Upvotes: 6

Related Questions