抱歉,如果重复。
是否可以或建议业务层使用对象而不是ID?
SELECT c
FROM Child AS c
WHERE c.parent = :parent
public List<Child> list(final Parent parent) {
// does parent must be managed?
// how can I know that?
// have parent even been persisted?
return em.createNamedQuery(...).
setParameter("parent", parent);
}
这就是我的工作方式。
SELECT c
FROM Child AS c
WHERE c.parent.id = :parent_id
public List<Child> list(final Parent parent) {
// wait! parent.id could be null!
// it may haven't been persisted yet!
return list(parent.getId());
}
public List<Child> list(final long parentId) {
return em.createNamedQuery(...).
setParameter("parent_id", parentId);
}
更新的问题--------------------------------------
是否可以在同一个JTA中说明每个可以注入@EJB
的JAX-RS或JAX-WS类?
这是我一直很好奇的原始问题。
假设我们有两个EJB。
@Stateless
class ParentBean {
public Parent find(...) {
}
}
@Stateless
class ChildBean {
public List<Child> list(final Parent parent) {
}
public List<Child> list(final long parentId) {
}
}
使用任何EJB客户端的正确方法是什么?
@Stateless // <<-- This is mandatory for being injected with @EJB, right?
@Path("/parents/{parent_id: \\d+}/children")
class ChildsResource {
@GET
@Path
public Response list(@PathParam("parent_id") final long parentId) {
// do i just have to stick to this approach?
final List<Child> children1 = childBean.list(parentId);
// is this parent managed?
// is it ok to pass to other EJB?
final Parent parent = parentBean.find(parentId);
// is this gonna work?
final List<Child> children2 = childBean.list(parent);
...
}
@EJB
private ParentBean parentBean;
@EJB
private ChildBean childBean;
}
答案 0 :(得分:2)
以下内容仅作为问题回答“是否可以或建议业务层使用对象而不是ID?”,因为遗憾的是我不完全理解第二个问题“做任何JAX-RS或JAX每个可以用@EJB注入的-WS类可以在同一个JTA中说出来吗?“
有可能。在大多数情况下也建议。 ORM的全部目的是我们可以操作对象及其关系,而不是它们在数据库中的表示。
实体的ID(特别是在代理ID的情况下)通常是在我们靠近存储本身时才有意义的概念。当只提供持久性本身需要访问id时,设计访问id为protected
的方法通常是有意义的。当我们这样做时,会向实体用户发布较少的噪音。
也像往常一样有效例外。例如,可以发现通过线路移动整个实体太耗费资源并且具有id列表而不是实体列表是优选的。在问题确实存在之前,不应该做出这样的设计决定。
答案 1 :(得分:1)
如果尚未持久化父级,则查询将不起作用,并且执行它没有多大意义。如果父母没有被坚持,那么你有责任避免执行它。但我不会让它成为find方法本身的责任。只是在方法的文档中明确说明父作为参数传递的方法必须具有ID,或者至少是持久的。无需与实体经理进行相同的验证。
如果它已被持久化,但尚未发生刷新,则实体管理器必须在执行查询之前进行刷新,正好使查询找到新父级的子级。
至少在Hibernate中,您可以使用分离的父级执行查询。如果ID在那里,查询将使用它并执行查询。