You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by CASERO Jaime <JC...@covansys.com> on 2007/07/20 15:15:46 UTC

Mapping tree structures or self-referencing foreign-Keys

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.
-----------------------------

Re: Mapping tree structures or self-referencing foreign-Keys

Posted by Pinaki Poddar <pp...@apache.org>.
I will open a JIRA report with the details and a small test case.


Patrick Linskey-2 wrote:
> 
> Pinaki,
> 
> Can you describe the failure in id creation in a bit more detail? I've
> been working on the enhancer recently, so I might be able to dive in
> and fix it at some point here.
> 
> -Patrick
> 
> On 7/23/07, Pinaki Poddar <pp...@apache.org> wrote:
>>
>> 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: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.
>> > -----------------------------
>> >
>> >
>>
>> --
>> 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.
>>
>>
> 
> 
> -- 
> Patrick Linskey
> 202 669 5907
> 
> 

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


Re: Mapping tree structures or self-referencing foreign-Keys

Posted by Pinaki Poddar <pp...@apache.org>.
This issue is logged as JIRA issue
https://issues.apache.org/jira/browse/OPENJPA-291



Patrick Linskey-2 wrote:
> 
> Pinaki,
> 
> Can you describe the failure in id creation in a bit more detail? I've
> been working on the enhancer recently, so I might be able to dive in
> and fix it at some point here.
> 
> -Patrick
> 
> On 7/23/07, Pinaki Poddar <pp...@apache.org> wrote:
>>
>> 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: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.
>> > -----------------------------
>> >
>> >
>>
>> --
>> 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.
>>
>>
> 
> 
> -- 
> Patrick Linskey
> 202 669 5907
> 
> 

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


Re: Mapping tree structures or self-referencing foreign-Keys

Posted by Patrick Linskey <pl...@gmail.com>.
Pinaki,

Can you describe the failure in id creation in a bit more detail? I've
been working on the enhancer recently, so I might be able to dive in
and fix it at some point here.

-Patrick

On 7/23/07, Pinaki Poddar <pp...@apache.org> wrote:
>
> 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: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.
> > -----------------------------
> >
> >
>
> --
> 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.
>
>


-- 
Patrick Linskey
202 669 5907

RE: Mapping tree structures or self-referencing foreign-Keys

Posted by Pinaki Poddar <pp...@apache.org>.
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: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.
> -----------------------------
> 
> 

-- 
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.


RE: Mapping tree structures or self-referencing foreign-Keys

Posted by CASERO Jaime <JC...@covansys.com>.
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.
-----------------------------

Re: Mapping tree structures or self-referencing foreign-Keys

Posted by Pinaki Poddar <pp...@apache.org>.
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-foreign-Keys-tf4117022.html#a11715126
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Mapping tree structures or self-referencing foreign-Keys

Posted by Patrick Linskey <pl...@gmail.com>.
Hi,

In general, recursive models shouldn't be a problem.

Looking at your example, I'm guessing that the problem might have to
do using a recursive relationship in the primary key -- that seems
like something that maybe we're not testing currently. What happens if
you remove the relationship from the primary key definition, for the
sake of experimentation?

-Patrick

On 7/20/07, CASERO Jaime <JC...@covansys.com> 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.
> -----------------------------
>


-- 
Patrick Linskey
202 669 5907