Search code examples
javajakarta-eeeclipselinkcriteria-api

How to query for the key in a JPA ElementCollection map having an enum as value and using CriteriaQuery?


I'd like to filter entities by the key of a ElementCollection Map, but an exception is thrown by EclipseLink. I have a small entity class to demonstrate my problem.

@Entity
public class TestEntity {
    public enum MyEnum {
        FOO,
        BAR;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "pkGen")
    @TableGenerator(allocationSize = 1000, initialValue = 0, name = "pkGen", table = "PRIMARY_KEYS")
    private int id;

    @ElementCollection(targetClass = MyEnum.class)
    @Enumerated(EnumType.STRING)
    @MapKeyClass(String.class)
    Map<String, MyEnum> col = new HashMap<>();

    public Map<String, MyEnum> getCol() {
        return col;
    }
}

Now I try to search for all entities with a col key "foobar" like this:

@LocalBean 
public class EclipseLinkBean {

@PersistenceContext
private EntityManager em;

    public void test() {
        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<TestEntity> q = builder.createQuery(TestEntity.class);
        Root<TestEntity> testEntity = q.from(TestEntity.class);
        MapJoin<TestEntity, String, MyEnum> col = testEntity.joinMap("col");
        q.where(builder.equal(col.key(), "foobar"));
        em.createQuery(q).getResultList();
    }
}

I'm getting this exception:

java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Enum at org.eclipse.persistence.mappings.converters.EnumTypeConverter.convertObjectValueToDataValue(EnumTypeConverter.java:160) ~[org.eclipse.persistence.core_2.4.1.v20121003-ad44345.jar:na]

Debugging shows, that EnumTypeConverter is trying to cast "foobar" to an Enum.

Is there something wrong with my annotations on col or my construction of the query? Normally I'm not using the criteria api but in this case I have to.

Update: The problem also occurs if i use a jpql query:

em.createQuery("SELECT te FROM TestEntity te JOIN te.col c WHERE KEY(c) = 'foobar'").getResultList();

Thanks for any solution or hint helping to solve my problem.


Solution

  • Seems like a bug. Try the 2.5 release, and if it still fails, log a bug.

    A workaround would be to use a native query, or in JPQL use the COLUMN operator (or Expression in Criteria), or map the relationship as a OneToMany to an Entity instead of ElementCollection.