如果它是@Transactional,则Delete方法不会影响数据库

时间:2019-06-30 16:14:10

标签: java spring-boot transactions modelmapper

我有这个简单的方法可以从数据库中删除条目。 在添加@Transactional批注之前,它一直运行良好。 在这种情况下,装饰会照常完成,但不会删除对象。

如果我删除@Transactional批注或ModelMapper,它将按预期工作。 (http://modelmapper.org/)。 而且我没有看到任何抛出的异常会向我解释回滚

请原谅我忽略代码中的一些最佳做法。我只是

这不起作用,不会影响数据库。

@Transactional
public JsonTrain delete(Long id) {
   Wagon wagon = wagonRepository.getOne(id);
   isSafeForDelete(wagon);
   wagonRepository.delete(wagon);
   return modelMapper.map(wagon.getTrain(), JsonTrain.class);
}

这有效:

public JsonTrain delete(Long id) {
   Wagon wagon = wagonRepository.getOne(id);
   isSafeForDelete(wagon);
   wagonRepository.delete(wagon);
   return modelMapper.map(wagon.getTrain(), JsonTrain.class);
}

这有效

@Transactional
public void delete(Long id) {
   Wagon wagon = wagonRepository.getOne(id);
   isSafeForDelete(wagon);
   wagonRepository.delete(wagon);
}

我可以解决问题,但想了解原因。

谢谢

1 个答案:

答案 0 :(得分:0)

您标记为“有效”的代码会导致一种假设,即Wagon-Train关系是fetch="EAGER"

此“无效”和“一笔交易”代码:

@Transactional
public JsonTrain delete(Long id) {
   Wagon wagon = wagonRepository.getOne(id);
   isSafeForDelete(wagon);
   wagonRepository.delete(wagon);
   return modelMapper.map(wagon.getTrain(), JsonTrain.class);
}

首先从存储库(Wagon wagon = wagonRepository.getOne(id)中加载货车,然后将其标记为已删除(wagonRepository.delete(wagon)),请参见:JPA entity lifecycle。最后,将Train(wagon.getTrain())参考传递给modelmapper。由于我的答案开头表达的是假说,在删除Wagon之前,已从数据库加载了Train。要删除货车,您还应该尝试从“火车货车”列表中将其删除。

标记为“工作”的代码具有语义,其中每个存储库操作都在单独的事务(Wagon wagon = wagonRepository.getOne(id)wagonRepository.delete(wagon))中执行。因此,当您将火车传递给modelmapper时,货车已经从数据库中删除了-但是-因为装有火车的货车在删除之前就已加载,所以删除的货车也应映射到JsonTrain(假设JsonTran的JsonWagon列表为:))。