Problems with making a query when using Enum in entity

后端 未结 3 1334
耶瑟儿~
耶瑟儿~ 2020-12-08 12:40

I have the following in a Question entity:

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


        
相关标签:
3条回答
  • 2020-12-08 13:05

    Please use below property in application.properties logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

    0 讨论(0)
  • 2020-12-08 13:24

    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").
    
    0 讨论(0)
  • 2020-12-08 13:27

    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.

    0 讨论(0)
提交回复
热议问题