2

I have this entity with an enum field:

@Entity
@NamedQueries({
    @NamedQuery(
        name = "MyEntity.findEnum",
        query = "SELECT myEntity FROM MyEntity myEntity WHERE myEntity.myEnum = 'A'"
    )
})
public class MyEntity {
    //...
    @Enumerated(STRING)
    private MyEnum myEnum;
    //...
}

The enum is very simple:

public enum MyEnum {
    A, B;
}

In my main class I have the following main function:

    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();
    }

So althuogh I have the @Enumerated(STRING) annotation I still got the exception: java.lang.String cannot be cast to java.lang.Enum. Any ideas why I get this error? Thank you!

Stack trace:

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
Display Name
  • 1,121
  • 2
  • 11
  • 14
  • See also http://stackoverflow.com/questions/8217144/problems-with-making-a-query-when-using-enum-in-entity – anre Nov 03 '16 at 11:49

1 Answers1

3

The problem is that you defined with the following declaration

@Enumerated(STRING)
private MyEnum myEnum

that the type of the field to be of type MyEnum. But you are passing a string value to the query. So you have to do the following (there might be other possibility to do this but only the following is known to me):

  1. Define the query string with named parameter:

    @NamedQuery(
        name = "MyEntity.findEnum",
        query = "SELECT me FROM MyEntity me WHERE me.myEnum = :myEnumValue"
    

    )

  2. Create an instance of the TypedQuery and set the named parameter on thiss instance as follows:

    TypedQuery<MyEntity> myEnumEntitiesQuery =
            em.createNamedQuery("MyEntity.findEnum", MyEntity.class);
    myEnumEntitiesQuery.setParameter("myEnumValue", MyEnum.A);
    List<MyEntity> myEntities = myEnumEntitiesQuery.getResultList();
    
ujulu
  • 3,289
  • 2
  • 11
  • 14
  • Thank you! I'm just learning these things and I have already seen this code before but did not remember, it works perfectly! – Display Name Aug 06 '16 at 22:08