Chris,
If the EJB is run on multiple machines (or in multiple VMs), I don't believe
you would get PK collisions. Correct me if I'm wrong.
When the EJB is instanced by the container, it saves the current timestamp.
The sequence numbers all start at 0, but since it is CRC'd (or
MessageDigest'ed, or other...) with the timestamp, the result should be
unique, as long as the timestamps are different. Wouldn't they be different
in GemStone and in other clustered servers?
jim
----- Original Message -----
From: Chris Raber <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Thursday, July 29, 1999 9:34 AM
Subject: Re: UUID Implementation
> I think your implementation assumes the entity bean instance at run-time
> will be a singleton... This may be the case in WL, but not in general. And
> even in WL, what happens when you go to their "clustered" configuration
> (i.e. multi-VM)?
>
> Also, I don't believe you can count on that per the spec, can you?
>
> If more than one instance gets activated at run tim, you'll get PK
> collisions...
>
> My fall back position on this sort of thing has been to implement
singletons
> as RMI or CORBA services. Not a portable EJB approach, but then again EJB
> can't address every scenario.
>
> -Chris.
>
> > -----Original Message-----
> > From: James Cook [SMTP:[EMAIL PROTECTED]]
> > Sent: Wednesday, July 28, 1999 10:20 AM
> > To: [EMAIL PROTECTED]
> > Subject: UUID Implementation
> >
> > Sorry if this shows up twice. It didn't appear in the archive list and
it
> > wasn't forwarded to me.
> >
> > A few people have asked in other threads about implementing a Unique ID
> > Generator. A few people were debating whether it could be implemented as
> > an
> > EJB, and if so, would it be a session bean or entity bean. There are
> > probably many ways to approach the problem, so I would be interested in
> > other opinions as well.
> >
> > Many clients will need to share a UID object. These clients would
> > frequently
> > be EJB's themselves, since UID generation is a key part to creating
> > primary
> > keys for most entity beans. The UID entity bean will return a
sufficiently
> > unique integer value to any client that calls it. The business process
> > that
> > I chose to implement this "unique" number is as follows:
> >
> > 1. Split a timestamp (long) into two int's.
> > 2. Increment a sequence counter (int).
> > 3. Use the java.util.zip.CRC32 class to generate a CRC value for
> > these 3 integer values.
> > 4. Return this value.
> >
> > In order to accomplish this, I implemented an entity bean that uses
> > bean-managed persistence (BMP). The bean actually performs no
persistence,
> > so I provide empty implementations of the ejbXXX methods. There is no
need
> > for persistence because of the business logic in the getUID() method. As
> > long as the sequence counter is incremented on each call, the CRC value
> > should be unique. If the EJB Server is restarted, the counter will reset
> > to
> > 0 (and increment again), but the timestamp will be different. This
should
> > keep the resulting values unique and sufficently fast for most demanding
> > applications.
> >
> > I'm not up on whether CRC32 is effective at generating truly unique
> > numbers
> > given 3 unique input values. Maybe someone else can either verify that
it
> > is
> > sufficient or provide an alternative method. I used to know the RFC for
> > generating a UUID, but I can't seem to find it now. It used information
> > that
> > Java could have difficulty obtaining, such as NIC/MAC address.
> >
> > Following is the source code for the bean. Please feel free to use it
> > anywhere you wish for any purpose. Also, your feedback is appreciated.
> > I've
> > attached the compiled source that is ready to be deployed with WebLogic
> > Server.
> >
> > jim
> >
> > Remote Interface
> > =================
> > package com.vxs.ejb.uid;
> >
> > import javax.ejb.*;
> > import java.rmi.*;
> >
> > public interface UID extends EJBObject {
> >
> > /**
> > * Returns a unique identifier value as an integer.
> > */
> > public long getUID() throws RemoteException;
> > }
> >
> > Home Interface
> > ===============
> > package com.vxs.ejb.uid;
> >
> > import javax.ejb.*;
> > import java.rmi.*;
> >
> > public interface UIDHome extends EJBHome {
> >
> > /**
> > * This will be the preferred method of locating/creating the UID
> > bean.
> > * This isn't usual for the create method to have no parameters,
but
> > we
> > * want to be sure that all clients are using the same instance of
> > the
> > * bean.
> > */
> > public UID create() throws java.rmi.RemoteException,
> > javax.ejb.CreateException;
> >
> > /**
> > * The findByPrimaryKey method is required by the EJB spec. If the
> > client
> > * uses this method, the primary key object that they pass in will
be
> > * irrelevant. This is done to ensure the same instance of the bean
> > is
> > * always used.
> > */
> > public UID findByPrimaryKey(UIDPK primaryKey) throws
RemoteException,
> > FinderException;
> > }
> >
> > Enterprise JavaBean
> > ====================
> > package com.vxs.ejb.uid;
> >
> > import java.rmi.*;
> > import javax.ejb.*;
> > import java.util.zip.CRC32;
> >
> > public class UIDBean implements EntityBean {
> > private EntityContext entityContext;
> > private CRC32 crc = new CRC32();
> > private int sequenceID;
> > private int a,b;
> >
> > /**
> > * The create method is guaranteed to be executed at least once. It
> > is
> > here
> > * that the timestamp value is read. The timestamp is split into
two
> > * integer values, as well. Note the return of a bogus primary key
> > object.
> > */
> > public UIDPK ejbCreate() throws RemoteException, CreateException {
> > long now = System.currentTimeMillis();
> > a = (int)(now >> 32);
> > b = (int) now;
> > return new UIDPK();
> > }
> >
> > public void ejbPostCreate() throws CreateException {
> > }
> >
> > /**
> > * The CRC32 object is reset and fed the two timestamp integers.
> > Next,
> > the
> > * sequence number is crunched, and sunsequently incremented. The
> > * calculated CRC value is then returned.
> > */
> > public long getUID() throws RemoteException {
> > crc.reset();
> > crc.update(a);
> > crc.update(b);
> > crc.update(sequenceID++);
> > return crc.getValue();
> > }
> >
> > public UIDPK ejbFindByPrimaryKey(UIDPK uidPk){
> > return new UIDPK();
> > }
> >
> > public void ejbActivate() throws RemoteException {
> > }
> >
> > public void ejbLoad() throws RemoteException {
> > }
> >
> > public void ejbPassivate() throws RemoteException {
> > }
> >
> > public void ejbRemove() throws RemoteException, RemoveException {
> > }
> >
> > public void ejbStore() throws RemoteException {
> > }
> >
> > public void setEntityContext(EntityContext context) throws
> > RemoteException {
> > entityContext = context;
> > }
> >
> > public void unsetEntityContext() throws RemoteException {
> > entityContext = null;
> > }
> > }
> >
> > EJB Primary Key
> > ================
> > package com.vxs.ejb.uid;
> >
> > public class UIDPK implements java.io.Serializable {
> >
> > public long id;
> >
> > /**
> > * This EJB primary key is a little different than most. The UID
EJB
> > does
> > * not represent a variety of different instances with different
> > data.
> > * In this case, there will only be one unique instance of our bean
> > on
> > the
> > * system. This will ensure that every client will go through our
> > bean
> > for
> > * service.
> > *
> > * To this end, the primary key's id value will always return 0.
> > */
> > public UIDPK() {
> > id = 0;
> > }
> >
> > public boolean equals(Object parm1) {
> > return super.equals( parm1);
> > }
> >
> > public int hashCode() {
> > return super.hashCode();
> > }
> >
> > public String toString() {
> > return "UIDPK: " + id;
> > }
> > }
> >
> > Test Client
> > ============
> > package com.vxs.ejb.uid;
> >
> > import javax.naming.*;
> > import java.io.*;
> > import java.rmi.*;
> > import java.util.*;
> >
> > public class UIDClient {
> >
> > private static PrintStream o = System.out;
> >
> > public static void main(String[] args) {
> > try{
> > Context jndiContext = getWebLogicContext();
> > o.println("Context retrieved: " + jndiContext);
> > UIDHome uidHome = (UIDHome)jndiContext.lookup("uid");
> >
> > UID uid = uidHome.create();
> > for (int i=0; i< 100; i++) {
> > long x = uid.getUID();
> > System.out.println(x);
> > }
> > } catch (Throwable t){t.printStackTrace();}
> >
> > }
> >
> > public static Context getWebLogicContext() throws
> > javax.naming.NamingException {
> > Properties p = new Properties();
> >
> >
p.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFacto
> > ry
> > ");
> > p.put(Context.PROVIDER_URL,"t3://localhost:7001");
> >
> > o.println("Obtaining context: " + p);
> >
> > return new InitialContext(p);
> > }
> >
> > }
> >
> >
==========================================================================
> > =
> > 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".
>
===========================================================================
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".