【问题标题】:get lazy object with hibernate and JPA使用休眠和 JPA 获取惰性对象
【发布时间】:2011-05-31 17:39:17
【问题描述】:

如何获得惰性对象?

例如, 我有一个“客户”表和一个“请求”表,然后我使用 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>

【问题讨论】:

    标签: hibernate jpa


    【解决方案1】:

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

    【讨论】:

    • 但当前会话未激活!我怎样才能使当前会话保持活动状态??
    【解决方案2】:

    我只能假设您遇到此问题是因为您试图访问分离实体中延迟加载的字段,对吗?否则,JPA 提供程序会自动为您加载。

    仅使用 JPA 的东西(不依赖于提供程序的功能)我可以想到两个选项:

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

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

    对于第二种选择,您可以使用 PersistenceUtil.isLoaded() 方法来确定集合是否已加载,并根据状态决定是否强制加载延迟获取集合。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 我提出了我的 applicationContext.xml 的问题
      【解决方案4】:

      循环集合,调用 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
      }
      

      【讨论】:

      • 我试过了,但是不行,当我调用请求方法时它会得到一个lazyInizializationExeption,我想是因为之前会话关闭了
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-02
      • 2015-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多