Java:有 @Enumerated(STRING) 但仍然得到 ClassCastException
Java: Have the @Enumerated(STRING) but still get ClassCastException
我有一个带有枚举字段的实体:
@Entity
@NamedQueries({
@NamedQuery(
name = "MyEntity.findEnum",
query = "SELECT myEntity FROM MyEntity myEntity WHERE myEntity.myEnum = 'A'"
)
})
public class MyEntity {
//...
@Enumerated(STRING)
private MyEnum myEnum;
//...
}
枚举非常简单:
public enum MyEnum {
A, B;
}
在我的主要 class 中,我有以下主要功能:
public static void main(String[] args) {
/...
MyEntity myEntity = new MyEntity();
myEntity.setMyEnum(MyEnum.A);
tx.begin();
em.persist(myEntity);
tx.commit();
TypedQuery<MyEntity> myEnumEntitiesQuery =
em.createNamedQuery("MyEntity.findEnum", MyEntity.class);
List<MyEntity> myEntities = myEnumEntitiesQuery.getResultList();
}
虽然我有 @Enumerated(STRING) 注释,但我仍然遇到异常:java.lang.String 无法转换为 java.lang.Enum。为什么我会收到此错误的任何想法?谢谢!
堆栈跟踪:
Exception in thread "main" Local Exception Stack:
Exception [EclipseLink-6168] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.QueryException
Exception Description: Query failed to prepare, unexpected error occurred: [java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Enum].
Internal Exception: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Enum
Query: ReadAllQuery(name="MyEntity.findEnum" referenceClass=MyEntity jpql="SELECT myEntity FROM MyEntity myEntity WHERE myEntity.myEnum = 'ENUM'")
at org.eclipse.persistence.exceptions.QueryException.prepareFailed(QueryException.java:1590)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:680)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.checkPrepare(ObjectLevelReadQuery.java:901)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:613)
at org.eclipse.persistence.internal.jpa.QueryImpl.getDatabaseQueryInternal(QueryImpl.java:341)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createNamedQuery(EntityManagerImpl.java:1124)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createNamedQuery(EntityManagerImpl.java:1144)
at com.istvanmosonyi.dbtest.Main.main(Main.java:29)
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Enum
at org.eclipse.persistence.mappings.converters.EnumTypeConverter.convertObjectValueToDataValue(EnumTypeConverter.java:160)
at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.getFieldValue(AbstractDirectMapping.java:776)
at org.eclipse.persistence.internal.expressions.QueryKeyExpression.getFieldValue(QueryKeyExpression.java:420)
at org.eclipse.persistence.internal.expressions.ConstantExpression.printSQL(ConstantExpression.java:152)
at org.eclipse.persistence.expressions.ExpressionOperator.printDuo(ExpressionOperator.java:2239)
at org.eclipse.persistence.internal.expressions.CompoundExpression.printSQL(CompoundExpression.java:286)
at org.eclipse.persistence.internal.expressions.RelationExpression.printSQL(RelationExpression.java:899)
at org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter.translateExpression(ExpressionSQLPrinter.java:306)
at org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter.printExpression(ExpressionSQLPrinter.java:129)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.printSQL(SQLSelectStatement.java:1683)
at org.eclipse.persistence.internal.databaseaccess.DatabasePlatform.printSQLSelectStatement(DatabasePlatform.java:3178)
at org.eclipse.persistence.platform.database.PostgreSQLPlatform.printSQLSelectStatement(PostgreSQLPlatform.java:530)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:782)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:792)
at org.eclipse.persistence.descriptors.ClassDescriptor.buildCallFromStatement(ClassDescriptor.java:813)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.setCallFromStatement(StatementQueryMechanism.java:390)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.prepareSelectAllRows(StatementQueryMechanism.java:315)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.prepareSelectAllRows(ExpressionQueryMechanism.java:1721)
at org.eclipse.persistence.queries.ReadAllQuery.prepareSelectAllRows(ReadAllQuery.java:813)
at org.eclipse.persistence.queries.ReadAllQuery.prepare(ReadAllQuery.java:744)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:661)
... 6 more
问题是你用下面的声明定义的
@Enumerated(STRING)
private MyEnum myEnum
字段类型为 MyEnum
。但是您正在将字符串值传递给查询。因此,您必须执行以下操作(可能还有其他可能性,但我只知道以下操作):
使用命名参数定义查询字符串:
@NamedQuery(
name = "MyEntity.findEnum",
query = "SELECT me FROM MyEntity me WHERE me.myEnum = :myEnumValue"
)
创建 TypedQuery
的实例并在该实例上设置命名参数,如下所示:
TypedQuery<MyEntity> myEnumEntitiesQuery =
em.createNamedQuery("MyEntity.findEnum", MyEntity.class);
myEnumEntitiesQuery.setParameter("myEnumValue", MyEnum.A);
List<MyEntity> myEntities = myEnumEntitiesQuery.getResultList();
我有一个带有枚举字段的实体:
@Entity
@NamedQueries({
@NamedQuery(
name = "MyEntity.findEnum",
query = "SELECT myEntity FROM MyEntity myEntity WHERE myEntity.myEnum = 'A'"
)
})
public class MyEntity {
//...
@Enumerated(STRING)
private MyEnum myEnum;
//...
}
枚举非常简单:
public enum MyEnum {
A, B;
}
在我的主要 class 中,我有以下主要功能:
public static void main(String[] args) {
/...
MyEntity myEntity = new MyEntity();
myEntity.setMyEnum(MyEnum.A);
tx.begin();
em.persist(myEntity);
tx.commit();
TypedQuery<MyEntity> myEnumEntitiesQuery =
em.createNamedQuery("MyEntity.findEnum", MyEntity.class);
List<MyEntity> myEntities = myEnumEntitiesQuery.getResultList();
}
虽然我有 @Enumerated(STRING) 注释,但我仍然遇到异常:java.lang.String 无法转换为 java.lang.Enum。为什么我会收到此错误的任何想法?谢谢!
堆栈跟踪:
Exception in thread "main" Local Exception Stack:
Exception [EclipseLink-6168] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.QueryException
Exception Description: Query failed to prepare, unexpected error occurred: [java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Enum].
Internal Exception: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Enum
Query: ReadAllQuery(name="MyEntity.findEnum" referenceClass=MyEntity jpql="SELECT myEntity FROM MyEntity myEntity WHERE myEntity.myEnum = 'ENUM'")
at org.eclipse.persistence.exceptions.QueryException.prepareFailed(QueryException.java:1590)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:680)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.checkPrepare(ObjectLevelReadQuery.java:901)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:613)
at org.eclipse.persistence.internal.jpa.QueryImpl.getDatabaseQueryInternal(QueryImpl.java:341)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createNamedQuery(EntityManagerImpl.java:1124)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createNamedQuery(EntityManagerImpl.java:1144)
at com.istvanmosonyi.dbtest.Main.main(Main.java:29)
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Enum
at org.eclipse.persistence.mappings.converters.EnumTypeConverter.convertObjectValueToDataValue(EnumTypeConverter.java:160)
at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.getFieldValue(AbstractDirectMapping.java:776)
at org.eclipse.persistence.internal.expressions.QueryKeyExpression.getFieldValue(QueryKeyExpression.java:420)
at org.eclipse.persistence.internal.expressions.ConstantExpression.printSQL(ConstantExpression.java:152)
at org.eclipse.persistence.expressions.ExpressionOperator.printDuo(ExpressionOperator.java:2239)
at org.eclipse.persistence.internal.expressions.CompoundExpression.printSQL(CompoundExpression.java:286)
at org.eclipse.persistence.internal.expressions.RelationExpression.printSQL(RelationExpression.java:899)
at org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter.translateExpression(ExpressionSQLPrinter.java:306)
at org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter.printExpression(ExpressionSQLPrinter.java:129)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.printSQL(SQLSelectStatement.java:1683)
at org.eclipse.persistence.internal.databaseaccess.DatabasePlatform.printSQLSelectStatement(DatabasePlatform.java:3178)
at org.eclipse.persistence.platform.database.PostgreSQLPlatform.printSQLSelectStatement(PostgreSQLPlatform.java:530)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:782)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:792)
at org.eclipse.persistence.descriptors.ClassDescriptor.buildCallFromStatement(ClassDescriptor.java:813)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.setCallFromStatement(StatementQueryMechanism.java:390)
at org.eclipse.persistence.internal.queries.StatementQueryMechanism.prepareSelectAllRows(StatementQueryMechanism.java:315)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.prepareSelectAllRows(ExpressionQueryMechanism.java:1721)
at org.eclipse.persistence.queries.ReadAllQuery.prepareSelectAllRows(ReadAllQuery.java:813)
at org.eclipse.persistence.queries.ReadAllQuery.prepare(ReadAllQuery.java:744)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:661)
... 6 more
问题是你用下面的声明定义的
@Enumerated(STRING)
private MyEnum myEnum
字段类型为 MyEnum
。但是您正在将字符串值传递给查询。因此,您必须执行以下操作(可能还有其他可能性,但我只知道以下操作):
使用命名参数定义查询字符串:
@NamedQuery( name = "MyEntity.findEnum", query = "SELECT me FROM MyEntity me WHERE me.myEnum = :myEnumValue"
)
创建
TypedQuery
的实例并在该实例上设置命名参数,如下所示:TypedQuery<MyEntity> myEnumEntitiesQuery = em.createNamedQuery("MyEntity.findEnum", MyEntity.class); myEnumEntitiesQuery.setParameter("myEnumValue", MyEnum.A); List<MyEntity> myEntities = myEnumEntitiesQuery.getResultList();