java标准继承:按子字段联接和搜索

ecr0jaav  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(226)

我有根实体:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity(name = "applications")
public class Application {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToOne(cascade = CascadeType.REFRESH)
    private Customer customer;
}

与父抽象实体相关的:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity(name = "customers")
public abstract class Customer {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;
}

还有子实体:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class SpecificCustomer extends Customer {
    private String title;
}

我尝试搜索字段:

@Service
@RequiredArgsConstructor
public class UserSearchRepository {

    private final EntityManager entityManager;
    private final PredicateUtils predicate;

    public void search() {
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Application> criteriaQuery = criteriaBuilder.createQuery(Application.class);
        Root<Application> root = criteriaQuery.from(Application.class);
        Join<Application, Customer> applicationCustomerJoin = root.join(Application_.CUSTOMER, JoinType.LEFT);
        Predicate[] predicates = {
                predicate.like(applicationCustomerJoin.get(Customer_.NAME), "some name") // it works
                // predicate.like(applicationCustomerJoin.get(SpecificCustomer_.TITLE), "some title") // it doesn't work

        };
        criteriaQuery.select(root).where(predicates);
        TypedQuery<Application> query = entityManager.createQuery(criteriaQuery);
        List<Application> result = query.getResultList();

        System.out.println("test:");
        System.out.println(result);
    }

    @PostConstruct
    void init() {
        this.search();
    }
}

当我按父级中存在的字段搜索时,它起作用:

predicate.like(applicationCustomerJoin.get(Customer_.NAME), "some name")

但当我从child按字段搜索时,它不起作用:

predicate.like(applicationCustomerJoin.get(SpecificCustomer_.TITLE), "some title")

例外情况:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userSearchRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Unable to locate Attribute  with the the given name [title] on this ManagedType [my.Customer]
...
Caused by: java.lang.IllegalArgumentException: Unable to locate Attribute  with the the given name [title] on this ManagedType [my.Customer]
    at my.UserSearchRepository.search(UserSearchRepository.java:32) ~[classes/:na]

我不能改变模型的设计。

6za6bjd0

6za6bjd01#

我发现我可以用这个方法 treat 在第一个联接上,创建具有特定类型的第二个联接:

Join<Application, Customer> applicationCustomerJoin = root.join(Application_.CUSTOMER, JoinType.LEFT);
Join<Application, SpecificCustomer> applicationSpecificCustomerJoin = criteriaBuilder.treat(applicationCustomerJoin, SpecificCustomer.class);
Predicate[] predicates = {
        predicate.like(applicationSpecificCustomerJoin.get(SpecificCustomer_.TITLE), "some title")
};

相关问题