我有一对一的单向关系。我想要实现的是
我的查询在SQL Manager中有效:
SELECT d.Description, d.AccountId, d.PartnerId, a.FormattedName FROM
InvoiceDesigns d
INNER JOIN UserAccount a
ON
a.id =
CASE
WHEN d.PartnerId != -1 AND d.AccountId = 1 THEN d.PartnerId
WHEN d.PartnerId = 1 THEN d.AccountId
ELSE 1
END
WHERE
d.AccountId = 1 OR PartnerId = 1
工作查询在SQL Manager中运行,而不是在hibernate中运行。这是我想要实现的,我希望hibernate创建这样的查询。
当一个帐户,让我们说ID = 1坚持示例,显示他们将看到的设计
A)设计的PartnerId不是-1且AccountId为1,这意味着它是由该帐户的合作伙伴创建的,并将显示合作伙伴的formattedName。
在查看可用设计时,这适用于普通帐户。如果合作伙伴为他们创建了设计,他们将看到该合作伙伴的名称。
B) PartnerId等于帐户的ID,这意味着它是合作伙伴设计,并且将显示为其创建的帐户相关设计的formattedName。 这是合作伙伴帐户查看他们创建的设计。
C)设计由帐户直接创建,因此将显示自己的名称。对于普通帐户和自己创建的设计。
当我只想使用AccountId或PartnerId时,正常连接在hibernate中正常工作但我需要更改列以获取相关的FormattedName。我试过@ Where,@ Filter,@ JoinColumnOrFormula但是我无法实现这个查询。
我和@Where的课程基本上是这样的:
设计类:
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
int id;
@Column(name="AccountId")
int accountId;
@Column(name="PartnerId")
int partnerId;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "AccountId", referencedColumnName = "id", insertable = false, updatable = false, nullable = true)
@Where(clause = "CASE " +
"WHEN PartnerId != -1 AND AccountId = :accountId THEN PartnerId " +
"WHEN PartnerId = :accountId THEN AccountId " +
"ELSE :accountId " +
"END")
AccountData account;
帐户类:
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
int id;
@Column(name="FormattedName")
String formattedName;
在这里,您可以看到我想使用“:accountId”将ID作为参数进行查询,该帐户将用于定义连接列。
这个问题:custom join clause实际上做了类似的事情。这就是为什么我专注于where子句
另外:我还找到了符合标准的内容
Criteria criteria = session.createCriteria(InvoiceDesignData.class, "design");
criteria.createCriteria("design.account", "acc", JoinType.LEFT_OUTER_JOIN, Restrictions.eqProperty("acc.id", "design.partnerId"));
invoiceDesignList = criteria.list();
但这不会忽略第一个条件,并使用AND为ON子句添加一个附加条件。我从@ one-to-many中删除了连接列,希望忽略第一个条件,但事实并非如此。生成查询:
from InvoiceDesigns this_ left outer join UserAccount acc1_ on this_.account_id=acc1_.id and ( acc1_.id=this_.PartnerId )
提前致谢
答案 0 :(得分:0)
您可以尝试移动案例陈述:
SELECT d.Description, d.AccountId, d.PartnerId, a.FormattedName
FROM (SELECT *, CASE
WHEN PartnerId != -1 AND AccountId = 1 THEN PartnerId
WHEN PartnerId = 1 THEN AccountId
ELSE 1
END AS SmartID
FROM InvoiceDesigns) d
INNER JOIN UserAccount a
ON a.id = d.SmartID
WHERE d.AccountId = 1 OR PartnerId = 1
编辑:这基本上会让你在没有条件ON语句的情况下直接加入内联查询。
答案 1 :(得分:0)
如果您只想将每个Design映射到一个AccountData对象,只有一个连接,但您希望根据其值加入accountId或partnerId,那么您应该可以通过使用连接来实现式。你会想要这样的东西:
@ManyToOne
@JoinColumnsOrFormulas(
{ @JoinColumnOrFormula(
formula = @JoinFormula(
value = "case " +
"when partnerId != -1 and accountId = 1 then partnerId" +
"when partnerId = accountId then accountId " +
"else 1" +
"end",
referencedColumnName="id")) }
)
请注意,您需要使用@ManyToOne注释,即使这实际上是一对一关联。如果您尝试在一对一上使用它,则连接公式将不起作用。
然后,您只需使用正常的HQL连接检索数据:
SELECT d.description, d.accountId, d.partnerId, a.formattedName FROM Design d
inner join d.account a