I have a class in the following form.
@Entity
public class Person{
public enum SEX {
MALE, FEMALE, OTHER
}
private String name;
private SEX sex;
}
And I have an interface class which extends the JpaRepostory. The enum doesn't work in the query. I am trying to using Spring JPA for fetchig the data.
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,);
}
I get the following exception
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Invalid path: 'com.example.Person.Sex.MALE'
How can I fix it ?
You're not respecting the case of your classes and attributes. It should be
p.sex = com.example.Person.SEX.MALE
Beyond the case errors which have already been mentioned, there is another problem: your enum class is a nested class. And a third problem is that Hibernate seems to have problems with capitalized class names, i.e. you need to change the class name from SEX to Sex.
Define the enum as a top-level class in package com.example
package com.example;
public enum Sex {
MALE, FEMALE, OTHER
}
and then you can access an enum value from the repository using e.g. 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);
}
Surprisingly (a bug?) this will end up with an error if you change the name of the enum from Sex to SEX (while adjusting the name in the query obviously).
You could keep the definition of Sex as a nested class. The enum is then compiled into the class with the name Person$Sex.class. Simply use this name in the query string:
@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;
}
}
The repository then needs to be written as
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);
}
Once again, if you change the name of the nested class fom Sex to SEX (also in the query string) then an exception with the text
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]
is thrown, although the generated byte code is stored in class Person$SEX.class.