0

Sorry if duplicated.

Is it possible or recommended for business layer to using objects instead of ids?

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);
}

This is how I work with.

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);
}

UPDATED QUESTION --------------------------------------

Do any JAX-RS or JAX-WS classes which each can be injected with @EJB can be said in the same JTA?

Here come the very original problem that I always curious about.

Let's say we have two EJBs.

@Stateless
class ParentBean {

    public Parent find(...) {
    }
}

@Stateless
class ChildBean {

    public List<Child> list(final Parent parent) {
    }

    public List<Child> list(final long parentId) {
    }
}

What is a proper way to do with any EJB clients?

@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;
}
Jin Kwon
  • 20,295
  • 14
  • 115
  • 184

2 Answers2

2

Following is presented as an answer only to question "Is it possible or recommended for business layer to using objects instead of ids?", because I unfortunately do not fully understand second question "Do any JAX-RS or JAX-WS classes which each can be injected with @EJB can be said in the same JTA?".

It is possible. In most cases also recommended. Whole purpose of ORM is that we can operate to objects and their relationships and not to their presentation in database.

Id of entity (especially in the case of surrogate id) is often concept that is only interesting when we are near storage itself. When only persistence provided itself needs to access id, it makes often sense to design methods to access id as protected. When we do so, less noise is published to the users of entity.

There is also valid exceptions as usual. It can be for example found that moving whole entity over the wire is too resource consuming and having list of ids instead of list of entities is preferable. Such a design decision should not be done before problem actually exists.

Mikko Maunu
  • 41,366
  • 10
  • 132
  • 135
1

If parent has not been persisted yet, then the query won't work, and executing it doesn't make much sense. It's your responsibility to avoid executing it if the parent hasn't been persisted. But I would not make it a responsibility of the find method itself. Just make it clear in the documentation of the method that the parent passed as argument must have an ID, or at least be persistent. No need to make the sameverification as the entity manager.

If it has been persisted, but the flush hasn't happened yet, the entity manager must flush before executing the query, precisely to make the query find the children of the new parent.

At least with Hibernate, you may execute the query with a detached parent. If the ID is there, the query will use it and execute the query.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255