Я получаю 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> {
}