我有一个实体,我们称之为Policy
。 Policy
持有PolicyHolder
。并非所有这些都只是一次,但它们可以随着时间而改变。我可以使用PolicyHolder
注释轻松地将@OneToMany
映射到策略。但是其中一个持有者是特殊的,因为它是现在的。我需要特殊的,最可能是瞬态的,可以保持其参考。
其中一个问题是没有严格的鉴别器来区分当前持有人与其他持有人。找出其中哪一个是特殊的唯一方法,我需要在添加持有人时找到最新的附件。从理论上讲,它可以通过查询和子查询轻松完成:
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
。但没有任何结果。
有什么想法吗?
答案 0 :(得分:0)
我有类似的情况,也无法使休眠生成内部联接。不幸的是,无法通过子查询完成外部联接(如您所知)。所以我的解决方案虽然不是最好的解决方案,但还是在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;
我知道这是一种解决方法,但在我的情况下效果很好。如果它是一个函数,休眠知道它将仅返回一行。否则,它不会评估查询是否看到您已添加max(),并且还会返回一行