Here's a first cut. comments and suggestions more than welcome.
(remember I'm newbie, so I may have missed important points). Stefan > Hi, > > go for it :-) > > If you do it fast enough, it will be included in the 1.2.2 release and be > put up on the web site. > > Heiko > > ________________________________ > > Von: [EMAIL PROTECTED] im Auftrag von Stefan > Champailler Gesendet: Mo 04.10.2004 09:34 > An: [EMAIL PROTECTED] > Betreff: Re: [Xdoclet-user] value-object and "almost" self-reference > > > > Ooops, > > it seems I didn't read the documentation enough... The solution is > explained in "Exposing Generated Methods" of the "Using Value Objects" > document. Just had to expose the missign interface. > > Since I've serached a lot for that little info, I thought it'd be nice to > have a small paragraph in the documentation explaining how to do > "self-reference" with entities and XDoclet. I could write it if some of you > are ready to proof-read it. What do you think ? > > > Stefan > > > Dear You all, > > > > > > I'm currently fighting big time with XDoclet to understand it. I think I > > have a very simple problem but for some reason, I don't get it. > > > > I have a bean that have a relationship with itself : "I'm a 'People' and > > I can have other 'People' as friends". > > > > Out of that bean, I try to make two value objects : > > > > - one with the bare minimum information about a 'People' : name, role, > > etc. No information about the "friends". It'll be called > > "PeopleListValue" - a "fat" one, with everything from People. For the > > "friends" relation, I use an aggregate of PeopleListValue. > > > > (I saw that idea there : > > http://www.mail-archive.com/xdoclet-user%40lists.sourceforge.net/msg03372 > >.h tml) > > > > So, I /think/ I'm OK here, no circular references. Now, for some reason I > > completely miss, XDoclet builds an erroneous CMP class out of the bean > > that can't compile : > > > > foundryserver/beans/PeopleCMP.java:135: cannot resolve symbol > > [javac] symbol : method getPeopleListValue () > > [javac] location: interface > > foundryserver.beans.interfaces.PeopleLocal [javac] > > PeopleVOValue.addFriend( > > ((foundryserver.beans.interfaces.PeopleLocal)iFriend.next()).getPeopleLis > >tV alue() ); > > > > I'd be very happy if one could tell me why it tries to get the > > PeopleListValue out of the local interface. I could think it makes sense, > > but then, how do I tell XDoclet to generate the getPeopleListValue () > > method ? > > > > For information, I have the following code in an entity bean (stripped > > useless stuff).: > > > > ... > > > > * @ejb.value-object name="PeopleList" > > * match="light" > > * @ejb.value-object name="PeopleVO" > > * match="fat" > > */ > > public abstract class PeopleBean implements EntityBean { > > > > ... > > > > /** > > * @ejb.interface-method > > * @ejb.relation name="friendship" > > * role-name="ILove" > > * target-ejb="People" > > * target-role-name="ImLoved" > > * > > * @ejb.value-object > > * match="fat" > > * type="java.util.Collection" > > * relation="external" > > * aggregate="foundryserver.beans.interfaces.PeopleListValue" > > * aggregate-name="Friend" > > * members="foundryserver.beans.interfaces.PeopleLocal" > > * members-name="Friend" > > * > > * @return Returns the name. */ > > > > public abstract Collection getFriends(); > > > > > > thank you for your patience. > > > > Stefan > > > > > > > > > > ------------------------------------------------------- > > This SF.net email is sponsored by: IT Product Guide on ITManagersJournal > > Use IT products in your business? Tell us what you think of them. Give us > > Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out > > more http://productguide.itmanagersjournal.com/guidepromo.tmpl > > _______________________________________________ > > xdoclet-user mailing list > > [EMAIL PROTECTED] > > https://lists.sourceforge.net/lists/listinfo/xdoclet-user > > ------------------------------------------------------- > This SF.net email is sponsored by: IT Product Guide on ITManagersJournal > Use IT products in your business? Tell us what you think of them. Give us > Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more > http://productguide.itmanagersjournal.com/guidepromo.tmpl > _______________________________________________ > xdoclet-user mailing list > [EMAIL PROTECTED] > https://lists.sourceforge.net/lists/listinfo/xdoclet-user
value objects and self reference.
We want to answer the following question : "how do I represent a tree-like structure with entity EJB and value-objects using XDoclet ?".
So, here we choose to go for entity bean. We won't discuss that further (freedom of choice :)). As you may know, entity EJB access through RMI can be costly and that's why one wants to use value-objects. However, we introduce a small catch here : we want the entity EJB to have some relationships with other entity EJB of the same class. This might seem easy but there's some catch when we want to create the value objects.
We choose to implement a family tree. The family tree is made of Persons. Each person has a name and an age. Moreover, a Person knows its children. Each child is itself a Person. We just described a 1-N (1 person can have 0..N children) uni-directional relationship (we don't implement the fact that a child knows its father, nor brothers).
Coding this, we end up with :/** * @ejb.interface-method * @ejb.relation name="offspring" * role-name="father" * target-ejb="Person" * target-role-name="child" * * @ejb.value-object * type="java.util.Collection" * relation="external" * aggregate="foundryserver.beans.interfaces.PersonLightValue" * aggregate-name="Offspring" * members="foundryserver.beans.interfaces.PersonLocal" * members-name="Offspring" * * @return Returns the offspring. */ public abstract Collection getOffspring(); /* * @ejb.interface-method */ public abstract PersonLightValue getPersonLightValue();
To be able to run XDoclet on the EJB the first time, pay attention to the following points :
- Make sure you import the PersonLightValue class in the code, although it doesn't exist yet (XDoclet will generate it itself). This also allows you tell XDoclet in which package that class must be generated.
- Add an abstract getter to your entity to get the PersonLightValue object. Read the "Exposing Generated Methods" part for more info.
Now a bit of explanation. The most important thing is to understand that a value-object cannot reference other value-objects of the same class. Think about this situation : one wants to retrieve a person that has some children. He gets the value-object for that person. Now, if the value-object can references to the children, then those children's value-objects are added to the person's value-object. However, to be complete, those children's value objects must in turn have the value-objects of their children, etc. This is a recursive loop and doing so can lead us to have a graph of value-object covering the whole database. Not good. To prevent that, we break the loop. The strategy is to represent the children with a different class of value-object, the PersonLightValue. The particularity of this one is that it doesn't have any kind of reference to its own children, thus avoiding any uncontrollable recursive construction. Of course this is limiting a bit because we'll have to retrieve the children of Person manually.
To be complete, just have a look at the relationship declaration. It uses the "target-ejb" and "target-role" attributes. It's because we define a uni-directional relationship (see "How Relationships Work" for more information). Finally, note that we used an aggregation. This is arbitrary.