Spring Data JPA规范继承 [英] Spring Data JPA Specification Inheritance

查看:94
本文介绍了Spring Data JPA规范继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有三个实体,如下所示:

I've three entities as shown below:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "type")
public abstract class Employee {
    @Id
    protected Long id;
    ...
}

@Entity
public class FullTimeEmployee extends Employee {
    protected Integer salary;
    ...
}

@Entity
public class PartTimeEmployee extends Employee {
    protected Float hourlyWage;
}

我尝试使用Spring Data Specification进行查询,如下所示:

And i trying query using Spring Data Specification, as shown:

我的Spring数据托管存储库:

My Spring data managed repository:

@Repository
public interface EmployeeRepository<T extends Employee> extends JpaRepository<T, Long> {
    Page<T> findAll(Specification<T> specification, Pageable pageable);
}

还有我的样品控制器

@Controller
public class MyController {
    private final EmployeeRepository employeeRepository;

    @Autowired
    public MyController(EmployeeRepository employeeRepository) {
        this.employeeRepository = employeeRepository;
    }

    @GetMapping("/")
    public ModelAndView queryEmployeeExample(EmployeeQueryDTO query) {
        Page response = this.employeeRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
            ArrayList<Predicate> predicates = new ArrayList<>();
            if(query.getId() != null) {
                predicates.add(
                    criteriaBuilder.equal(root.get("id"), query.getId())
                );
            }
            if(query.getSalary() != null) {
                predicates.add(
                    criteriaBuilder.equal(root.get("salary"), query.getSalary())
                );
            }
            if(query.getHourlyWage() != null) {
                predicates.add(
                    criteriaBuilder.equal(root.get("hourlyWage"), query.getHourlyWage())
                );
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        }, new PageRequest(0, 100));

        return new ModelAndView("index")
                    .addObject("result", response);
    }

    @Getter
    @Setter
    static class EmployeeQueryDTO {
        private Long id;
        private Integer salary;
        private Float hourlyWage;
    }
}

我可以使用id执行查询,但是对于其他参数(例如salary和hourlyWage)则不会发生此情况,我会收到此异常:

I can execute the query with the id, but the same does not occur with the other parameters like salary and hourlyWage, i receive this exception:

java.lang.IllegalArgumentException:无法使用 在此ManagedType [Employee]上给定的名称[salary/hourlyWage]

java.lang.IllegalArgumentException: Unable to locate Attribute with the the given name [salary/hourlyWage] on this ManagedType [Employee]

我了解问题是要在超类中查找该字段,而该字段不存在,我想知道是否有解决我问题的方法吗?

I understand that the problem is to look for the field in the superclass and it does not exist, I would like to know if there is a solution to my problem?

致谢.

推荐答案

作为@JBNizet技巧来使用'CriteriaBuilder.treat()':

As @JBNizet tip to use 'CriteriaBuilder.treat()':

@GetMapping("/")
public ModelAndView queryEmployeeExample(EmployeeQueryDTO query) {
    Page response = this.employeeRepository.findAll((root, 
                                                    criteriaQuery, 
                                                    criteriaBuilder) -> {

    ArrayList<Predicate> predicates = new ArrayList<>();

    if(query.getId() != null) {
        predicates.add(
            criteriaBuilder.equal(
                    root.get("id"), 
                    query.getId()
            )
        );
    }
    if(query.getSalary() != null) {
        //Downcast Root object to the specified type.
        Root<FullTimeEmployee> rootFullTImeEmployee = criteriaBuilder
                                        .treat(root, FullTimeEmployee.class);
        predicates.add(
            criteriaBuilder.equal(
                    rootFullTImeEmployee.get("salary"), 
                    query.getSalary()
            )
        );
    }
    if(query.getHourlyWage() != null) {
        //Downcast Root object to the specified type.
        Root<PartTimeEmployee> rootPartTimeEmployee = criteriaBuilder
                                        .treat(root, PartTimeEmployee.class);
        predicates.add(
            criteriaBuilder.equal(
                    rootPartTimeEmployee.get("hourlyWage"), 
                    query.getHourlyWage()
            )
        );
    }
    return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));}, 
                new PageRequest(0, 100));

    return new ModelAndView("index")
                .addObject("result", response);
}

@Getter
@Setter
static class EmployeeQueryDTO {
    private Long id;
    private Integer salary;
    private Float hourlyWage;
}

这篇关于Spring Data JPA规范继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆