英文:
InvalidDataAccessApiUsageException trying to find using JPA query with Enum value
问题
Enum def -
// 枚举定义
public enum someAccountType {
ACCOUNT_NUMBER("account_number"),
CREDIT_CARD("credit_card");
public final String v;
someAccountType(String value) {
this.v = value;
}
}
@AllArgsConstructor
@Getter
@Entity
@Builder
@Setter
public class SomeDetail {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Enumerated(EnumType.STRING)
@Column(name="accountType")
private Enum.someAccountType accountType;
..
}
Repository -
// 存储库定义
@Repository
public interface SomeDetailRepository extends JpaRepository<SomeDetail, Long> {
List<SomeDetail> findByEncryptedIfscAndEncryptedAccountNoAndAccountTypeAndIsValid(
String encryptedIfsc, String encryptedAccountNo, String accountType, Boolean isValid);
}
Service call -
// 服务调用
List<SomeDetail> someDetails = someDetailRepository.findByEncryptedIfscAndEncryptedAccountNoAndAccountTypeAndIsValid(
ben.getEncryptedIfsc(), ben.getEncryptedAccountNo(), Enum.someAccountType.CREDIT_CARD.v, isValid);
Exception -
// 异常信息
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [credit_card] did not match expected type [Enum$someAccountType (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [credit_card] did not match expected type [Enum$someAccountType (n/a)]
Why is it throwing this exception? I have defined @Enumerated(EnumType.STRING) so it should expect string type stored in db.
英文:
Enum def -
public enum someAccountType {
ACCOUNT_NUMBER("account_number"),
CREDIT_CARD("credit_card");
public final String v;
someAccountType(String value) {
this.v = value;
}
}
@AllArgsConstructor
@Getter
@Entity
@Builder
@Setter
public class SomeDetail {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Enumerated(EnumType.STRING)
@Column(name="accountType")
private Enum.someAccountType accountType;
..
}
Repository -
@Repository
public interface SomeDetailRepository extends JpaRepository<SomeDetail, Long> {
List<someDetail> findByEncryptedIfscAndEncryptedAccountNoAndAccountTypeAndIsValid(
String encryptedIfsc, String encryptedAccountNo, String accountType, Boolean isValid);
Service call -
List<SomeDetail> someDetails = someDetailRepository.findByEncryptedIfscAndEncryptedAccountNoAndAccountTypeAndIsValid(
ben.getEncryptedIfsc(), ben.getEncryptedAccountNo(), Enum.someAccountType.CREDIT_CARD.v, isValid);
Exception -
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [credit_card] did not match expected type [Enum$someAccountType (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [credit_card] did not match expected type [Enum$someAccountType (n/a)]
Why is it throwing this exception? I have defined @Enumerated(EnumType.STRING) so it should expect string type stored in db.
答案1
得分: 0
当使用JPA与Enum时,需要依赖于Enum对象,而不是它的属性。
例如,我会像这样更改您的存储库方法:
@Repository
public interface SomeDetailRepository extends JpaRepository<SomeDetail, Long> {
List<SomeDetail> findByEncryptedIfscAndEncryptedAccountNoAndAccountTypeAndIsValid(
String encryptedIfsc, String encryptedAccountNo, Enum.someAccountType accountType, Boolean isValid);
并直接使用枚举值:
List<SomeDetail> someDetails = someDetailRepository.findByEncryptedIfscAndEncryptedAccountNoAndAccountTypeAndIsValid(
ben.getEncryptedIfsc(), ben.getEncryptedAccountNo(), Enum.someAccountType.CREDIT_CARD, isValid);
顺便说一下,在Java中,始终使用大写字母为类、枚举等命名,例如将 someAccountType
改为 SomeAccountType
。
关于 @Enumerated
的含义:
@Enumerated
允许您指定Hibernate将如何在数据库中存储值。您有两个选项(来自javadoc):
- EnumType.ORDINAL:将枚举类型属性或字段持久化为整数
- EnumType.STRING:将枚举类型属性或字段持久化为字符串
但它不会改变您在存储库代码中的使用方式,它只会改变Hibernate如何存储它。
英文:
When using Enum with JPA, you need to rely on the Enum object, not on its attribute.
For instance, I'll change your repository method like this:
@Repository
public interface SomeDetailRepository extends JpaRepository<SomeDetail, Long> {
List<someDetail> findByEncryptedIfscAndEncryptedAccountNoAndAccountTypeAndIsValid(
String encryptedIfsc, String encryptedAccountNo, Enum.someAccountType accountType, Boolean isValid);
And use the enum val directly:
List<SomeDetail> someDetails = someDetailRepository.findByEncryptedIfscAndEncryptedAccountNoAndAccountTypeAndIsValid(
ben.getEncryptedIfsc(), ben.getEncryptedAccountNo(), Enum.someAccountType.CREDIT_CARD, isValid);
By the way, in Java, always name your class, enum ... with a capital letter someAccountType
-> SomeAccountType
What means @Enumarated
@Enumerated
lets you specify how Hibernate will store the value in DB. You have two options (from the javadoc):
- EnumType.ORDINAL: Persist enumerated type property or field as an integer
- EnumType.STRING: Persist enumerated type property or field as a string
But it doesn't change how you use it in your repository code, it is changing only how Hibernate will store it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论