2016-03-17 4 views
4

Я пытаюсь написать интеграционный тест для приложения Spring Boot. У меня есть модель продукта и GalleryImage. Они связаны друг с другом.Получить org.hibernate.LazyInitializationException в тесте интеграции весной загрузки

public class Product { 
    ... 

    @OneToMany(mappedBy = "product") 
    private List<GalleryImage> galleryImages; 
} 

У меня есть интеграционный тест, как показано ниже:

@Test 
public void testProductAndGalleryImageRelationShip() throws Exception { 
    Product product = productRepository.findOne(1L); 
    List<GalleryImage> galleryImages = product.getGalleryImages(); 
    assertEquals(1, galleryImages.size()); 
} 

Однако, этот тест дает мне LazyInitializationException. Я искал в Google и StackOverFlow, он говорит, что сеанс закрывается после productRepository.findOne (1L), так как galleryImages лениво загружаются, поэтому galleryImages.size() дает мне это исключение.

Я попытался добавить аннотацию @Transactional на тест, но он все еще не работает.

+0

Вы, вероятно, нужно добавить @Transactional на верните свой тест, чтобы исправить это. Но я бы, вероятно, переместил ваш код для обслуживания и добавил аннотацию к методу службы. –

+0

Я попытался добавить @Transactional на тест, это не сработало. Нужно ли добавить некоторую конфигурацию, чтобы включить @Transactional? – Slim

+0

У вас есть «SpringJUnit4ClassRunner» для вашего теста? –

ответ

0

Сессия спящего режима закрыта после следующей строки productRepository.findOne(1L).

Вы можете попробовать сделать Hibernate.initialize(product.getGalleryImages())

public static void initialize(Object proxy) 
        throws HibernateException 

инициализацию Форсировать прокси-сервера или постоянной коллекции. Примечание: это гарантирует только инициализацию прокси-объекта или коллекции; не гарантируется, что элементы INSIDE коллекции будут инициализированы/материализованы.

Чтобы избежать Hibernate.initialize, вы можете создать услугу.

@Service 
@Transactional 
public class ProductService { 

    @Transactional(readOnly = true) 
    public List<GalleryImage> getImages(final long producId) throws Exception { 
     Product product = productRepository.findOne(producId); 
     return product.getGalleryImages(); 
    } 
} 

Если вы используете Spring Data JPA в вас приложений, то динамический искатель является хорошей альтернативой.

-3

Вариант 1

У вас есть интеграционный тест, так что предположение: есть «вид», как и большинство тестов интеграции охватывает весь MVC. Как вы правильно указали, ваша сессия (сеанс Hibernate) закрывается до того, как прокси возвращается в представление по вашей транзакции. Один из способов решения этой проблемы - использовать Open Session In View, чтобы сохранить сеанс открытым до тех пор, пока ответ не будет отображаться в представлении. См. Этот StackOverFlow answer для конфигурации компонента.

Вариант 2

Hibernate использует lazy initialization по умолчанию для всех @OneToMany и @ManyToMany отношений. Другой способ подойти к этой проблеме является установить fetchType в Eager

@OneToMany(mappedBy = "product", fetch = FetchType.EAGER) 
private List<GalleryImage> galleryImages; 

Я не рекомендовал бы второй подход к ситуациям, когда запрос возвращает очень большой набор результатов

Смежные вопросы