簡體   English   中英

JPA CriteriaQuery 查詢每個實體的最新數據

[英]JPA CriteriaQuery Query latest data of each entity

我有一個使用 SpringBoot 1.5.9 的項目(無法更改版本)。

我有這些實體:

@Entity
@Table(name = "data")
public class DataEntity extends Timestampable {

    @Column(name = "value")
    private String value;

    @Column(name = "data_timestamp")
    private ZonedDateTime dataTimestamp;

    @ManyToOne
    @JoinColumn
    private DataTypeEntity type;

    @ManyToOne
    @JoinColumn
    private AssetEntity asset;
}

@Entity
@Table(name = "data_type")
public class DataTypeEntity extends Timestampable {

    @Column(name = "name", unique = true)
    private String name;

    ...
}

我有這個工作 SQL 查詢(在 PostgreSQL 下),以檢索每個資產的最新數據():

SELECT * FROM data d1
JOIN (
  SELECT max(data_timestamp) as newest, asset_id FROM data
  GROUP BY asset_id
) d2
ON d1.data_timestamp = d2.newest AND d1.asset_id = d2.asset_id
WHERE d1.type_id IN (
  SELECT id FROM data_type
  WHERE name = 'ELECTRICITY_CONSUMPTION'
);

我想將此查詢轉換為 JPA CriteriaQuery。 有沒有辦法這樣做,或者我是否需要在特定實體上使用 @SubSelect 注釋?

感謝您閱讀本文!

(丑)解決方案

我最終使用了一個帶有 SubSelect 的數據庫視圖。 我已將我的 DataEntity 拆分為 2 個實體:

  1. 一種操作數據
  2. 另一個視圖,僅用於檢索最新數據

基類:

@MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractDataEntity extends Timestampable {

    @Column(name = "value")
    protected String value;

    ...

}

操作類:

@Entity
@SequenceGenerator(name = "idgen", sequenceName = "data_seq")
@Table(name = "data")
@DiscriminatorValue("DataEntity")
public class DataEntity extends AbstractDataEntity {
    @Override
    public DataEntity setValue(String value) {
        super.setValue(value);
        return this;
    }

   ...
}

查看類:

@Entity
@Immutable
@SequenceGenerator(name = "idgen", sequenceName = "view_data_last_seq")
@DiscriminatorValue("LastDataView")
@Subselect(
    "SELECT * FROM data d1 " +
    "JOIN ( " +
    "  SELECT max(d.data_timestamp) as newest, d.asset_id, d.type_id FROM data d " +
    "  WHERE d.parameter_id IS NULL " +
    "  GROUP BY d.asset_id, d.type_id" +
    ") d2 " +
    "ON d1.data_timestamp = d2.newest " +
    "  AND d1.asset_id = d2.asset_id " +
    "  AND d1.type_id = d2.type_id"
)
public class LastDataView extends AbstractDataEntity {
}

即使我覺得這個解決方案很難看,它也可以幫助其他人!

JPQL 不支持FROMJOIN上的子查詢。 僅在WHEREHAVING子句中。 從 2.4 開始, Eclipse Link 支持FROM子句上的子查詢。

由於每個 Criteria 都轉換為 JPQL ,因此不可能使用 Criteria 來做您想做的事。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM