Hi Nicolas,
Pinaki has responded and my comments are intended to complement, not
contradict his reply.
On Aug 26, 2008, at 3:30 AM, andiqo wrote:
>
> Hi,
>
> A question for JPA experts in order to avoid calling evict, please.
>
> I have a simple model made of 2 classes : Node and Link to modelize
> a graph
> in database (Link = many-to-many relationship). The Link class has a
> 'kind'
> attribute, in order to know if the association between Nodes is an
> aggregation or a composition. Thus, as I cannot use 'dependent-
> element' tag,
> I manage deletion by code.
Let's start with the modeling.I'm assuming that the Entity Link is
mapped to a join table with two columns "to" and "from" representing
the Nodes, and the columns contain foreign keys to Nodes. An
additional column tells you whether the relationship is composition,
for which cascade delete is appropriate.
So your Node has two Collections, one mapped to the "to" foreign key,
and another mapped to the "from" foreign key. Your Node business logic
needs to treat the union of these two collections as the collection of
Links.
>
> So, when the user chooses to delete one node somewhere in the graph, a
> delete action manages it and implements a 'cascade-delete' in
> database for
> hard links. But I need to call evict potentially a lot of times, in
> order to
> avoid stale nodes...
The issue with stale nodes is an unfortunate decision by the JPA
expert group to require that relationships must be explicitly managed
by the user, regardless of whether the other side has even been
brought into the EntityManager's context.
But beyond the JPA requirements, OpenJPA automatically does the
appropriate unlinking for you if you delete instances in memory where
the other side is not in cache and the other side doesn't otherwise
need to be updated. So the only thing you need to worry about is
deleting the Node on other side of the Link in case the Link is a
composition.
When you delete a Node, you need to explicitly fetch the two
collections of Links (to and from this Node) and check each link to
decide whether to delete the Node on the other side or not.
You might implement a policy where the only Links that are allowed to
cascade delete are Links in the "to" Collection. Then the logic is a
little easier since you don't need to even look at cascade delete for
links in the "from" collection. (I'm assuming that you never have the
case where both "to" and "from" links can have cascade delete).
For Links that are not cascaded, all you need is to delete them using
normal JPA delete. OpenJPA will unlink the Nodes on the other sides
automatically.
For Links that are cascaded, you need to delete the target Node. You
could simply invoke JPA delete on the Node on the "to" side. If you
want to be more efficient, you can implement a query and do a group
delete of the other Nodes.
List<Node> to_be_deleted = em.createQuery("Select n from Link l join
l.to as n where l.from = :theNode and l.type =
cascade").setParameters(node).listResult();
EntityManager.cast(em).removeAll(to_be_deleted);
Craig
>
>
> Doing something like:
>
> // --
> // Avoid stale children in other Node parents
> queryString = "SELECT FROM_ID FROM LINK AS l WHERE l.TO_ID=" + id;
> query = getEntityManager().createNativeQuery(queryString);
> List<?> list = query.getResultList();
> for (Object parent : list) {
> queryString = "SELECT n FROM Node n WHERE n.id = " + (Long) parent;
> query = getEntityManager().createQuery(queryString);
> Node node = (Node) query.getSingleResult();
> OpenJPAEntityManager openJPAEM =
> OpenJPAPersistence.cast(getEntityManager());
> openJPAEM.evict(node);
> }
> // --
>
> Thus I create a native query using only ids, then a JPA query to get
> the
> Node object, then call evict.
> But most of the time, the parent Node I tried to evict isn't even
> loaded in
> the EntityManager. Thus my question is, do you see better way to do
> this?
>
> Thanks a lot for your help.
>
> Nicolas
> --
> View this message in context:
http://n2.nabble.com/avoid-calling-evict--tp783696p783696.html> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>
Craig L Russell
Architect, Sun Java Enterprise System
http://java.sun.com/products/jdo408 276-5638 mailto:
Craig.Russell@...
P.S. A good JDO? O, Gasp!