Search code examples
javajpaenumseclipselinkjava-ee-7

JPA Converter unnessecary call of "convertToDatabaseColumn" leads to ClassCastException


I have a Converter to convert the String stored in the DB to the corresponding Enum element:

@Converter(autoApply=true)
public class DokumentTypConverter implements AttributeConverter<DokumentTypSchluessel, String> {

   @Override
   public String convertToDatabaseColumn(DokumentTypSchluessel attribute) {
      return attribute.getValue();
   }

   @Override
   public DokumentTypSchluessel convertToEntityAttribute(String dbData) {
      return DokumentTypSchluessel.from(dbData);
   }
}

I have an Entity class which has a field of the Enum type:

@Entity
@Table(name="REF_DOKUMENTTYPEN")
public class DokumentTyp {
   private DokumentTypSchluessel schluessel;
   // snip
}

Now when I try to retrieve an instance of that entity from the db

String query = "SELECT d FROM DokumentTyp d WHERE d.schluessel = " + VORBEREITUNG;
entityManager.createQuery(query, DokumentTyp.class).getSingleResult();

I get the following error:

javax.persistence.PersistenceException: An exception occurred while calling convertToDatabaseColumn on converter class de.drvbund.pub.model.convert.DokumentTypConverter with value VORBEREITUNG
        at org.eclipse.persistence.mappings.converters.ConverterClass.convertObjectValueToDataValue(ConverterClass.java:139)
        at org.eclipse.persistence.mappings.foundation.AbstractDirectMapping.getFieldValue(AbstractDirectMapping.java:778)
        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:2241)
        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:325)
        at org.eclipse.persistence.internal.expressions.ExpressionSQLPrinter.printExpression(ExpressionSQLPrinter.java:129)
        at org.eclipse.persistence.internal.expressions.SQLSelectStatement.printSQL(SQLSelectStatement.java:1755)
        at org.eclipse.persistence.internal.databaseaccess.DatabasePlatform.printSQLSelectStatement(DatabasePlatform.java:3268)
        at org.eclipse.persistence.platform.database.OraclePlatform.printSQLSelectStatement(OraclePlatform.java:967)
        at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:843)
        at org.eclipse.persistence.internal.expressions.SQLSelectStatement.buildCall(SQLSelectStatement.java:854)
        at org.eclipse.persistence.descriptors.ClassDescriptor.buildCallFromStatement(ClassDescriptor.java:815)
        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:1723)
        at org.eclipse.persistence.queries.ReadAllQuery.prepareSelectAllRows(ReadAllQuery.java:904)
        at org.eclipse.persistence.queries.ReadAllQuery.prepare(ReadAllQuery.java:835)
        at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:673)
        ... 151 more
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to de.drvbund.pub.enums.DokumentTypSchluessel

I guess the framework takes the toString()-representation of the Enum element from the query, assumes it is the entity attribute value, that needs to be converted to its corresponding dbValue and tries to call the convertToDatabaseColumn() method passing the String. I just don't know how to do this correctly.

How can I retrieve entities filtered by an Enum attribute value with JPA?


Solution

  • The problem was solved by the suggestion of Chris:

    entityManager.createQuery("SELECT d FROM DokumentTyp d WHERE d.schluessel = ?1", DokumentTyp.class)
                 .setParameter(1, DokumentTypSchluessel.VORBEREITUNG)
                 .getSingleResult();