这是我们的代码
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
。问题在于,即使ResourceNotFoundException
或op1
不为空,它也会抛出op2
。现在,如果我改变这样的返回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
返回空对象。 在方案1中,
idType
是有效的identificationType
,因此不是id
,因此findById
将引发异常。在方案2中,
idType
不是有效的identificationType
,如果它是合法的id
,则该方法应导致引发异常。编辑:
尽管此答案可以诊断问题并描述这种行为的原因,但是
@Abinash Ghosh
答案提供了最简单,最完美的imo解决方案。通常,避免使用
orElse
。在这种情况下,请将findByIdentificationTypeOrId(String it, String id)
添加到您的存储库中。