java - 如何使用querydsl或spring data jpa规范对分层实体执行查询?

标签 java hibernate spring-data-jpa querydsl

我有一个 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/

相关文章:

java - 在 Java 中调用 Grep 会给出错误的结果,而在 shell 中调用 grep 会给出正确的结果

Java - 编写 XSL-FO 的方法

java - iinc在Java中是原子的吗?

java - Hibernate Custom 查询可以返回 Map 而不是 List 吗?

java - 使用 servlet 和 Hibernate 技术将图像存储到 MySql 数据库并检索它并在 Jsp 中显示的源代码

java - 使用 spring data jpa 更新单个字段

java - 了解以毫秒为单位的 XMLGregorianCalendar/GregorianCalendar 时间

hibernate - Grails/GORM延迟加载CLOB字段

java - 事务注释不能解决 org.hibernate.LazyInitializationException

java - 如何使用 spring data jpa 将审计行添加到审计表