我正在使用Hibernate与SQL Server 2016/Azure SQL Server进行接口,并且迄今为止一直在与它共享美好时光。在我的数据库中,我实现了系统版本化的时态表。我想通过注释将两个更多变量(最好是懒惰地)映射到我的Hibernate实体,这些实体代表适当表的时间历史记录中的原始ValidFrom和UpdatedBy字段。Hibernate sql注释
例如,我有一个帐户类和表。账户[减去不相关的列,约束等表如下:
CREATE TABLE [dbo].[Account] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[UpdatedBy] INT NOT NULL,
[ValidFrom] DATETIME2 (7) GENERATED ALWAYS AS ROW START DEFAULT (sysutcdatetime()) NOT NULL,
[ValidTo] DATETIME2 (7) GENERATED ALWAYS AS ROW END DEFAULT (CONVERT([datetime2],'9999-12-31 23:59:59.9999999')) NOT NULL,
CONSTRAINT [FK_Account.UpdatedById_Account.Id] FOREIGN KEY ([UpdatedBy]) REFERENCES [dbo].[Account] ([Id]),
PRIMARY KEY CLUSTERED ([Id] ASC),
PERIOD FOR SYSTEM_TIME ([ValidFrom], [ValidTo])
)
WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE=[dbo].[AccountHistory], DATA_CONSISTENCY_CHECK=ON));
的SQL语句来获得我想要看起来像这样的数据(我想,我会每注解只选择UpdatedBy或ValidFrom,但他们现在在一起要简明扼要):
SELECT UpdatedBy, ValidFrom FROM dbo.Account
FOR SYSTEM_TIME ALL
WHERE ValidFrom IN
(
SELECT MIN(ValidFrom) OVER (Partition BY Id) AS ValidFrom
FROM dbo.Account
FOR SYSTEM_TIME ALL
WHERE ID = $(passedInIdOfThisEntity)
)
最后,我的休眠实体/ POJO看起来像这样(再次,redacting无关的变量):
@Entity
@Table(name = "Account")
public class Account implements Serializable {
@Id
@Column(name = "Id", unique = true, nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "UpdatedBy")
private Account updatedBy;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "ValidFrom", nullable = false, length = 27, insertable = false, updatable = false)
private Date validFrom;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "ValidTo", nullable = false, length = 27, insertable = false, updatable = false)
private Date validTo;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "updatedBy")
private Set<Account> accountsUpdated;
// This is a stub of what I'm hoping you can help me add
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "ValidFrom", fetch = FetchType.LAZY, insertable = false, updatable = false, somesqlselect = SQL_STATEMENT_FROM_ABOVE)
private Date createdOn;
@Column(name = "UpdatedBy", fetch = FetchType.LAZY, insertable = false, updatable = false, somesqlselect = SQL_STATEMENT_FROM_ABOVE)
private Account createdBy
// ... getters and setters below
}
我甲肝尽管我已经找到并使用了实现本机查询的例子来检索实体,而不是使用条件查询,但它在很大程度上一直在使用Hibernate,但在查找这方面的信息时遇到了困难。如果你能帮我解决这个谜题,让我继续使用标准查询检索数据并通过需求注释填充这些字段,我将不胜感激。
如果我明白你想要什么,你应该做一个@ManyToOne并映射另一个表,而不是试图用一个本地子查询使它成为一个列值。 – JustinKSU
所以,你说有一个帐户originalAccount与映射到AccountHistory?我不确定这样做是否有效,因为历史表实际上应该由代理通过主表间接查询。历史表没有PK,不能写入,并且所有基于时间的查询对话只能在它的父表Account中使用。如果我用sql查询映射了一个新实体,我可能可以通过这种方式做一个懒加载,尽管 – Proto
哦,我现在看到了。我认为你最好的选择是Native Query https://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/querysql.html – JustinKSU