JOIN ... WITH子句中不存在限制的替代解决方案

时间:2015-10-30 10:29:42

标签: java hql

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

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

@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。给我所有标题包含'dog'的文章.2。2015'”。

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

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查询可以解决我的问题,或者我的模型是否完全出错?

1 个答案:

答案 0 :(得分: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
);

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

相关问题