[英]JPA CriteriaQuery Query latest data of each entity
I have a project that uses SpringBoot 1.5.9 (can't change version).我有一个使用 SpringBoot 1.5.9 的项目(无法更改版本)。
I have these entities :我有这些实体:
@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;
...
}
I have this working SQL query (under PostgreSQL), to retrieve the latest data per asset ( source ):我有这个工作 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'
);
I want to translate this query into a JPA CriteriaQuery.我想将此查询转换为 JPA CriteriaQuery。 Is there a way to do so, or do I need to use a @SubSelect annotation on a specific entity ?有没有办法这样做,或者我是否需要在特定实体上使用 @SubSelect 注释?
Thanks for reading this !感谢您阅读本文!
(UGLY) SOLUTION (丑)解决方案
I ended up using a database View, with a SubSelect.我最终使用了一个带有 SubSelect 的数据库视图。 I've split my DataEntity into 2 entities :我已将我的 DataEntity 拆分为 2 个实体:
Base class :基类:
@MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractDataEntity extends Timestampable {
@Column(name = "value")
protected String value;
...
}
Manipulation class :操作类:
@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;
}
...
}
View class :查看类:
@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 {
}
Even if I find this solution ugly, it may help others !即使我觉得这个解决方案很难看,它也可以帮助其他人!
JPQL does not support subqueries on FROM
or JOIN
. JPQL 不支持FROM
或JOIN
上的子查询。 Only in WHERE
or HAVING
clauses.仅在WHERE
或HAVING
子句中。 Eclipse Link, starting from 2.4 , have support for subqueries on the FROM
clause. 从 2.4 开始, Eclipse Link 支持FROM
子句上的子查询。
As every Criteria is converted to the JPQL , it's not possible to use Criteria to do what you want.由于每个 Criteria 都转换为 JPQL ,因此不可能使用 Criteria 来做您想做的事。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.