LazyInitializationException при попытке извлечь дочерние объекты в том же методе внутри класса Spring @Service, аннотированного @Transactional - PullRequest
0 голосов
/ 17 мая 2019

Я получаю org.hibernate.LazyInitializationException в классе обслуживания в моем проекте весенней загрузки. Несмотря на то, что я видел несколько вопросов, касающихся этого исключения, ничего найти не удалось, что схоже с моей ситуацией.

Я пытаюсь загрузить коллекцию дочерних объектов внутри @Transactional аннотированного сервисного метода, как показано ниже.

@Override
public Order addOrderPayment(OrderPaymentRQ form, Integer orderId) {
    Order order = repository.findById(orderId).orElseThrow(EntityNotFoundException::new);
    OrderPayment orderPayment = new OrderPayment();
    BeanUtils.copyProperties(form, orderPayment);
    order.getOrderPayments().add(orderPayment); //Exception thrown at this line
    repository.save(order);
    return order;
}

Особое исключение выдается на order.getOrderPayments().

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

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class OrdersRestControllerTest {

final Integer EDIT_ID = 2;

@Autowired
MockMvc mockMvc;

@Autowired
ObjectMapper mapper;

@Autowired
CarsService carsService;

@Autowired
OrdersService ordersService;

@Test
public void removeOrderPayment() throws Exception {
    OrderPaymentRQ payment = new OrderPaymentRQ();
    payment.setDescription("advance payment");
    BigDecimal amount = BigDecimal.valueOf(2000.50);
    payment.setAmount(amount);
    payment.setPaymentMethod(PaymentMethod.CASH);
    payment.setDate(LocalDate.now());

    Order order = ordersService.findById(EDIT_ID).get();
    ordersService.addOrderPayment(payment, EDIT_ID); //This line causes the exception
    OrderPayment toDelete = ordersService.getOrderPayments(EDIT_ID).get(0);

    MvcResult mvcResult = mockMvc.perform(delete("/orders/" + EDIT_ID + "/orderPayments/" + toDelete.getId()).contentType(MediaType.APPLICATION_JSON))
            .andExpect(status().isCreated())
            .andExpect(jsonPath("$.id", is(EDIT_ID)))
            .andReturn();

    Order orderReturned = mapper.readValue(mvcResult.getResponse().getContentAsString(), Order.class);
    assertEquals(order.getPayments().subtract(toDelete.getAmount()), orderReturned.getPayments());

}
}

Соотношение сущностей выглядит следующим образом (однонаправленное OneToMany).

@Data
@Entity
public class Order implements Serializable{
     @Getter
     @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
     @JoinColumn(name = "order_id", nullable = false)
     @OrderBy("date DESC")
     List<OrderPayment> orderPayments = new ArrayList<>();

     other properties...
}

@Data
@Entity
public class OrderPayment implements Serializable{
    properties...
}

Насколько я понимаю, Транзакция не должна была закрыться на строке, где выдается исключение, поскольку она находится внутри того же метода @Transactional.

Исключение не выдается, когда я аннотирую свой тестовый класс с @Transactional. При этом данные не сохраняются в базе данных, поэтому я не могу гарантировать правильное поведение при производстве.

Не могли бы вы помочь мне выяснить, что я здесь делаю неправильно.

РЕДАКТИРОВАТЬ: Добавлен репозиторий

public interface OrdersRepository extends CustomRepository<Order, Integer> {
}

@NoRepositoryBean
public interface CustomRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>, QuerydslPredicateExecutor<T> {

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