получить ленивый объект с Hibernate и JPA - PullRequest
3 голосов
/ 31 мая 2011

как мне получить ленивый объект?

например, У меня есть таблица "customer" и таблица "request", а затем я создаю проект, используя hibernate и JPA.

в таблице клиентов есть такой код

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

Итак, если из объекта customer вызвать метод 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 ]

5 голосов
/ 31 мая 2011

Использовать Hibernate.initialize(lazyCollection) - если текущий сеанс активен, коллекция будет инициализирована.

1 голос
/ 31 мая 2011

Я могу только предположить, что у вас есть эта проблема, потому что вы пытаетесь получить доступ к лениво загруженному полю в отдельном объекте, верно? В противном случае поставщик JPA автоматически загрузил бы вас.

Только с использованием JPA (не зависит от поставщика). Я могу представить два варианта:

1) Вы меняете тип выборки на нетерпеливый. Поскольку вам кажется, что коллекция требуется в отдельном объекте, возможно, лучше всего убедиться, что она полностью загружена к моменту ее отсоединения.

2) Убедитесь, что коллекция загружена, прежде чем отсоединять объект. Вы можете просто вызвать метод getRequests () в управляемом объекте до того, как объект будет отсоединен, что заставит провайдера загрузить его, если он еще не загружен.

Для этого второго варианта вы можете использовать метод PersistenceUtil.isLoaded (), чтобы определить, загружена коллекция или нет, и на основании состояния вы можете решить, принудительно ли загружать коллекцию отложенной выборки.

0 голосов
/ 12 августа 2011

Цикл набора, вызов 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
}
0 голосов
/ 12 августа 2011

Вам может понадобиться entityManager или, если это веб-приложение, вы можете оставить сеанс открытым с помощью «открыть сеанс в поле зрения» и лениво извлекать объекты при необходимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...