带有枚举的 QuerySyntaxException

QuerySyntaxException with enum

我有一个像这样的 UserAssignmentRole class :

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

角色是枚举,看起来像这样:

public enum Role{
    admin,
    member,
    pending
}

现在,当我在我的存储库中尝试以管理员角色查询 select 时,它给我错误:

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

如何解决?

错误:org.hibernate.hql.internal.ast.QuerySyntaxException:无效路径:'Role.admin'

完全错误:https://pastebin.com/tk9r3wDg

你可以尽量不要自己写这个sql,而是用存储库创建这样的代码:

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

    public List<UserAssignmentRole> findByRole(Role role);

}

然后:

@Autowired
UserAssignmentRolelRepository repository ;

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

更新 1

正如指出的那样:非常规命名。您可以将枚举中的标签更改为大写。

public enum Role{
    Admin,
    Member,
    Pending
}

然后:

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

更新 2

但是如果你真的想在数据库中使用小写。 它需要更多代码才能更改。枚举更改为:

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;
    }
}

UserAssignmentRole

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

还有额外的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);
    }
}

从 5 开始,这是 Hibernate 的一种奇怪但有意为之的行为。2.x 枚举值是常量,您使用的是非常规命名(小写)

看看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.