25

Is it possible to use enum parameter with @Query annotation?

Here is the code I'm using to find user role:

Role userRole = roleRepository.findByRole(Roles.USER);
if ( userRole == null ) {
    LOGGER.debug("No role found with role: {}", Roles.USER);
}

and it prints out

No role found with role: ROLE_USER

but if I try to find all roles this is what I get:

for ( Role r : roleRepository.findAll() )
    LOGGER.debug("{}", r);

Role@8a8c0a[roleId=1,role=role_admin,version=0]
Role@1efe9ee[roleId=2,role=role_staff,version=0]
Role@1e70f68[roleId=3,role=role_user,version=0]
Role@a475d1[roleId=4,role=role_guest,version=0]

As you can see user role does exists.

RoleRepository:

public interface RoleRepository extends JpaRepository<Role, Long> {

    @Query("SELECT r FROM Role r WHERE LOWER(r.role) = LOWER(:role)")
    public Role findByRole(@Param("role") Roles role);

}

Role:

@Entity
@Table(name = "role")
public class Role {

    public enum Roles {

        ADMIN("ROLE_ADMIN"),
        STAFF("ROLE_STAFF"),
        USER("ROLE_USER"),
        GUEST("ROLE_GUEST");

        private String role;

        private Roles(String role) {
            this.role = role;
        }

        public String getRole() {
            return role;
        }

        @Override
        public String toString() {
            return role;
        }

    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "role_id", updatable = false)
    private Long roleId;

    @Column(name = "role")
    private String role;

    @Version
    @Column(name = "version")
    private long version = 0;

    public Long getRoleId() {
        return roleId;
    }

    public String getRole() {
        return role;
    }

    public long getVersion() {
        return version;
    }

    @Override
    public String toString() {
        return new ReflectionToStringBuilder(this).toString();
    }

}
1

3 Answers 3

10

Try using SpEl in Query and call toString() of Enum parameter like this:

@Query("SELECT r FROM Role r WHERE LOWER(r.role) = LOWER(:#{#role?.toString()})")
    public Role findByRole(@Param("role") Roles role);

or shorter:

@Query("SELECT r FROM Role r WHERE LOWER(r.role) = LOWER(:#{#role})")
    public Role findByRole(@Param("role") Roles role);
Sign up to request clarification or add additional context in comments.

1 Comment

What if I need a list of roles?
3

I suggest proper use of JPA enumerated types. Change the type "role" property as:

@Column(name = "role")
@Enumerated(EnumType.STRING)
private Roles role;

This should automatically fix the query result.

3 Comments

Tried this without any success. After enabling more specific logging I got this message: 09:20:28.953 [main] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARBINARY] - ROLE_USER. Does it bind parameter as wrong type?
Maybe try to use a "String" param in the repository method, instead of the Enum directly. If you use native SQL in the query, try to use "like"
This question is not about query results. The question is about parameter supplied to the query!
0

Just add .name at end of your enum value like:

Example: #{#MyEnum.TEST.name}

In your case it should look like:

@Query("SELECT r FROM Role r WHERE LOWER(r.role) = LOWER(:#{#role.MyEnumValue.name})")
    public Role findByRole(@Param("role") Roles role);

Comments

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.