openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "CASERO Jaime" <JCas...@covansys.com>
Subject RE: Mapping tree structures or self-referencing foreign-Keys
Date Mon, 23 Jul 2007 08:33:20 GMT
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:ppoddar@apache.org] 
Sent: Friday, July 20, 2007 10:05 PM
To: users@openjpa.apache.org
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.
-----------------------------

Mime
View raw message