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("..."))oorElse(o)而不是使用orElse一个应该更喜欢orElseGet。
return specRepo.findByIdentificationType(idType)
.orElseGet(() -> specRepo.findById(idType)
.orElseThrow(() -> new ResourceNotFoundException("...")));
Run Code Online (Sandbox Code Playgroud)
它只会在需要时调用。
我们这里有两个场景:
specRepo 返回一个非空的 Optional。specRepo 返回空对象。在场景 1 中,idTypeis a valididentificationType因此不是 an id,因此findById将抛出异常。在场景 2 中,idType是无效的identificationType,如果它是合法的,则id该方法应导致抛出异常。
虽然这个答案诊断了问题并描述了这种行为的原因,但@Abinash Ghosh答案提供了问题的最简单和最好的解决方案。
一般来说,避免使用orElse. 在这种情况下,将 添加findByIdentificationTypeOrId(String it, String id)到您的存储库。
| 归档时间: |
|
| 查看次数: |
862 次 |
| 最近记录: |