【发布时间】:2020-06-05 20:40:15
【问题描述】:
我有一个像这样的entity hierarchy。除了一些公共属性外,一些属性仅由少数子类型共享:
@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 我正在尝试根据动态过滤条件搜索 Persons,如下所示:
@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);
}
}
这似乎不是正确的方法,但是,我遇到了很多错误,例如“薪水”不是 Person 的成员。
处理分层实体搜索的各种方法是什么?我更喜欢 QueryDSL 的类型安全,但使用 Spring Data Specification 的解决方案也可以。
edit:使用超过 15 种不同的搜索条件,搜索条件可能会变得非常复杂。所以我需要一种程序化的方法来制定它们。
【问题讨论】:
-
我在这里stackoverflow.com/questions/60243712/…回答了类似的问题
-
您可以使用 JPA 元模型使 Criteria api 类型安全
-
@alexvaluiskyi 使用平面对象的规范 api 是没有问题的。我的问题是我的实体的层次结构,这使得标准更加复杂。我需要将谓词转换为 hibernate 不喜欢的多个子类型。
-
这里的问题不是只有 Employee 和 BoardMember 实体知道薪水,因此对于 PersonRepository,它是一个未知字段吗?
-
@ManuelJain 是的,这就是hibernate拒绝执行查询的问题。那么我如何使用 querydsl 或条件 api 以编程方式在这些字段上创建查询?有一些方法可以将 QEntities “转换”为它们的子类型 (querydsl.com/static/querydsl/latest/reference/html/ch03.html),但这似乎不起作用。
标签: java hibernate spring-data-jpa querydsl