本文介紹了Java.lang.IlLegalArgumentException:未找到枚舉常量的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我有此枚舉,我要使用它來設置不同的狀態:
@Enumerated(EnumType.STRING)
@Column(name = "status", length = 20)
private OnboardingTaskStatus status;
public enum OnboardingTaskStatus {
NEW,
IN_PROGRESS,
DISABLED,
}
當我嘗試構建搜索規范時,我得到的結果是:
public Page<OnboardingTaskDto> findOnboardingTasks(OnboardingTaskSearchParams params, Pageable pageable){
Specification<OnboardingTasks> spec = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
if (params.getStatus() != null) {
predicates.add(cb.equal(root.get("status"), params.getStatus()));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
return onboardingTasksService.findAll(spec, pageable).map(onboardingMapper::taskToTaskDTO);
}
@Getter
@Setter
public class OnboardingTaskSearchParams {
private String title;
private String status;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
我嘗試將狀態更新到此字段:
predicates.add(cb.equal(root.get("status"), OnboardingTaskStatus.valueOf(params.getStatus())));
但我收到錯誤:
OnboardingTaskStatus.2769df0841;嵌套異常為java.lang.IlLegalArgumentException:no enum常量OnboardingTaskStatus.2769df0841]帶有根本原因
Java.lang.IlLegalArgumentException:沒有枚舉常量OnboardingTaskStatus.2769df0841
您知道在未找到值的情況下實現Enum搜索而不引發錯誤的正確方法嗎?
推薦答案
報告的錯誤表明您正在嘗試將String
OnboardingTaskStatus.2769df0841
轉換為未定義的OnboardingTaskStatus
枚舉值。
請不要在如何處理錯誤的值上尋找解決辦法,而是嘗試找出為什么您一開始就獲得了錯誤的值。使用正確的枚舉值單獨測試Specification
,看看它是否工作。如果是這樣的話-我認為它可能會這樣做-檢查您用來為OnboardingTaskSearchParams
表單提供值的代碼,并仔細檢查status
參數的值,可能您正在以錯誤的方式迭代枚舉,等等。可能不是,但也要確保您的status
列沒有包含不正確的值-在以前的代碼版本中手動插入…
此外,為了緩解該問題,我會嘗試在搜索條件中直接定義您的枚舉值,Spring將自動處理String
和枚舉值之間的轉換。
我的意思是,不要將status
定義為OnboardingTaskSearchParams
中的String
,只需將該字段定義為枚舉:
@Getter
@Setter
public class OnboardingTaskSearchParams {
private String title;
private OnboardingTaskStatus status;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
或者更好:
@Getter
@Setter
public class OnboardingTaskSearchParams {
private String title;
private List<OnboardingTaskStatus> statuses;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
并在Specification
中使用枚舉:
public Page<OnboardingTaskDto> findOnboardingTasks(OnboardingTaskSearchParams params, Pageable pageable){
Specification<OnboardingTasks> spec = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
if (params.getStatus() != null) {
predicates.add(cb.equal(root.get("status"), params.getStatus()));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
return onboardingTasksService.findAll(spec, pageable).map(onboardingMapper::taskToTaskDTO);
}
或者,如果使用多個值作為搜索條件:
public Page<OnboardingTaskDto> findOnboardingTasks(OnboardingTaskSearchParams params, Pageable pageable){
Specification<OnboardingTasks> spec = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
final List<OnboardingTaskStatus> statuses = params.getStatuses();
if (statuses != null && ! statuses.isEmpty()){
predicates.add(root.get("status").in(statuses));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
};
return onboardingTasksService.findAll(spec, pageable).map(onboardingMapper::taskToTaskDTO);
}
必須確保在您的前端中為可能的OnboardingTaskStatus
枚舉、NEW
、IN_PROGRESS
和DISABLED
在表單中提供了正確的值。
需要注意的是,如果您的表單被提交,并且在到達您的服務或數據庫相關代碼之前發現任何不正確的枚舉值,Spring將立即在Web層投訴。
如果您確實需要檢查枚舉值是否存在,并且仍然在搜索條件中使用String
表示status
,則您有多個選擇。
例如,您可以在Commons-lang庫的EnumUtils
類中使用isValidEnum
方法:
if(EnumUtils.isValidEnum(OnboardingTaskStatus.class, params.getStatus())){
predicates.add(
cb.equal(
root.get("status"),
OnboardingTaskStatus.valueOf(params.getStatus())
)
);
}
您可以使用Guava的Enums
類中的getIfPresent
方法:
Optional<OnboardingTaskStatus> optStatus = Enums.getIfPresent(OnboardingTaskStatus.class, params.getStatus());
if(optStatus.isPresent()){
predicates.add(
cb.equal(
root.get("status"),
OnboardingTaskStatus.valueOf(optStatus.get())
)
);
}
這個SO question提供了Jon Skeet和其他人的幾個替代方案。
在Java 8中,您也有幾個選項。除了其他答案中提供的答案外,您還可以嘗試:
Optional<OnboardingTaskStatus> optStatus = EnumSet.allOf(OnboardingTaskStatus.class)
.stream()
.filter(e -> e.name().equals(params.getStatus()))
.findAny();
if(optStatus.isPresent()){
predicates.add(
cb.equal(
root.get("status"),
OnboardingTaskStatus.valueOf(optStatus.get())
)
);
}
最后,您似乎在幕后使用某種轉換機制將status
String
轉換為Specification
中相應的枚舉值;相反,您可以簽入Hibernate source code,該行將引發不同的錯誤:
predicates.add(cb.equal(root.get("status"), params.getStatus()));
類似:
Parameter value ... did not match expected type ...
如果是這樣的話,請也復習一下這個邏輯,也許問題就在那里。
這篇關于Java.lang.IlLegalArgumentException:未找到枚舉常量的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,