0

如有重复请见谅。

业务层是否可以或推荐使用对象而不是 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);
}

更新的问题 --------------------------------------

@EJB是否可以在同一个 JTA 中说任何可以注入的 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;
}
4

2 回答 2

2

以下仅作为对“业务层是否可以或建议使用对象而不是 ids可以说注入@EJB 在同一个JTA 中?”。

有可能的。大多数情况下也推荐。ORM 的全部目的是我们可以对对象及其关系进行操作,而不是对它们在数据库中的表示进行操作。

实体的 ID(特别是在代理 ID 的情况下)通常是仅在我们靠近存储本身时才有意义的概念。当只有提供的持久性本身需要访问 id 时,设计访问 id 的方法通常是有意义的protected。当我们这样做时,向实体用户发布的噪音更少。

像往常一样也有有效的例外。例如,可以发现在线路上移动整个实体太耗费资源,并且最好使用 id 列表而不是实体列表。在问题实际存在之前,不应做出这样的设计决策。

于 2012-07-23T07:14:38.860 回答
1

如果 parent 还没有被持久化,那么查询将不起作用,执行它没有多大意义。如果父级没有被持久化,你有责任避免执行它。但我不会让它成为 find 方法本身的责任。只需在方法的文档中明确说明,作为参数传递的父级必须有一个 ID,或者至少是持久的。无需进行与实体管理器相同的验证。

如果它已被持久化,但尚未发生刷新,则实体管理器必须在执行查询之前刷新,正是为了使查询找到新父级的子级。

至少使用 Hibernate,您可以使用分离的父级执行查询。如果 ID 存在,查询将使用它并执行查询。

于 2012-07-23T07:20:50.660 回答