子类属性的Hibernate JPA过滤器

问题描述

我有以下JPA实体,

@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@discriminatorColumn(name = "type",discriminatorType = discriminatorType.STRING)
public abstract class OrderItem {

    // some inherited fields

}
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@discriminatorValue("TYPE1")
public class OrderItemTypeOne extends OrderItem {

    @OnetoOne(mappedBy = "orderItem")
    @JsonManagedReference
    private SomeTypeA a;

}
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@discriminatorValue("TYPE2")
public class OrderItemTypeTwo extends OrderItem {

    @OnetoOne(mappedBy = "orderItem")
    @JsonManagedReference
    private SomeTypeB b;

}

我想执行一个查询,该查询为我提供所有OrderItem,其中一个JPA查询中a ='a'(对于OrderItemTypeOne)和b ='b'(对于OrderItemTypeTwo)。我该如何实现?到目前为止,我有查询,但它在运行时提供了sqlGrammarException。

@Query("SELECT oi FROM OrderItem oi "
            + "LEFT JOIN OrderItemTypeOne t1 "
            + "LEFT JOIN OrderItemTypeTwo t2 "
            + "WHERE t1.a = :a "
            + "AND t2.b = :b")
Page<OrderItem> findOrders(@Param("a") String a,@Param("b") String b);

我尝试过使用这种方法

@Query("SELECT oi FROM OrderItem oi "
            + "WHERE treat(oi as OrderItemTypeOne).a = :a "
            + "AND treat(oi as OrderItemTypeTwo).b = :b")
Page<OrderItem> findOrders(@Param("a") String a,@Param("b") String b);

但是这不起作用,因为treat()仅在我提供子属性(例如treat(oi.someOtherProperty as SomeOtherType))时起作用。

任何指导将不胜感激!

解决方法

我怀疑您应该在这里使用or条款而不是and

 select oi 
 from OrderItem oi 
 where treat(oi as OrderItemTypeOne).a=:a or treat(oi as OrderItemTypeTwo).b=:b

使用and子句时,您什么也不会得到,因为OrderItem不能同时是OrderItemTypeOneOrderItemTypeTwo的实例。

另一种方法是通过这种方式使用交叉联接

select oi 
from OrderItem oi,OrderItemTypeOne t1,OrderItemTypeTwo t2
where (oi.id=t1.id or oi.id=t2.id) and (t1.a=:a or t2.b=:b)

其中oi.id-OrderItem id字段名称

,

使用以下内容:

@Query("SELECT oi FROM OrderItem oi "
            + "WHERE oi.a = :a "
            + "OR oi.b = :b")
Page<OrderItem> findOrders(@Param("a") String a,@Param("b") String b);