【问题标题】:Alternative solution to nonexisting limit in JOIN ... WITH clauseJOIN ... WITH 子句中不存在限制的替代解决方案
【发布时间】:2015-10-30 10:29:42
【问题描述】:

我需要对以下场景进行建模:实体具有可能随时间变化的值,我需要保留所有历史值。例如我有实体文章,它有标题。如果文章是在 2015 年 1 月 1 日创建的,它将获得标题“标题 1”,然后,在 2015 年 2 月 1 日,有人将标题更改为“标题 2”,3 月 1 日,标题更改为“标题 3”。我想问“2015 年 2 月 20 日的文章标题是什么?”

为此,我创建了具有标题列表的 Article 实体:

@Entity
public class Article {
    @Id
    private Long id;
    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL)
    private List<ArticleTitle> title = new LinkedList<>();

    //Setters and getters are here
}

标题如下所示:

@Entity
public class Title extends DateDependentEntity<Title> {
    @NotNull
    private String title;
}

DateDependentEntity 看起来像这样(我有很多)

@MappedSuperclass
public abstract class DateDependentEntity<PARENT> {
    @Id
    private Long id;
    @Column(nullable = false)
    private LocalDate validFrom;
    @ManyToOne
    private PARENT parent;
}

一切正常,我创建了保存和读取这些实体的方法(例如“给我文章,其中 id = 1,值在 20. 2. 2015 有效”)。

但我无法根据日期确定 HQL 过滤器查询,例如“给我所有在 '20. 2. 2015' 上标题包含 'dog' 的文章”。

首先,我会使用这样的东西:

SELECT DISTINCT a FROM Article a JOIN a.title at WITH (at.validFrom <= :date)  WHERE at.title LIKE :title

但这并不总是返回预期的结果 - 如果 1 月份的标题是“我们爱狗”和 2 月份以来的“我们喜欢猫”,并且我在 3 月份过滤了包含狗的值,它仍然会找到这篇文章。据我所知,我不能在 WITH 子句中使用某种限制,对吗?

所以我虽然会使用子查询,但在 HQL 中不支持 LIMIT,所以问题与上面的 JOIN 相同。

是否有一些 HQL 查询可以解决我的问题,或者我的模型完全错误?

【问题讨论】:

  • 您可以通过在标题中额外引入 validUntil 列来扩展您的模型,当标题当前有效时该列将为空,然后将其包含到您的 Join 的 where 子句中......
  • 这是我想避免的数据冗余 - 错误地更新 validUntil 列会导致数据库不一致。

标签: java hql


【解决方案1】:

在整天摆弄 HQL 之后(在意识到 IntelliJ 将我的查询标记为语法不正确后,尽管查询有效),我想出了这个:

SELECT at.parent FROM ArticleTitle at 
WHERE at.title LIKE :title AND (at.validFrom, at.parent) IN (
    SELECT max(at2.validFrom), at2.parent FROM ArticleTitle at2 
    WHERE at2.validFrom <= :date GROUP BY at2.parent
);

现在就可以了,虽然只针对一个字段的查询大小让我感到害怕,但我认为对于给定的模型它不会变得更简单。时间会证明这在实践中是否可用。

【讨论】:

    猜你喜欢
    • 2015-09-06
    • 2017-12-10
    • 1970-01-01
    • 2015-03-03
    • 2011-04-13
    • 2016-10-24
    • 2011-10-16
    • 2020-08-29
    • 1970-01-01
    相关资源
    最近更新 更多