我有一個控制器,服務POST請求(文件上傳),但實際上提供更新。邏輯很簡單: - 通過ID 找到對象 - 如果我們沒有這樣的對象返回BAD_REQUEST - 否則更新發現對象,並返回更新ResponseEntitySpring Data Jpa findOne方法是否返回被管實體?
@PostMapping("/{id}")
public ResponseEntity<?> post(@PathVariable("id") long id,
@RequestParam("file") MultipartFile file) {
//this is not @Transactional method
Optional<Job> jobOptional = jobService.getJobById(id);
return jobOptional
.map(
job ->
getSuccessfulResponse(
//this is @Transactional
jobService.update(job, file))) //1
.orElse(
getBadRequestResponse(
getJobNotFoundByIdMessage(id)));
}
[...]
@Service
public class JobService {
@Transactional
public Job update(Job job, MultipartFile file) {...}
}
在我們更新(最後由CrudRepository#findOne
)實體檢索並更新並保存爲DB值。
我的問題是:我們可以改變方法參數並返回這個突變的結果,或者我們應該在方法內部創建clone參數,然後改變它然後返回結果嗎?
就jpa/hibernate而言:CrudRepository#findOne
給我們一個managed/attached
實體嗎?我個人認爲 - 不,導致調用它的方法沒有標記@Transactional
,我們可以克隆它,調用CrudRepository#save
來提供更新
它已經包裝,因爲我提到的問題。我不確定。兩次檢索同一個實體是個好主意。感謝您使用@Transactional'來封裝Spring data-jpa存儲庫方法。我不知道。實際上它是'@Transactional(readOnly = true)' –
您可以更改您的服務以傳回可選實體是否存在。例如 @Transactional public可選更新(作業作業,MultipartFile文件){...} 如果實體不存在,則可選爲空。如果實體存在,則可選包含更新後的實體。 –
gkatzioura
非常好的一點。它解決了我的情況。謝謝! –