Hi Jonathan,

Thanks for the interesting post. The only other options I can see currently
is that we always use a OID (generated number) as a primary key for all
beans (green field project....dream on...) or that we require the primary
key class to contain the primary key "fields" relating to both entities but
this is too database like and not OO, places more work on the developer, is
potentially impractical in the case of pk fields from both with the same
name and requires changes to the ejb descriptor. For example :-

public class ToyPK {
  public String name; // this is the name field from the ChildPK class
  public int index;     // this is the additional field introduce by the toy
}

If we consider that the toy ships with a set of manuals then we have....

public class ManualBean {
  public Toy toy;
  public String manual;
}

public class ToyManualPK {
  public String name; // this is not very nice really database like
  public int index; // same again
  public String manual;
}

with this when we map the reference to toy in the ManualBean we will need to
map 2 undisclosed cmp fields over some table columns. The container will
load the 2 fields index and name into the stub for the toy reference and
when accessed the stub can use these fields and call
findByPrimaryKey....pause....while typing this email I say another way maybe
we can just require that the ToyManual must contain the manual field and a
ToyPK field and that the ToyPK must contain a name field and ChildPK
field....

public class ToyManualPK {
  public ToyPK toy;
  public String manual;
}

There is probably many reasons this solution is just not up to it. Sorry a
bit unstructured its hard to work and still read this newsgroup....here
comes another context switch...bye...

William Louth

> -----Original Message-----
> From: Jonathan K. Weedon [SMTP:[EMAIL PROTECTED]]
> Sent: Tuesday, May 02, 2000 7:18 PM
> To:   [EMAIL PROTECTED]
> Subject:      Re: References to EBs from other EBs & CMP
>
> Jim,
>
> I thought I might follow up on your question to:
>
> 1) show an example of using references, and
>
> 2) set the stage for a question regarding the EJB spec. that has been
> nagging me for a while.
>
> In your example, you have a Child entity which has a reference to an
> Address entity, and which has references to a collection of Toy
> entities.  Using the normal EJB naming conventions, where Foo is the
> remote interface and FooBean is the bean implementation class, then
> you would have the following:
>
>         public class ChildBean implement EntityBean {
>
>           public String name;     // child's primary key field
>           public Address address; // container managed reference to
> Address
>           public Collection toys; // container managed collection of Toys
>
>           // other stuff omitted
>
>         }
>
>         public class Address implements EntityBean {
>
>           public Integer id;      // Address's primary key field
>           public String street;   // various container managed fields
>           public String city;
>           public int zipCode;
>
>           // other stuff omitted
>
>         }
>
>         public class Toy implements EntityBean {
>
>           public Child child;     // partial primary key, also a foreign
> key
>           public int index;       // other half of the primary key
>           public String color;    // some other container managed fields
>
>           // other stuff omitted
>
>         }
>
> As you can see, we have container managed fields which are references
> to the various entities' remote interfaces, or collections thereof.
> These typically correspond to foreign keys in the underlying schema.
>
> <vendor> We too will automatically create the various tables for you,
> if you are not mapping to preexisting tables.</vendor>
>
> The question that has been bothering me has to do with the primary key
> for Toy.  As you can see, Toy's primary key is a composite of a
> foreign key referring to a Child, and an index indicating which toy it
> is.
>
> (Note that I am assuming the Child-to-Toy relationship is one-to-many,
> not many-to-many.  I.e., two children cannot own the same toy.  This
> is just a simplifying assumption, not a requirement of the model.)
>
> Thus, the primary key type of Toy would be:
>
>         public class ToyPK implements Serializable {
>
>           public Child child;
>           public int index;
>
>           public int hashCode() {
>             // details omitted
>           }
>
>           public boolean equals(Object object) {
>             // details omitted
>           }
>
>         }
>
> So, my question is how can we implement the hashCode and equals
> method?  In the EJB spec., it is required that I implement these
> methods, but for fields which are remote references, it is not clear
> to me that there is a portable and performant way to write these
> methods.
>
> The equals method is not overly complicated to implement:
>
>           public boolean equals(Object object) {
>             if(!(object instanceof ToyPK)) {
>               return false;
>             }
>             ToyPK that = (ToyPK) object;
>             try {
>               return this.index == that.index &&
> this.child.isIdentical(that.child);
>             }
>             catch(RemoteException e) {
>               // if we are unable to call isIdentical, then assume the
> references
>               // are not the same
>               return false;
>             }
>           }
>
> This was not too hard to write, but unfortunately has poor
> performance, in that if I am not colocated with the EJBs, I have to do
> an RPC to the server to handle the isIdentical method.
>
> Much harder is writing the hashCode method.  Obviously, computing a
> hash code for an int is trivial, but what about the Child reference.
> The best that I can do in a totally portable manner is to get the
> child's handle, serialize it to an object output stream, an then
> compute a hash code from the stream's underlying byte array:
>
>             ByteArrayOutputStream byteOutput = new
> ByteArrayOutputStream();
>             ObjectOutputStream objectOutput = new
> ObjectOutputStream(byteOutput);
>             Handle handle = child.getHandle();
>             objectOutput.writeObject(handle);
>             byte[] bytes = byteOutput.toByteArray();
>             int hashCode = 0;
>             for(int i = 0; i < bytes.length; i++) {
>               // be careful to rotate the hashCode around, so you get a
> full
>               // 32 bits of hashing, not just 8 bits.
>               hashCode =
>                   (hashCode <<  8) & 0xffffff00 |
>                   (hashCode >> 24) & 0x000000ff;
>               hashCode += bytes[i];
>             }
>
> Obviously, this code is not for the feint of heart, and it is not yet
> even complete (it does not handle exceptions).
>
> Furthermore, I am not totally sure this code will work portably, in
> that I don't know that an EJBObject reference's handle is guaranteed
> to serialize to same bytes every time.  In fact, I would guess for a
> lot of servers, it might not.
>
> In summary, I think it is pretty much infeasible to implement the hashCode
> method for this primary key class.  Which leads me to one of the following
> conclusions:
>
> 1) The EJB spec. should remove the requirement that a primary key class
> implement
> hashCode and equals.  (I personally see no good reason to need these
> methods, as
> it encourages a very non-OO way of interacting with entity beans, but that
> is another
> discussion).
>
> 2) The EJB spec. should add a requirement that every EJBObject
> implement hashCode and equals method.  Then, I could easily implement
> the PK methods as:
>
>           public int hashCode() {
>             return index + child.hashCode();
>           }
>
>           public boolean equals(Object object) {
>             if(!(object instanceof ToyPK)) {
>               return false;
>             }
>             ToyPK that = (ToyPK) object;
>             return this.index == that.index &&
> this.child.equals(that.child);
>           }
>
> I apologize if the EJB 2.0 spec has already addressed this, and I just
> missed it.
>
> -jkw
>
> Jim Archer wrote:
> >
> > Hi All...
> >
> > I'm trying to understand how references to entity beans work in EJB 1.1
> > servers when using CMP. I'm sorry this is kind of convoluted, but I have
> > been through a few books and and web sites and have not figured out how
> > this works.
> >
> > I'm interested in modeling my world using entity beans that have
> reference
> > to other entity beans, like I would in any other OO system. I don't
> > understand how all this works in EJB when I am using CMP.
> >
> > If I have an eb that represents a child, and another eb that represents
> an
> > address, I would like to put a reference to an Address eb in my Child eb
> > and have CMP handle persisting both of the beans. If I do that will the
> > address in some way be persisted with the Child eb (maybe by saving its
> > primary key)? When I later do a find that loads the Child eb from the
> > database will the Address eb be loaded as well?
> >
> > Now, what if I want to model the Child having some not fixed number of
> > toys? I would like for the Child eb to have an instance of a Collection
> of
> > Toy entity beans. Can I do this such that when the Child is persisted
> that
> > all the toys get persisted as well?
> >
> > Thanks very much!
> >
> > Jim
> >
> >
> ==========================================================================
> =
> > To unsubscribe, send email to [EMAIL PROTECTED] and include in the
> body
> > of the message "signoff EJB-INTEREST".  For general help, send email to
> > [EMAIL PROTECTED] and include in the body of the message "help".
>
> ==========================================================================
> =
> To unsubscribe, send email to [EMAIL PROTECTED] and include in the
> body
> of the message "signoff EJB-INTEREST".  For general help, send email to
> [EMAIL PROTECTED] and include in the body of the message "help".


***********************************************************************
Bear Stearns is not responsible for any recommendation, solicitation,
offer or agreement or any information about any transaction, customer
account or account activity contained in this communication.
***********************************************************************

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff EJB-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to