我有一個實體:JPA可空JoinColumn
public class Foo {
@Id
@GeneratedValue
private Long id;
private String username;
@ManyToOne(cascade = { CascadeType.MERGE }, fetch = FetchType.LAZY, optional = true)
@JoinColumn(name = "ParentID", nullable = true)
private Foo parent;
// other fields
}
利用這種關係,每個Foo對象具有父,除了在DB中的第一富實例具有NULL PARENTID。當我嘗試創建通過標準API查詢,並嘗試搜索使用任何它的第一個Foo對象(null父ID)的屬性(ID,用戶名等),我得到一個:
javax.persistence.NoResultException: No entity found for query
如何應該在這種情況下實施JoinColumn?我應該如何獲得具有空父ID的數據庫中的第一個Foo對象?
感謝
更新2011年9月28日
什麼,我想實現的是看lookfor所有FOOS使用用戶名在「foo」的開始,並希望作爲單獨的對象使用返回然後:
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder;
CriteriaQuery<FooDto> criteriaQuery = criteriaBuilder.createQuery(FooDto.class);
Root<Foo> foo = criteriaQuery.from(Foo.class);
criteriaQuery.multiselect(foo.get("id"), foo.get("username"), foo.get("parent").get("username"), foo.get("property1")
//other selected properties);
Predicate predicate = criteriaBuilder.conjunction();
predicate = criteriaBuilder.and(predicate, criteriaBuilder.like(foo.get("username").as(String.class), criteriaBuilder.parameter(String.class, "username")));
// other criteria
criteriaQuery.where(predicate);
TypedQuery<FooDto> typedQuery = entityManager.createQuery(criteriaQuery);
typedQuery.setParameter("username", "foo%");
// other parameters
// return result
假設用戶名是foo1和Foo2和foo3其中foo1具有null父,結果集將只返回foo2的和foo3即使foo1具有與指定的謂詞啓動一個用戶名。 並尋找foo1單獨將拋出一個
javax.persistence.NoResultException: No entity found for query
有沒有辦法仍然包括與其餘結果的foo1?或foo1將永遠是一個特例,因爲我必須添加一個標準,指定父項爲空?或者,也許ai錯過了joinColumn中的一個選項來執行此操作。
感謝
修訂週四9月29日13時03分41秒PHT 2011 @mikku 我已經更新上面(property1)後的標準的一部分,因爲我認爲這是負責的部分因爲foo1不包含在結果集中。
下面是生成的查詢的從日誌中的部分觀點:
select
foo.id as id,
foo.username as username,
foo.password as password,
foo.ParentID as parentId,
foo_.username as parentUsername,
foo.SiteID as siteId,
from FOO_table foo, FOO_table foo_ cross join Sites site2_
where foo.ParentID=foo_.id and foo.SiteID=site2_.id and 1=1
and foo.username=? and site2_.remoteKey=? limit ?
,這不會返回Foo1,顯然是因爲用戶名值是foo_這就是爲什麼我原來的問題是「我應該怎麼去Foo1 」。
在部分我已經評論說,生病使用SelectCase,並與你的第一個回覆混合起來,我所做的是對多選添加此部分:
criteriaBuilder
.selectCase()
.when(criteriaBuilder.isNotNull(agent.get("parent")), agent.get("parent").get("username"))
.otherwise(criteriaBuilder.literal("")),
更換
foo.get("parent").get("username")
但是,這也不會得到Foo1。我最後的手段雖然效率低下,但可能會檢查參數是否爲Foo1,並創建一個criteriaQuery指定用戶名的文字值,否則使用默認查詢。
建議/替代方案非常感謝。
感謝您的回答。遺憾的是,我忘了在帖子上放置實體註釋。順便說一下,基於你的推薦答案,我假設我需要爲第一個foo的情況有一個單獨的查詢,因爲它有一個空的父親?我已經用我希望實現的內容更新了我發佈的問題。 謝謝 – geneqew
你不需要特殊情況。這是你的原始問題的答案:「我應該如何獲得具有空父ID的數據庫中的第一個Foo對象?」 –
感謝您的回覆。 &道歉我已經忘記包括FooDto構造函數,我已經有+(multiselect上面說的是工作給定的構造函數存在相同的參數類型和順序,因爲c的類型已經被指定爲FooDto)。但是,因爲我的後續問題是: 有沒有辦法將foo1與其他結果一起包含?或foo1將永遠是一個特例,因爲我必須添加一個標準,指定父項爲空? 我結束了混合你的第一個答案,指定一個選擇案例鏈接的空標準。 再次感謝 – geneqew