2015-09-21 1 views
1

Я использую EclipseLink в качестве поставщика JPA в проекте Java SE. Я правильно настроил плетение, чтобы позволить Lazy Loading.JPA + EclipseLink - Lazy Загрузка с закрытым EntityManager

В отличие от Hibernate (который бросает LazyInitializationException), EclipseLink может получить прокси-связь LAZY, даже с закрытым EntityManager. Чтобы запустить этот запрос, он получает новое соединение из пула.

Есть ли какая-то настройка, которая отключает или изменяет поведение этой функции? Мне нужно получить нулевое значение или исключение при попытке получить доступ к выгруженному атрибуту, например, Hibernate.

Пример:

List<Customer> customers = entityManager.createQuery("from Customer c", Customer.class).getResultList(); 
entityManager.close(); // Closing the EntityManager 

for (Customer customer: customers) { 
    customer.getAddress(); // Here EclipseLink executes a query to get the relationship. 
} 

Благодаря.

ответ

0

Образец «jpa session in view» - ваш друг. В основном: во время цикла запроса вы открываете EntityManager (довольно рано или по запросу), не закрывайте в своем коде приложения (весь ленивый элемент может быть извлечен) и автоматизируйте закрытие EM в одной из последних операций.

У меня была идентичная проблема. Лично я использую Wicket, заменить

class MyWebRequestCycle extends RequestCycle { 
... // extract from bigger project 
protected void onEndRequest() { 
     super.onEndRequest(); 
     if (em != null) { 
      if (em instanceof MyEntityManager) { 
       MyEntityManager em2 = (MyEntityManager) em; 
       em2.original.close(); 
      } else 
       em.close(); 
      em = null; 
     } 
} 

}

MyEntityManager является прокси (почти генерироваться в Eclpse) над открыт в ранней стадии EntityManager. И «если» выше - из-за начала приложения, это не является частью нашего обсуждения.

В других рамках в адекватном режиме. Это зависит от тебя.

Ответ имеет два пути: полный контейнер JEE (код программистов ничего не открывает или закрывает EM) и контейнеры сервлетов. Мой ответ на второй.

Примечание: слово сеанс в этом шаблоне не является веб-сеансом или нет сеансом в параметрах ввода параметров JPA-движка. Это только слово;)

+0

Спасибо, но эта модель не решает мою проблему. Мне нужно, чтобы EclipseLink не делал запросы, чтобы возвращать отношения LAZY, мне нужно, чтобы он возвращал значение null. –

+0

Я бы посоветовал против «открытой сессии в поле зрения»: http://blog.jhades.org/open-session-in-view-pattern-pros-and-cons/ https: // блог.frankel.ch/the-opensessioninview-antipattern Это считается антипаттерном в Hibernate, и я сомневаюсь, что EclipseLink считает его намного лучше. –

2

EclipseLink позволяет получить доступ к ленивым отношениям, даже когда EntityManager был закрыт. Такое поведение является специфичным для EclipseLink, а не частью спецификации JPA.

Вы получите Исключение, которое вы ищете, когда соединение было закрыто.

Однако EclipseLink обертывает неконвертированные списки в IndirectList. Вы можете проверить программно, если экземпляр List был создан или нет.

if(customers instanceof IndirectList) { 
    boolean foo = ((IndirectList) customers).isInstantiated(); 
    // ... 
} 

Смотрите также:

+0

Спасибо, но в моем случае это отношения ManyToOne. Я попытался проверить метод Persistence.getPersistenceUtil(). IsLoaded(), но не работал. –