0

次のエンティティがあるとします。

@Entity
@Table(name="ORDER_ITEM")
public class Order {

    @Id
    @Column(name = "ORDER_ID")
    private Long id;

    @Column(name = "ORDER_VALUE")
    private BigDecimal value;

    @Temporal(TemporalType.TIMESTAMP)
    @DateTimeFormat(style = "M-")
    @Column(name = "CREATED_AT", columnDefinition = "date")
    private Date createdAt;

    @Column(name = "HOURS_MAX")
    private Integer hoursMax = 24;


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public BigDecimal getValue() {
        return value;
    }

    public void setValue(BigDecimal value) {
        this.value = value;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public Integer getHoursMax() {
        return hoursMax;
    }

    public void setHoursMax(Integer hoursMax) {
        this.hoursMax = hoursMax;
    }

    @Override
    public String toString() {
        return "Order{" +
                "id=" + id +
                ", value=" + value +
                ", createdAt=" + createdAt +
                ", hoursMax=" + hoursMax +
                '}';
    }
}

だから私は、hoursMax整数フィールドの最大期間のcreateAt日付フィールドによって制限する注文の基準クエリを作成する必要があります。以下の例のように、Date インスタンス java から整数リテラル値を時間単位で引いたものを使用する例がたくさんあります。

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Order> cq = cb.createQuery(Order.class);
    Root<Order> orderRoot = cq.from(Order.class);

    Calendar c = Calendar.getInstance();
    c.add(Calendar.HOUR_OF_DAY, -24);

     cq.select(orderRoot).where(
            cb.greaterThan(orderRoot.get(Order_.createdAt) ,c.getTime())
     );

    TypedQuery<Order> query = em.createQuery(cq);
    List<Order> result = query.getResultList();

しかし、この場合、この最大期間を表すフィールドhoursMaxを使用する必要があります???? 下 ?

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Order> cq = cb.createQuery(Order.class);
    Root<Order> orderRoot = cq.from(Order.class);

    cq.select(orderRoot).where(
            cb.greaterThan(orderRoot.get(Order_.createdAt) , ??? )
    );

    TypedQuery<Order> query = em.createQuery(cq);
    List<Order> result = query.getResultList();

注: また、hoursMax に対して追加の事前クエリを実行することは避けたいと考えています。

4

1 に答える 1

0

まあ、私はそれに対する回避策を見つけましたが、実装がデータベース固有のプロバイダーに依存するため、より良い解決策があるかどうかはわかりません。

この場合、次の例のように hibernate の @Formula を使用しました。

注:答えを簡単にするために、GETTERSとSETTERSを省略しています。

h2 データベース用。

@Entity
@Table(name="ORDER_ITEM")
public class Order {

    @Id
    @Column(name = "ORDER_ID")
    private Long id;

    @Column(name = "ORDER_VALUE")
    private BigDecimal value;

    @Temporal(TemporalType.TIMESTAMP)
    @DateTimeFormat(style = "M-")
    @Column(name = "CREATED_AT", columnDefinition = "date")
    private Date createdAt;

    @Column(name = "HOURS_MAX")
    private Integer hoursMax = 24;

    @Formula("DATEADD('HOUR',HOURS_MAX *(-1), CURRENT_DATE())")
    private Date createSinceLimitHours;

}

Oracle 11g ダイアレクトがまだないため、Oracle データベースの場合はそれほど単純ではありません。詳細については、こちらを参照してください。

最後に、新しいフィールドを使用して基準を作成します。

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Order> cq = cb.createQuery(Order.class);
Root<Order> orderRoot = cq.from(Order.class);

cq.select(orderRoot).where(
        cb.greaterThan(orderRoot.get(Order_.createdAt) , orderRoot.get(Order_.createSinceLimitHours))
);

TypedQuery<Order> query = em.createQuery(cq);
List<Order> result = query.getResultList();
于 2015-08-13T21:54:43.330 に答える