使用hibernate和JPA获取惰性对象

时间:2011-05-31 17:39:18

标签: hibernate jpa

我怎样才能得到一个懒惰的对象?

例如,

我有一个“客户”表和“请求”表,然后我使用hibernate和JPA构建了一个项目。

客户表中的

就是这样的代码

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

所以,如果从客户对象调用getRequests()方法,它会返回一个空对象,因为它是懒惰的。

如何在不使用EAGER注释的情况下使惰性对象变满?

我已经看到我的问题取决于会话,因为它很接近。因此,在服务器端,我需要通过JPA保持开放会话。 我该怎么办?

这是我的applicationContext.xml的一部分,但它不起作用:

<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>

4 个答案:

答案 0 :(得分:5)

使用Hibernate.initialize(lazyCollection) - 如果当前会话处于活动状态,则会初始化集合。

答案 1 :(得分:1)

我只能假设你有这个问题因为你试图访问一个分离实体中的延迟加载字段,对吧?否则,JPA提供程序将自动为您加载。

仅使用JPA内容(不依赖于提供程序的功能)我可以考虑两个选项:

1)您将获取类型更改为急切。由于您似乎需要在分离的实体中使用该集合,因此最好是在分离时确保它已完全加载。

2)确保在分离实体之前加载了集合。您可以在实体被分离之前调用托管实体中的getRequests()方法,这会强制提供程序加载它(如果尚未加载)。

对于第二种替代方法,您可以使用PersistenceUtil.isLoaded()方法来确定是否加载了集合,并且根据状态,您可以决定是否强制加载lazily fetch集合。 / p>

答案 2 :(得分:0)

您可能需要entityManager或者如果是web应用程序,您可以通过"open session in view"保持会话打开,并在需要时延迟获取对象。

答案 3 :(得分:0)

循环集合,调用getId()或对象的任何方法。这必须在会话结束之前完成,这意味着在交易中。

Hibernate独立版

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版

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