我在spring-boot项目的服务类中得到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> {
}