我有一个实体: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