我有一个 entity hierarchy像这样。除了一些公共(public)属性之外,还有一些属性仅由少数子类型共享:
@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> {
}
使用 QueryDSL,我尝试根据动态过滤条件搜索人员,如下所示:
@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);
}
}
这似乎不是正确的方法,但是,我收到了很多错误,例如“salary”不是 Person 的成员。
处理分层实体搜索的各种方法有哪些?我更喜欢 QueryDSL 来保证类型安全,但使用 Spring Data 规范的解决方案也可以。
编辑:使用超过 15 个不同的搜索条件,搜索条件可能会变得非常复杂。因此,我需要一种编程方法来制定它们。
最佳答案
我无法重现“不是 Person 的成员”错误,但我已设法从您的查询中获取结果。
已关注 Baeldung's tutorial并根据您的问题调整代码,我成功地得到了没有错误的结果。 Here是示例项目。希望这有帮助
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;
}
}
关于java - 如何使用querydsl或spring data jpa规范对分层实体执行查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60338276/