覆盖JPA @Embedded列上的排序行为

时间:2012-05-03 12:41:16

标签: java jpa

我有一个实体类,其中包含一个嵌入对象:

@Entity
public class Flight implements Serializable {

    /// .... other attributes
    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name = "value", column =
        @Column(name = "FLIGHT_TIME")),
        @AttributeOverride(name = "dataState", column =
        @Column(name = "FLIGHT_TIME_TYPE", length = 20))
    })
    private DateDataStateValue flightDate;
}

DateDataStateValue如下:

@Embeddable
public class DateDataStateValue implements DataStateValue<Date>, Serializable {

    private static final long serialVersionUID = 1L;

    @Column(name = "DATASTATE")
    @Enumerated(value = EnumType.STRING)
    private final DataState dataState;

    @Column(name = "DATAVALUE")
    @Temporal(TemporalType.TIMESTAMP)
    private final Date value;
}

使用CriteriaQuery从数据库中获取Flights时,并在时间列上创建Order对象:

Path<Flight> propertyPath = queryRoot.get("flightDate");
Order order = isAscending() ? criteriaBuilder.asc(propertyPath) :  criteriaBuilder.desc(propertyPath);

订购不是我想要的。例如,如果航班表具有以下值:

Flight 1  | ESTIMATED | 1 Jan 2012
Flight 2  | ESTIMATED | 1 Jan 2011
Flight 3  | ACTUAL    | 1 Jan 2010
Flight 4  | ESTIMATED | 1 Jan 2009

升序排序的结果将是:

Flight 3  | ACTUAL    | 1 Jan 2010
Flight 4  | ESTIMATED | 1 Jan 2009
Flight 2  | ESTIMATED | 1 Jan 2011
Flight 1  | ESTIMATED | 1 Jan 2012

@Embedded列的默认排序似乎是按照它们在类中命名的顺序使用元素的自然顺序。即首先是DATASTATE,然后是DATAVALUE秒。

我想做的是每当sort属性为flightDate时,排序首先是日期,然后是状态,即:

Flight 4  | ESTIMATED | 1 Jan 2009
Flight 3  | ACTUAL    | 1 Jan 2010
Flight 2  | ESTIMATED | 1 Jan 2011
Flight 1  | ESTIMATED | 1 Jan 2012

使DateDataStateValue具有可比性并不影响它,@ orderColumn / @ OrderBy似乎不适合这项工作。有没有人有任何想法?

提前致谢。

2 个答案:

答案 0 :(得分:0)

我甚至不知道你可以通过查询在这样的可嵌入属性上添加订单。但我不会依赖它,只需在查询中添加两个订单:

Path<Flight> statePath = queryRoot.get("flightDate.dateState"); // or queryRoot.get("flightDate").get("dateState"): to be tested
Path<Flight> valuePath = queryRoot.get("flightDate.value");
Order[] orders;
if (isAscending()) {
    orders = new Order[] {criteriaBuilder.asc(valuePath), criteriaBuilder.asc(statePath)  };
}
else {
    orders = new Order[] {criteriaBuilder.desc(valuePath), criteriaBuilder.desc(statePath)  
}

query.orderBy(orders);

答案 1 :(得分:0)

也许像"flightDate.value ASC, flightDate.dataState ASC"这样的东西,因为你所定义的只是“flightDate”,这意味着该对象的自然排序