Aru*_*ran 6 java optional findby spring-data-jpa spring-boot
这是我们的代码
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)));
}
Run Code Online (Sandbox Code Playgroud)
因为idType
我们期待两个值,它可以是主键 id或其对应的identificationType
. 表只有两列id
和identificationType
。问题是ResourceNotFoundException
即使op1
或op2
不为空它也会抛出。现在如果我像这样改变我的回报
return specRepo.findByIdentificationType(idType)
.orElse(specRepo.findById(idType)
.orElseThrow(() -> new ResourceNotFoundException("Id Type Not Found " + idType)));
Run Code Online (Sandbox Code Playgroud)
它再次抛出相同的异常!
存储库
@Repository
public interface IdentificationSpecRepository extends CrudRepository<IdentificationMaster, String>{
Optional<IdentificationMaster> findByIdentificationType(String identificationType);
}
Run Code Online (Sandbox Code Playgroud)
实体
@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
}
Run Code Online (Sandbox Code Playgroud)
可能是什么问题呢?
return specRepo.findByIdentificationType(idType)
.orElse(specRepo.findById(idType)
.orElseThrow(() -> new ResourceNotFoundException("...")));
Run Code Online (Sandbox Code Playgroud)
是原因。
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("...")));
Run Code Online (Sandbox Code Playgroud)
它只会在需要时调用。
我们这里有两个场景:
specRepo
返回一个非空的 Optional。specRepo
返回空对象。在场景 1 中,idType
is a valididentificationType
因此不是 an id
,因此findById
将抛出异常。在场景 2 中,idType
是无效的identificationType
,如果它是合法的,则id
该方法应导致抛出异常。
虽然这个答案诊断了问题并描述了这种行为的原因,但@Abinash Ghosh
答案提供了问题的最简单和最好的解决方案。
一般来说,避免使用orElse
. 在这种情况下,将 添加findByIdentificationTypeOrId(String it, String id)
到您的存储库。
归档时间: |
|
查看次数: |
862 次 |
最近记录: |