117

I have the following in a Question entity:

@NamedQuery(name = "Question.allApproved",
    query = "SELECT q FROM Question q WHERE q.status = 'APPROVED'")

and

@Enumerated(EnumType.STRING)
private Status status;

// usual accessors

I am getting this exception:

Exception Description: Error compiling the query [Question.countApproved: SELECT COUNT(q) FROM Question q WHERE q.status = 'APPROVED'], line 1, column 47: invalid enum equal expression, cannot compare enum value of type [myCompnay.application.Status] with a non enum value of type [java.lang.String]. at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.deploy(EntityManagerSetupImpl.java:501)

How do I fix this?

1
  • are you using a custom enum? Can you update the document to show the Status enum? Commented Nov 21, 2011 at 19:22

3 Answers 3

247

I think you should use your (fully qualified) Status enum instead of literal value, so something like this: (assuming your Status enum is in com.myexample package)

@NamedQuery(name = "Question.allApproved", 
            query = "SELECT q 
                     FROM Question q 
                     WHERE q.status = com.myexample.Status.APPROVED").
Sign up to request clarification or add additional context in comments.

12 Comments

What about a JPA2 regular @Query ? It complains with: The value for annotation attribute Query.value must be a constant expression.
What @Query annotation are you talking about?
This fully qualified is more important as I thought it could be.
On a sidenote: It didn't work when the enum was an inner class of the entity. If this doesn't work for you, make sure the enum is it's own file!
@evandongen any solution if enum is inner class?
|
1

You can use JPQL (Java Persistence Query Language) in the @NamedQuery (or @Query) annotation and then use the properties of the param object in the query.

@NamedQuery(name = "Question.allApproved",
    query = "SELECT q FROM Question q WHERE :#{#q.status.name()} = 'APPROVED'")

1 Comment

Just for clarity, it's not a working solution. You can reference method args in this way, but not a selected entity
-3

4 years since the initial post, there are some developments. Using spring 4 and Hibernate 4 it's now possible to 'trick' Hibernate using a SpEL expression. For example:

The enum:

package com.mycompany.enums

public enum Status {
    INITIAL, PENDING, REJECTED, APPROVED, SHIPPED, DELIVERED, COMPLETE;
}

Here's a wrapper class called 'Filter' which we'll pass to the repository filtering method.

package com.mycompany.enums

public class Filter implements Serializable {

    /** The id of the filtered item */
    private Integer id;
    /** The status of the filtered item */
    private Status status;
    // more filter criteria here...

    // getters, setters, equals(), hashCode() - omitted for brevity

    /**
     * Returns the name of the status constant or null if the status is null. This is used in the repositories to filter
     * queries by the status using a the SPEL (T) expression, taking advantage of the status qualified name. For example:
     * {@code :#{T(com.mycompany.enums.Status).#filter.statusName}}
     *
     * @return the status constant name or null if the status is null
     */
    public String getStatusName() {
        return null == status ? status : status.name();
    }

 }

Finally, in the repository, we can now use the Filter class as the single parameter and make the query translate what appears to be a mixture of literals and SpEL expressions to a Status object:

The repository:

package com.mycompany.repository

@Repository
public interface OrderRepository extends CrudRepository<Order, Integer> {

    @Query("SELECT o from Order o "
            + "WHERE o.id = COALESCE(:#{#filter.id},o.id) "
            + "AND o.status = COALESCE(:#{T(com.mycompany.enums.Status).#filter.statusName},o.status)")
    public List<Order> getFilteredOrders(@Param(value = "filter") Filter filter);
}

This works perfectly, but for some odd reason I haven't figured out yet, if you enable SQL debugging in Hibernate and turn on the binder logging, you'll not be able to see Hibernate binding this expression to query variables.

1 Comment

You don't see it among the variable bindings because the constant has already been substituted into the query string.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.