【发布时间】: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列会导致数据库不一致。