有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在JPA查询中包含枚举

我有一节课,形式如下

@Entity
public class Person{
    public enum SEX {
      MALE, FEMALE, OTHER
    }

    private String name;
    private SEX sex;
 }

我有一个接口类,它扩展了JpaRepostory。枚举在查询中不起作用。我正在尝试使用Spring JPA获取数据

public interface PersonRepository extends JpaRepository<Person, Long> {


    @Query("SELECT p FROM Person p WHERE 
            "p.SEX = com.example.Person.Sex.MALE " +
            "AND p.name = :name")
    public List<Person> checkName(@Param("name") String name,);

}

我得到以下例外

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'com.example.Person.Sex.MALE'

我该怎么修


共 (2) 个答案

  1. # 1 楼答案

    除了前面提到的case错误之外,还有另一个问题:enum类是嵌套类。第三个问题是Hibernate似乎对大写的类名有问题,即需要将类名从SEX更改为Sex

    备选案文1:

    将枚举定义为包com.example中的顶级类

    package com.example;
    public enum Sex {
        MALE, FEMALE, OTHER
    }
    

    然后,您可以使用com.example.Sex.MALE从存储库中访问枚举值:

    @Repository
    public interface PersonRepository extends JpaRepository<Person, Long> {
    
        @Query("SELECT p FROM Person p WHERE " + 
                "p.sex = com.example.Sex.MALE " +
                "AND p.name = :name")
        public List<Person> checkName(@Param("name") String name);
    
    }
    

    令人惊讶的是(一只虫子?)如果将枚举的名称从Sex更改为SEX(同时调整查询中的名称),则会出现错误

    备选案文2:

    可以将Sex的定义保留为嵌套类。然后将枚举编译成名为Person$Sex.class的类。只需在查询字符串中使用此名称:

    @Entity
    public class Person {
    
        public enum Sex {
            MALE, FEMALE, OTHER
        }
    
        @Id @GeneratedValue long id;
        private String name;
        private Sex sex;
        
        public Person() {}
        public Person(String name, Sex sex) {
            this.name = name;
            this.sex = sex;
        }
    }
    

    然后需要将存储库编写为

    public interface PersonRepository extends JpaRepository<Person, Long> {
    
        @Query("SELECT p FROM Person p WHERE " + 
                "p.sex = com.example.Person$Sex.MALE " +
                "AND p.name = :name")
        public List<Person> checkName(@Param("name") String name);
    
    }
    

    同样,如果您将嵌套类fomSex的名称更改为SEX(也在查询字符串中),则文本会出现异常

    Invalid path: 'com.example.Person$SEX.MALE' 
       [SELECT p FROM com.example.Person p WHERE p.sex = com.example.Person$SEX.MALE 
                                                                 AND p.name = :name]
    

    抛出,尽管生成的字节码存储在类Person$SEX.class

  2. # 2 楼答案

    你不尊重你的类和属性。应该是的

    p.sex = com.example.Person.SEX.MALE