[英]JPA findBy method always goes to orElseThrow
這是我們的代碼
private IdentificationMaster validateIdentificationType(String idType) {
if(!StringUtils.isNotBlank(idType))
throw new IllegalArgumentException("Invalid idType");
Optional<IdentificationMaster> op1 = specRepo.findById(idType); //testing purpose
Optional<IdentificationMaster> op2 = specRepo.findByIdentificationType(idType); //testing purpose
return specRepo.findById(idType)
.orElse(specRepo.findByIdentificationType(idType)
.orElseThrow(() -> new ResourceNotFoundException("Id Type Not Found " + idType)));
}
對於idType
我們期待兩個值,它可以是主鍵 id或其對應的identificationType
。 表只有兩列id
和identificationType
。 問題是即使op1
或op2
不為空,它也會拋出ResourceNotFoundException
。 現在如果我像這樣改變我的回報
return specRepo.findByIdentificationType(idType)
.orElse(specRepo.findById(idType)
.orElseThrow(() -> new ResourceNotFoundException("Id Type Not Found " + idType)));
它再次拋出相同的異常!
存儲庫
@Repository
public interface IdentificationSpecRepository extends CrudRepository<IdentificationMaster, String>{
Optional<IdentificationMaster> findByIdentificationType(String identificationType);
}
實體
@Entity
@Table(name = "IDENTIFICATION_MASTER")
public class IdentificationMaster {
@Id
@Column(name = "ID")
private String id;
@Column(name = "IDENTIFICATION_TYPE", unique = true)
private String identificationType;
// getters and setters
}
可能是什么問題呢?
return specRepo.findByIdentificationType(idType)
.orElse(specRepo.findById(idType)
.orElseThrow(() -> new ResourceNotFoundException("...")));
是原因。
Java 非常急切地執行並且總是調用 orElse 方法來准備以防萬一它需要它。
你的執行順序不知何故:
specRepo.findByIdentificationType(idType)
orElse
無法執行,因為它的參數尚未評估specRepo.findById(idType)
.orElseThrow(() -> new ResourceNotFoundException("..."))
o
orElse(o)
而不是使用orElse
一個應該更喜歡orElseGet
。
return specRepo.findByIdentificationType(idType)
.orElseGet(() -> specRepo.findById(idType)
.orElseThrow(() -> new ResourceNotFoundException("...")));
只有在需要時才會調用它。
我們這里有兩種情況:
specRepo
返回一個非空的 Optional。specRepo
返回空的 object。 在場景 1 中, idType
是一個有效的identificationType
因此不是一個id
,所以findById
會拋出一個異常。 在場景 2 中, idType
不是有效的identificationType
,如果它是合法的id
,則該方法應導致拋出異常。
雖然這個答案可以診斷問題並描述這種行為的原因是什么, @Abinash Ghosh
的答案提供了該問題的最簡單和 imo 最佳解決方案。
一般來說,避免使用orElse
。 在這種情況下,將findByIdentificationTypeOrId(String it, String id)
添加到您的存儲庫。
@xenteros 是對的,這就是問題所在。 您可以使用findByIdentificationTypeOrId
在一個查詢中獲取數據
return specRepo.findByIdentifcationTypeOrId(idType, idType)
.orElseThrow(() -> new ResourceNotFoundException("...")));
和存儲庫之類的
@Repository
public interface IdentificationSpecRepository extends CrudRepository<IdentificationMaster, String>{
Optional<IdentificationMaster> findByIdentificationTypeOrId(String identificationType, String id);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.