I have a "Pet" domain and a "Person" domain, a person may have a pet. Using QuerydslPredicate on my RestController, I would like to return only the persons that have a Pet of type "DOG".
Pet.java
@Entity
public class Pet {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Enumerated(EnumType.STRING)
@Column(nullable = false, name = "animal_type")
private AnimalType type;
// constructors & getters/setters
}
enum AnimalType {
DOG, CAT
}
Person.java
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String surname;
@OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
@JoinColumn(name = "pet_id")
private Pet pet;
// constructors & getters/setters
}
PersonController.java
@RestController
@RequestMapping("persons")
public class PersonController {
@Autowired
private PersonRepository personRepository;
@GetMapping
public List<Person> getAll(@QuerydslPredicate(root = Person.class) Predicate predicate)
{
return (List<Person>) personRepository.findAll(predicate);
}
}
PersonRepository.java
public interface PersonRepository extends JpaRepository<Person, Long>, QuerydslPredicateExecutor<Person> {
}
I'd like to query only persons that have a dog with a GET request like this:
localhost:8080/persons?pet.type=DOG
But this renders the following error:
{
"timestamp": "2019-04-09T18:11:23.430+0000",
"status": 500,
"error": "Internal Server Error",
"message": "Could not access method: Class org.springframework.util.ReflectionUtils can not access a member of class com.example.demo.domain.QPerson with modifiers \"protected\"",
"path": "/persons"
}
Querying for people named "Tom" works fine though using localhost:8080/persons?name=Tom
.
I have this repo available here.
I have already tried solutions from this, this, this, and this stackoverflow questions, but haven't being able to make it work yet.
Just change your querydsl.entityAccessors
property in your pom.xml
to false
(or remove it, the default value is false
).
Why this is happening?
In your pom.xml
, you have the following configuration:
<querydsl.entityAccessors>true</querydsl.entityAccessors>
This option makes your relationships being created as protected
methods in your class, hence your error (https://github.com/querydsl/querydsl/blob/master/querydsl-codegen/src/main/java/com/querydsl/codegen/EntitySerializer.java#L211).
if (config.useEntityAccessors()) {
writer.protectedField(queryType, field.getEscapedName());
} else {
writer.publicFinal(queryType, field.getEscapedName());
}