I'm having an entity hierarchy like this. Besides some common properties, some properties are shared only by a few subtypes:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Person {
private String firstName;
private String lastName
... further properties, getters and setters...
}
@Entity
public class Employee extends Person {
private String salary;
... further properties, getters and setters...
}
@Entity
public class BoardMember extends Person {
private String salary;
... further properties, getters and setters...
}
@Entity
public class ExternalMember extends Person {
private String clearanceLevel;
... further properties, getters and setters...
}
@Repository
public interface PersonRepository extends JpaRepository<Person, Long>, QuerydslPredicateExecutor<Person> {
}
Using QueryDSL I'm trying to search for Persons depending on dynamic filter criterias like this:
@Service
@Transactional
public class PersonService {
@Autowired
PersonRepository personRepository;
public Page<Person> search(String firstName, String salary) {
var searchCriterias = new BooleanBuilder();
if (firstName != null) {
searchCriterias.and(QPerson.firstName.eq(firstName));
}
if (salary != null) {
searchCriterias.andAnyOf(
QPerson.person.as(QEmployee.class).salary.eq(salary),
QPerson.person.as(QBoardMember.class).salary.eq(salary),
);
}
personRepository.findAll(searchCriterias);
}
}
This doesn't seem to be the right way, however, I'm getting a lot of errors like "salary" not a member of Person.
What are the various ways to deal with searches for hierarchical entities? I'd prefer QueryDSL for type-safety, but solutions using Spring Data Specification would be fine as well.
edit: The search criterias could get very complex using 15+ different search criterias. So I need a programmatic approach to formulate them.
I could not reproduce the "not a member of Person" error but I have managed to get the result from your query.
Following Baeldung's tutorial and adapting the code from your question I've managed to get the result without errors. Here is the sample project. Hope this helps
import javax.persistence.*;
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@Column
private String firstName;
@Column
private String lastName;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public Person() {
}
}
import javax.persistence.Column;
import javax.persistence.Entity;
@Entity
public class BoardMember extends Person {
@Column
private String salary;
public BoardMember(String firstName, String lastName, String salary) {
super(firstName, lastName);
this.salary = salary;
}
public BoardMember() {
}
}
@Service
@Transactional
public class PersonService {
@Autowired
PersonRepository personRepository;
public List<Person> search(String firstName, String salary) {
var searchCriterias = new BooleanBuilder();
if (firstName != null) {
searchCriterias.and(QPerson.person.firstName.eq(firstName));
}
if (salary != null) {
searchCriterias.andAnyOf(
QPerson.person.as(QEmployee.class).salary.eq(salary),
QPerson.person.as(QBoardMember.class).salary.eq(salary)
);
}
var result = new ArrayList<Person>();
for (Person person : personRepository.findAll(searchCriterias)) {
result.add(person);
}
return result;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With