Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用querydsl或spring数据jpa规范对分层实体执行查询?_Java_Hibernate_Spring Data Jpa_Querydsl - Fatal编程技术网

Java 如何使用querydsl或spring数据jpa规范对分层实体执行查询?

Java 如何使用querydsl或spring数据jpa规范对分层实体执行查询?,java,hibernate,spring-data-jpa,querydsl,Java,Hibernate,Spring Data Jpa,Querydsl,我有一个像这样的梦。除了一些常见属性外,一些属性仅由少数子类型共享: @Entity @Inheritance(strategy = InheritanceType.JOINED) public class Person { private String firstName; private String lastName ... further properties, getters and setters... } @Entity public class Emp

我有一个像这样的梦。除了一些常见属性外,一些属性仅由少数子类型共享:

@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> {

}
@实体
@继承(策略=InheritanceType.JOINED)
公共阶层人士{
私有字符串名;
私有字符串lastName
…进一步的属性、getter和setter。。。
}
@实体
公共类雇员扩展个人{
私人串薪;
…进一步的属性、getter和setter。。。
}
@实体
公共类董事会成员{
私人串薪;
…进一步的属性、getter和setter。。。
}
@实体
公共类ExternalMember扩展了Person{
私有字符串清除级别;
…进一步的属性、getter和setter。。。
}
@存储库
公共接口PersonRepository扩展了JpaRepository、QueryDSL谓词执行器{
}
使用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);
  }
}
@服务
@交易的
公共类人员服务{
@自动连线
个人知识库;
公共页面搜索(字符串firstName,字符串salary){
var searchCriterias=new BooleanBuilder();
if(firstName!=null){
和(QPerson.firstName.eq(firstName));
}
如果(工资!=null){
安达尼奥夫搜索标准(
QPerson.person.as(QEmployee.class).salary.eq(salary),
QPerson.person.as(QBoardMember.class).salary.eq(salary),
);
}
personRepository.findAll(搜索标准);
}
}
这似乎不是正确的方法,然而,我得到了很多错误,比如“薪水”不是一个人的成员

处理层次实体搜索的各种方法有哪些?为了类型安全,我更喜欢QueryDSL,但使用Spring数据规范的解决方案也可以

编辑:使用15个以上不同的搜索标准,搜索标准可能会变得非常复杂。因此,我需要一种程序化的方法来表述它们。

我无法重现“not a member of Person”错误,但我已设法从您的查询中获得结果

按照您的问题中的代码进行修改,我已经成功地获得了没有错误的结果。这是一个示例项目。希望这有帮助

import javax.persistence.*;
@实体
@继承(策略=InheritanceType.JOINED)
公共阶层人士{
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
私有int-id;
@纵队
私有字符串名;
@纵队
私有字符串lastName;
公众人物(字符串名、字符串名){
this.firstName=firstName;
this.lastName=lastName;
}
公众人士(){
}
}
import javax.persistence.Column;
导入javax.persistence.Entity;
@实体
公共类董事会成员{
@纵队
私人串薪;
公共董事会成员(字符串firstName、字符串lastName、字符串salary){
超级(名字,姓氏);
这个。薪水=薪水;
}
公共董事会成员(){
}
}
@服务
@交易的
公共类人员服务{
@自动连线
个人知识库;
公共列表搜索(字符串firstName,字符串salary){
var searchCriterias=new BooleanBuilder();
if(firstName!=null){
搜索标准和(QPerson.person.firstName.eq(firstName));
}
如果(工资!=null){
安达尼奥夫搜索标准(
QPerson.person.as(QEmployee.class).salary.eq(salary),
QPerson.person.as(QBoardMember.class).salary.eq(salary)
);
}
var result=new ArrayList();
for(Person:personRepository.findAll(searchCriterias)){
结果:增加(人);
}
返回结果;
}
}

我在这里回答了类似的问题,您可以使用JPA元模型来创建标准api类型-safe@alexvaluiskyi为平面对象使用规范api是无故障的。我的问题是实体的层次结构,这使得标准更加复杂。我需要将谓词强制转换为多个子类型,这是hibernate不喜欢的。这里的问题不是只有实体员工和董事会成员才知道工资,因此对于PersonRepository来说它是一个未知字段吗?@ManuelJain是的,这就是hibernate拒绝执行查询的原因。那么,如何使用querydsl或criteria api以编程方式在这些字段上创建查询呢?有很多方法可以将QEntity“强制转换”到它们的子类型(),但这似乎不起作用。谢谢您的努力。不幸的是,这不起作用。的确,没有hibernate异常,但搜索无法正常工作,可能是因为有两个salary属性会混淆QueryDSL或hibernate。调试应用程序时,谓词如下所示:
person.salary eq“salary”| | person.salary eq“salary”
,它无法区分不同的子类型。由于悬赏即将到期,我将它授予您,因为您提供了最接近的答案并付出了很大努力。但我无法确定标记是否正确,因为搜索工作不正常,我不想用同样的问题混淆其他人。