使用公式休眠@OneToOne - 列不能外连接到子查询
Posted
技术标签:
【中文标题】使用公式休眠@OneToOne - 列不能外连接到子查询【英文标题】:Hibernate @OneToOne with formula - A column may not be outer-joined to a subquery 【发布时间】:2015-09-23 21:44:41 【问题描述】:我有一个实体,我们称之为Policy
。 Policy
由 PolicyHolder
s 持有。不是一次全部,只有一个,但它们可以随着时间的推移而改变。我可以使用 @OneToMany
注释轻松地将 PolicyHolder
s 映射到策略。但是其中一位持有者很特别,因为它是当前持有者。我需要特殊的、很可能是瞬态的字段,它可以保留其引用。
其中一个问题是没有严格的鉴别器来区分当前持有人与其他人。唯一的办法是找出其中一个是这个特殊的,我需要在添加持有人时找到最新的附件。理论上可以通过查询和子查询轻松完成:
SELECT * FROM holders h
WHERE h.policy_id = :myPolicyId AND h.annex_id =
(SELECT MAX(annex_id) FROM holders sh WHERE sh.policy_id = h.policy_id)
将当前PolicyHolder
映射为一个字段似乎是个好主意,即使用@JoinColumnOrFormulas
注释。我试过这样:
public class Policy
@OneToMany(...)
private Set<PolicyHolder> holders;
@ManyToOne
@JoinColumnOrFormulas(
@JoinColumnOrFormula(
column = @JoinColumn(columnName = "policy_id", referencedColumnName = "policy_id")),
@JoinColumnOrFormula(
formula = "SELECT MAX(annex_id) FROM holders h WHERE h.policy_id = policyId",
referencedColumnName = "annex_id")
)
)
private PolicyHolder currentHolder;
我什至不知道上面这段代码是否有效。我现在无法检查它,它是用记事本写的。无论如何,它以 Hibernate 生成正确查询的方式对我有用。但是查询没有在 Oracle 数据库上执行并显示错误消息:A column may not be outer-joined to a subquery
(为什么?)。
好的,所以我尝试强制 Hibernate 生成内部联接而不是外部联接。这是安全的,因为总是至少有一个policy holder
对应一个policy
。我尝试将列设置为nullable = false
(我知道-它用于生成模式)和optional = false
。但没有任何结果。
有什么想法吗?
【问题讨论】:
【参考方案1】:我也有类似的情况,我也无法让 hibernate 生成内部连接。不幸的是,外连接不能用子查询完成(正如你已经注意到的)。所以我的解决方案虽然不是最好的,但还是在 oracle 中创建一个函数。那么它会变成:
@ManyToOne
@JoinColumnOrFormulas(
@JoinColumnOrFormula(
column = @JoinColumn(columnName = "policy_id", referencedColumnName = "policy_id")),
@JoinColumnOrFormula(
formula = "getMaxAnnexForPolicy(policyId)",
referencedColumnName = "annex_id")
)
)
private PolicyHolder currentHolder;
并创建一个类似的函数:
CREATE OR REPLACE Function getMaxAnnexForPolicy
( policyId in varchar2)
RETURN varchar2
IS
res varchar2(200);
BEGIN
SELECT MAX(annex_id) into res FROM holders h WHERE h.policy_id = policyId;
RETURN res;
end getMaxAnnexForPolicy;
我知道这是一种解决方法,但在我的场景中效果很好。如果它是一个函数,hibernate 知道它只会返回一行。否则它不会评估查询以查看您是否添加了 max() 并且它也会返回一行
【讨论】:
以上是关于使用公式休眠@OneToOne - 列不能外连接到子查询的主要内容,如果未能解决你的问题,请参考以下文章
休眠 | Spring Data JPA | @OneToOne