Self-recursive Entity relation as part of the compound key will continue to
throw SatckOverflow exception with current implementation. I was only
partially successful in plugging that error by changing OpenJPA
implementation. Because even if the recursive loop is terminated while
resolving metadata -- OpenJPA enhanced code does not fully account for
self-recursive composite keys. Hence the test fails later within enhanced
code to create an application identity. Making changes to enhanced code has
a more sever impact across the board.

At this point, a tree-structured domain model has to live with simple keys
-- imo.
   


CASERO Jaime wrote:
> 
> After changing the OwnerId class definition as you suggested.
> The same exception is thrown again:
> 
> java.lang.StackOverflowError
>       at
> org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepositor
> y.java:277)
>       at
> org.apache.openjpa.meta.MetaDataRepository.resolveMeta(MetaDataRepositor
> y.java:528)
>       at
> org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.ja
> va:488)
>       at
> org.apache.openjpa.meta.MetaDataRepository.getMetaData(MetaDataRepositor
> y.java:290)
>       at
> org.apache.openjpa.meta.MetaDataRepository.resolveMeta(MetaDataRepositor
> y.java:557)
>       at
> org.apache.openjpa.meta.MetaDataRepository.resolve(MetaDataRepository.ja
> va:488)
> )
> 
>       Any ideas? 
> 
>       I'm worry about the "equals" and "hascode" methods overridings
> of both the Owner and OwnerId (they have a very recursive behavior).
> Could be this issue affecting the metadata resolving?. I guess "equals"
> and "hasCode" are only important in runtime.
> 
> -----Original Message-----
> From: Pinaki Poddar [mailto:[EMAIL PROTECTED] 
> Sent: Friday, July 20, 2007 10:05 PM
> To: [email protected]
> Subject: Re: Mapping tree structures or self-referencing foreign-Keys
> 
> 
> 1. Owner has a compound key. The key is comprised of two fields:
> @Id  protected String label;
> @Id  protected Owner owner;  
> 
> 2. Owner says that its compound key class is represented by
> OwnerId.class
> @IdClass(com.covansys.routingengine.ifc.jpa.OwnerId.class)
> public class Owner
> 
> 3. The rule to define the Idclass OwnerId is
>  a) it must declare all the key fields of Owner 
>      and you declared 'label' and 'owner'  
>  b) the type of the Idclass' fields must be the same as the original
> fields
> *except* for relation field.
>    for relation field R, the type of Idclass' field must be the R's
> identity
> class type.
>    Here for field 'owner' is a relation field i.e. R=Owner. Id type of R
> is
> OwnerId. So OwnerId.owner should be of type OwnerId. Resulting into
>      public class OwnerId {
>             public String label;
>             public OwnerId owner;
> 
> ======================================================================
> 
> I do not know the details of your domain model that requires such
> identity
> scheme. I would suggest that design a simpler Tree structure like this:
> 
> @Entity
> public class Node {
>   @Id 
>   private long;
>   @ManyToOne 
>   private Node parent;
>   @OneToMany(mappedBy="parent", cascade=CascadeType.ALL)
>    private List<Node> children;
> }
> 
> 
> 
> 
> 
> CASERO Jaime wrote:
>> 
>> Hi all,
>> 
>>  
>> 
>>             I'm trying to persist a tree structure. Here class A
>> references several A's (as his children -> OneToMany), and one A(p)
> (as
>> his parent -> ManyToOne). When JPA is parsing my metadata a
>> "StackOverflowError" exception is thrown. Seems to be the typical
>> recursive problem because of the self-referencing foreign key (=a
>> foreign key to the same table) created.
>> 
>>  
>> 
>>             I haven't seend any referente in the manual to this
>> scenario.
>> 
>>  
>> 
>>             Has anyone try this before? Is this feature supported by
>> openJPA/JPA? Should i try one of the standard sql approches
> ("Adjacency
>> List Model", "The Path Enumeration Model", "Nested Set Model of
>> Hierarchies"..), or is completely unsupported?
>> 
>>  
>> 
>>             Thanks in advance
>> 
>>  
>> 
>>  
>> 
>>             Here is the class, and its corresponding Id class:
>> 
>>  
>> 
>> /////Owner///////
>> 
>> package com.covansys.routingengine.functionalcore;
>> 
>>  
>> 
>> import javax.persistence.*;
>> 
>>  
>> 
>> import org.apache.openjpa.persistence.ElementDependent;
>> 
>>  
>> 
>> import com.covansys.routingengine.ifc.jpa.ScreeningElementId;
>> 
>>  
>> 
>> import java.util.*;
>> 
>>  
>> 
>> @Entity
>> 
>> @IdClass(com.covansys.routingengine.ifc.jpa.OwnerId.class)
>> 
>> public class Owner extends OwnerEntity implements Comparable
>> 
>> {
>> 
>>             
>> 
>>             @Id
>> 
>>             protected String label;
>> 
>>             
>> 
>>             @Id
>> 
>>             @ManyToOne
>> 
>>             protected Owner owner;  
>> 
>>             /**
>> 
>>              * <p>
>> 
>>              * This function returns the value of the owner member
>> 
>>              * </p>
>> 
>>              * @return owner, Owner object which contains the owner
>> member value
>> 
>>              */
>> 
>>             public Owner getOwner()
>> 
>>             {
>> 
>>                         return owner;
>> 
>>             }
>> 
>>  
>> 
>>             
>> 
>>             /**
>> 
>>              * <p>
>> 
>>              * This function sets the owner value to the value of the
>> owner passed
>> 
>>              * as argument. If the value of the targetOwner is null
> then
>> it sets its 
>> 
>>              * value to the same owner.
>> 
>>              * </p>
>> 
>>              * @param o Owner object to be set as owner
>> 
>>              */
>> 
>>             public void setOwner(Owner o)
>> 
>>             {
>> 
>>                         owner = o;
>> 
>>             }
>> 
>>             
>> 
>>             
>> 
>>  
>> 
>>  
>> 
>>             
>> 
>>             /**
>> 
>>              * <p>
>> 
>>              * This function returns the value of the label member
>> 
>>              * </p>
>> 
>>              * @return label, String which contains the label member
>> value
>> 
>>              */
>> 
>>             public String getLabel()
>> 
>>             {
>> 
>>                         return label;
>> 
>>             }
>> 
>>  
>> 
>>  
>> 
>>             /**
>> 
>>              * <p>
>> 
>>              * This function sets the value of the label member to the
>> value
>> 
>>              * of the String passed as argument
>> 
>>              * </p>
>> 
>>              * @param l String to be set as label 
>> 
>>              */
>> 
>>             public void setLabel(String l)
>> 
>>             {
>> 
>>                         label = l;
>> 
>>             }
>> 
>>             
>> 
>>             @ElementDependent
>> 
>>             @OneToMany(mappedBy="owner", cascade={CascadeType.ALL})
>> 
>>             private Set<Owner> children;      
>> 
>>             
>> 
>>             
>> 
>>             @Basic
>> 
>>             private String tag;
>> 
>>             
>> 
>>             
>> 
>>  
>> 
>>             
>> 
>>             public Owner()
>> 
>>             {
>> 
>>                         children = new HashSet<Owner>();
>> 
>>             }
>> 
>>             
>> 
>>             public void setOwnerId(long id)
>> 
>>             {
>> 
>>                         //ownerId= id;
>> 
>>             }
>> 
>>             
>> 
>>             public long getOwnerId()
>> 
>>             {
>> 
>>                         //return ownerId;
>> 
>>                         return 0;
>> 
>>             }
>> 
>>             
>> 
>>             public int compareTo(Object o)
>> 
>>             {
>> 
>>                         if (o instanceof Owner)
>> 
>>                         {
>> 
>>                                     Owner owner = (Owner)o;
>> 
>>                                     return
>> getLabel().compareTo(owner.getLabel());
>> 
>>                         } else {
>> 
>>                                     //put behind
>> 
>>                                     return 1;
>> 
>>                         }
>> 
>>             }
>> 
>>  
>> 
>>             
>> 
>>  
>> 
>>  
>> 
>>     /*public int hashCode() {
>> 
>>         return ((label == null) ? 0 : label.hashCode())
>> 
>>             ^ ((owner == null) ? 0 : owner.hashCode());
>> 
>>     } */    
>> 
>>  
>> 
>>             public boolean equals(Object o)
>> 
>>             {
>> 
>>                         if (this == o) return true;
>> 
>>                         if (o instanceof Owner)
>> 
>>                         {
>> 
>>                                     Owner owner = (Owner)o;
>> 
>>                                     //return this.getOwner() ==
>> owner.getOwner() && getLabel().equals(owner.getLabel());
>> 
>>                                     return
>> getLabel().equals(owner.getLabel());
>> 
>>                         } else {
>> 
>>                                     return false;
>> 
>>                         }
>> 
>>             }
>> 
>>  
>> 
>>             public boolean isChild(Owner o)
>> 
>>             {
>> 
>>                         if (o == null )
>> 
>>                         {
>> 
>>                                     return false;
>> 
>>                         } else {
>> 
>>                                     if (equals(o)) {
>> 
>>                                                 return true;
>> 
>>                                     } else {
>> 
>>                                                 boolean found = false;
>> 
>>                                                 Iterator<Owner> it =
>> children.iterator();
>> 
>>                                                 Owner child = null;
>> 
>>                                                 while(it.hasNext() &&
>> !found) {
>> 
>>                                                             child =
>> it.next();
>> 
>>                                                             found =
>> child.isChild(o);
>> 
>>                                                 }
>> 
>>                                                 return found;
>> 
>>                                     }
>> 
>>                         }
>> 
>>             }
>> 
>>  
>> 
>>  
>> 
>>             public void setTag(String t)
>> 
>>             {
>> 
>>                         tag = t;
>> 
>>             }
>> 
>>             
>> 
>>             public String getTag()
>> 
>>             {
>> 
>>                         return tag;
>> 
>>             }
>> 
>>             
>> 
>>             public void addChild(Owner o)
>> 
>>             {
>> 
>>                         children.add(o);
>> 
>>                         o.setOwner(this);
>> 
>>             }
>> 
>>             public void removeChild(Owner o)
>> 
>>             {
>> 
>>                         children.remove(o);
>> 
>>             }
>> 
>>             public void removeAllChildren()
>> 
>>             {
>> 
>>                         for (int i = 0 ; i < children.size(); i ++)
>> 
>>                                     children.remove(i);
>> 
>>             }
>> 
>>             
>> 
>>             public Collection<Owner> getChildren()
>> 
>>             {
>> 
>>                         return children;
>> 
>>             }
>> 
>>             
>> 
>>             
>> 
>>             public List<Owner> getAllChildren()
>> 
>>             {
>> 
>>                         List<Owner> allChildren = new Vector<Owner>();
>> 
>>                         for(Owner oAux : children)
>> 
>>                         {
>> 
>>  
>> allChildren.addAll(oAux.getAllChildren());
>> 
>>                         }
>> 
>>                         return allChildren;
>> 
>>             }
>> 
>>             
>> 
>>             public Owner searchChild(String label) throws
> OwnerNotFound
>> 
>>             {
>> 
>>                         Owner oAux = new Owner();
>> 
>>                         oAux.setLabel(label);
>> 
>>                         return searchChild(oAux);
>> 
>>             }
>> 
>>             
>> 
>>             public Owner searchChildByTag(String t) throws
> OwnerNotFound
>> 
>>             {
>> 
>>                         if (t == null )
>> 
>>                         {
>> 
>>                                     throw new OwnerNotFound();
>> 
>>                         } else {
>> 
>>                                     if (t.equals(this.tag)) 
>> 
>>                                     {
>> 
>>                                                 return this;
>> 
>>                                     } else {
>> 
>>                                                 boolean found = false;
>> 
>>                                                 Iterator<Owner> it =
>> children.iterator();
>> 
>>                                                 Owner child = null;
>> 
>>                                                 Owner oAux = null;
>> 
>>                                                 while(it.hasNext() &&
>> !found)
>> 
>>                                                 {
>> 
>>                                                             try 
>> 
>>                                                             {
>> 
>>  
>> child = it.next();
>> 
>>  
>> oAux = child.searchChildByTag(t);
>> 
>>  
>> found = true;
>> 
>>                                                             } catch
>> (Exception e) {
>> 
>>
> 
>> 
>>                                                             }
>> 
>>                                                 }
>> 
>>                                                 if (found) 
>> 
>>                                                 {
>> 
>>                                                             return
> oAux;
>> 
>>                                                 } else {
>> 
>>                                                             throw new
>> OwnerNotFound();
>> 
>>                                                 }
>> 
>>                                     }
>> 
>>                         }
>> 
>>             }           
>> 
>>             
>> 
>>             public Owner searchChild(Owner o) throws OwnerNotFound
>> 
>>             {
>> 
>>                         if (o == null )
>> 
>>                         {
>> 
>>                                     throw new OwnerNotFound();
>> 
>>                         } else {
>> 
>>                                     if (equals(o)) 
>> 
>>                                     {
>> 
>>                                                 return this;
>> 
>>                                     } else {
>> 
>>                                                 boolean found = false;
>> 
>>                                                 Iterator<Owner> it =
>> children.iterator();
>> 
>>                                                 Owner child = null;
>> 
>>                                                 Owner oAux = null;
>> 
>>                                                 while(it.hasNext() &&
>> !found)
>> 
>>                                                 {
>> 
>>                                                             try 
>> 
>>                                                             {
>> 
>>  
>> child = it.next();
>> 
>>  
>> oAux = child.searchChild(o);
>> 
>>  
>> found = true;
>> 
>>                                                             } catch
>> (Exception e) {
>> 
>>  
>> //this child don't have the owner, try with the next
>> 
>>                                                             }
>> 
>>                                                 }
>> 
>>                                                 if (found) 
>> 
>>                                                 {
>> 
>>                                                             return
> oAux;
>> 
>>                                                 } else {
>> 
>>                                                             throw new
>> OwnerNotFound();
>> 
>>                                                 }
>> 
>>                                     }
>> 
>>                         }                       
>> 
>>             }           
>> 
>>             
>> 
>> }
>> 
>>  
>> 
>> ////////end owner///////
>> 
>>  
>> 
>>  
>> 
>>  
>> 
>> //////////OwnerId//////////
>> 
>> package com.covansys.routingengine.ifc.jpa;
>> 
>>  
>> 
>> import java.util.List;
>> 
>>  
>> 
>> import com.covansys.routingengine.functionalcore.Owner;
>> 
>>  
>> 
>>  
>> 
>> public class OwnerId
>> 
>> {
>> 
>>             public String label;
>> 
>>             public String owner;
>> 
>>             
>> 
>>     public boolean equals(Object other) {
>> 
>>         if (other == this)
>> 
>>             return true;
>> 
>>         if (!(other instanceof OwnerId))
>> 
>>             return false;
>> 
>>  
>> 
>>         OwnerId mi = (OwnerId) other;
>> 
>>         return (label == mi.label
>> 
>>             || (label != null && label.equals(mi.label)))
>> 
>>             && (owner == mi.owner
>> 
>>             || (owner != null && owner.equals(mi.owner)));
>> 
>>     }
>> 
>>     public int hashCode() {
>> 
>>         return ((label == null) ? 0 : label.hashCode())
>> 
>>             ^ ((owner == null) ? 0 : owner.hashCode());
>> 
>>     } 
>> 
>>     
>> 
>>             
>> 
>> }           
>> 
>> /////////end ownerid/////////
>>  
>> Confidentiality Statement:
>>  
>> This message is intended only for the individual or entity to which it
> is
>> addressed. It may contain privileged, confidential information which
> is
>> exempt from disclosure under applicable laws. If you are not the
> intended
>> recipient, please note that you are strictly prohibited from
> disseminating
>> or distributing this information (other than to the intended
> recipient) or
>> copying this information. If you have received this communication in
>> error, please notify us immediately by return email.
>> -----------------------------
>> 
>> 
> 
> -- 
> View this message in context:
> http://www.nabble.com/Mapping-tree-structures-or-self-referencing-foreig
> n-Keys-tf4117022.html#a11715126
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>  
> Confidentiality Statement:
>  
> This message is intended only for the individual or entity to which it is
> addressed. It may contain privileged, confidential information which is
> exempt from disclosure under applicable laws. If you are not the intended
> recipient, please note that you are strictly prohibited from disseminating
> or distributing this information (other than to the intended recipient) or
> copying this information. If you have received this communication in
> error, please notify us immediately by return email.
> -----------------------------
> 
> 

-- 
View this message in context: 
http://www.nabble.com/Mapping-tree-structures-or-self-referencing-foreign-Keys-tf4117022.html#a11748494
Sent from the OpenJPA Users mailing list archive at Nabble.com.

Reply via email to