QuerySyntaxException with enum

时光总嘲笑我的痴心妄想 提交于 2021-01-28 05:25:32

问题


I have a UserAssignmentRole class like this :

@Data
@Entity
public class UserAssignmentRole {
    ...
    @Enumerated(EnumType.STRING)
    public Role role;
}

And the Role is enum, it looks like this:

public enum Role{
    admin,
    member,
    pending
}

Now when in my repository I try to query to select all with role of admin, it gives me error:

@Query("select uar from UserAssignmentRole uar where uar.role=Role.admin")
public List<UserAssignmentRole> listAdmin(Long userID, Long assignmentID);

How this can be solved?

Error : org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'Role.admin'

Full error : https://pastebin.com/tk9r3wDg


回答1:


You can try not to write this sql by yourself but with repository create code like this:

@Repository
public interface UserAssignmentRolelRepository extends JpaRepository<UserModel, Long>{

    public List<UserAssignmentRole> findByRole(Role role);

}

And then:

@Autowired
UserAssignmentRolelRepository repository ;

public void someMethod(){
   List<UserAssignmentRole> userAssignmentRoles = repository.findByRole(Role.admin);
}

UPDATE 1

As it was point out in this answer: non-conventional naming. You can change labels in your enum to uppercase.

public enum Role{
    Admin,
    Member,
    Pending
}

and then:

@Query("select uar from UserAssignmentRole uar where uar.role=com.example.package.Role.Admin")
public List<UserAssignmentRole> listAdmin(Long userID, Long assignmentID);

UPDATE 2

But if you really want to have lowercase in DB. It requires more code to change. Enum change to:

public enum Role{
    Admin("admin"),
    Member("member"),
    Pending("pending");

    private String name;

    Role(String name) {
        this.name = name;
    }

    public String getName() { return name; }

    public static Role parse(String id) {
        Role role = null; // Default
        for (Role item : Role.values()) {
            if (item.name.equals(id)) {
                role = item;
                break;
            }
        }
        return role;
    }
}

In UserAssignmentRole

//    @Enumerated(EnumType.STRING)
    @Convert(converter = RoleConverter.class)
    private Role role;

And additional class:

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

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

    @Override
    public String convertToDatabaseColumn(Role role) {
        return role.getName();
    }

    @Override
    public Role convertToEntityAttribute(String dbData) {
        return Role.parse(dbData);
    }
}



回答2:


It is a strange but intended behaviour of Hibernate since 5.2.x An enum value is a constant and you're using a non-conventional naming (lowercase)

Take a look at this issue and Vlad Mihalcea's long explanation of the performance penalty.

If you’re using non-conventional Java constants, then you’ll have to set the hibernate.query.conventional_java_constants configuration property to false. This way, Hibernate will fall back to the previous behavior, treating any expression as a possible candidate for a Java constant.



来源:https://stackoverflow.com/questions/59543649/querysyntaxexception-with-enum

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!