使用Spring JPA从关联列表中获取最后一个条目

时间:2015-07-31 10:13:40

标签: java spring hibernate jpa jpql

我有一个关于Spring JPA(JPQL和排序)的问题。 一直在寻找我的屁股,我似乎无法找到答案。 如果有任何重复,请告诉我。我没有遇到符合我需求的问题/教程/指南。

好的,所以我用JPA获得了Spring。我有2个实体。 资产和资产状况。资产可以有多个AssetStatus,一个AssetStatus属于一个Asset。

实体构建如下。我省略了不需要的属性。

资产:

@Entity
@Table(name = "T_ASSET")
public class Asset implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToMany(mappedBy = "asset", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
    private List<AssetStatus> assetStatus;
}

AssetStatus:

@Entity
@Table(name = "T_ASSETSTATUS")
public class AssetStatus implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @NotNull
    @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
    @JsonSerialize(using = CustomLocalDateTimeSerializer.class)
    @JsonDeserialize(using = CustomLocalDateTimeDeserializer.class)
    @Column(name = "timestamp", nullable = false, insertable = true, updatable = true)
    private LocalDateTime timestamp;

    @JsonIgnore
    @NotNull
    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Asset asset;
}

我得到了一个标准的AssetRepository。 (忽略条形码查找,它是资产中省略的属性。)

public interface AssetRepository extends JpaRepository<Asset, Long>, QueryDslPredicateExecutor<Asset> {

    Asset findOneByBarcode(String barcode);
}

现在,我希望获得所有资产,以及他们拥有的最后一个AssetStatus。这由AssetStatus中的时间戳定义。获取所有资产但我也获得了他们拥有(或拥有)的所有AssetStatuses。我只想要最新的。

我如何设法做到这一点?我尝试用@Query编写自定义查询。或者命名一个像findLastAssetStatus()之类的方法。一切都行不通。

有人可以帮我解决这个问题吗?我愿意提供更多信息并回答任何问题。

编辑:我在MySQL中发现了查询以获得想要的结果(在我的数据库中使用MySQL Workbench):

SELECT * FROM T_ASSET asset JOIN T_ASSETSTATUS assetStatus WHERE asset.id = assetStatus.asset_id AND assetStatus.timestamp = (SELECT max(timestamp) FROM T_ASSETSTATUS WHERE asset_id = asset.id);

当我在我的AssetRepository中使用@query nativequery = true(如下所述)时,它不会给我想要的结果。这仍将为我提供它曾经拥有的每一个资产状态的每个状态。

@Query(value = "SELECT * FROM T_ASSET asset JOIN T_ASSETSTATUS assetStatus WHERE asset.id = assetStatus.asset_id AND assetStatus.timestamp = (SELECT max(timestamp) FROM T_ASSETSTATUS WHERE asset_id = asset.id)", nativeQuery = true)
List<Asset> findAssetWithlastStatus();

如何在JPQL中编写此查询?或者以其他任何方式解决这个问题?

提前致谢!

干杯,克莱门兹

1 个答案:

答案 0 :(得分:0)

您可以查看Hibernate filters。编写一个过滤器,用于过滤掉旧状态,并在要应用它的会话中启用它。