Primary Key Generator Bean

Discussions

EJB design: Primary Key Generator Bean

  1. Primary Key Generator Bean (4 messages)

    Hello,
     I have written a simple primary key generator for my entity beans. Base on this discussion.
     It is a stateful session bean based on the HIGH/LOW principle. I have a pktable in my database (MySQL) which has just one auto_increment column. This column gives the High values. The code that I am pasting below is self explanatory.

    Could anybody please be kind enough to critisize it? I want to know in what situation it might fail.


    [CODE]
    public class PKGeneratorBean implements SessionBean
    {
      SessionContext sessionContext;

      int theHigh;
      int theLow;

      int HIGHFACTOR;

      Object mutex = new Object();

      public void ejbRemove() { }
      public void ejbActivate() { }
      public void ejbPassivate() { }

      public void setSessionContext(SessionContext sessionContext) { this.sessionContext = sessionContext; }

      public Integer getNextID() throws EJBException
      {
         synchronized(mutex)
         {
           if (theLow == HIGHFACTOR)
           {
             loadHigh();
             theLow = 0;
           }
           return new Integer(HIGHFACTOR * theHigh + theLow++);
         }
      }

      public void ejbCreate() throws CreateException
      {
        try
        {
          InitialContext ctx = new InitialContext();
          this.HIGHFACTOR = ( (Integer) ctx.lookup("java:comp/env/HIGHFACTOR")).intValue();
          System.out.println("HIGHFACTOR = "+HIGHFACTOR);

          loadHigh();
        }
        catch(Exception e)
        {
          throw new CreateException( e.getMessage());
        }
      }

      public void loadHigh() throws EJBException
      {
        try
        {
          InitialContext ctx = new InitialContext();

          DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/omsdb");
          Connection con = ds.getConnection();
          Statement stmt = con.createStatement();
          stmt.executeUpdate("insert into pktable values(NULL)");
          ResultSet rs = stmt.executeQuery("select last_insert_id()");
          this.theHigh = rs.getInt(1);
          stmt.close();
          con.close();
        }
        catch(Exception e)
        {
          throw new EJBException( e.getMessage());
        }
      }

    }
    [/CODE]

    Thank you very much for your time.

    Threaded Messages (4)

  2. Primary Key Generator Bean[ Go to top ]

    Hi,
    I making following assumption for your code.

    1. loadHigh() methods load a different value of theHigh variable every time
       it is called. This attains more significance in case when multiple instances of PKGeneratorBean are loaded in memory.
    If the assumption is true then code should run fine in all cases.

    Comment.
    1. Why are you using synchronized(mutex)? , ejbs are always thread safe.

    Thanks,
    Badrish
  3. about synchronized(mutex)[ Go to top ]

    Comment.

    > 1. Why are you using synchronized(mutex)? , ejbs are always thread safe.
    >
    Thank you very much for the review, Badrish. So do you think there is no need of syncrhonizing the check condition and increment part?
    Is there a guarantee that multiple client requests to this bean will be serialized. I'm sckeptical about it because this is a stateless session bean and so I believe the container will allow multiple requests to be served simultaneously. In that case, I thought that the mutex part is necessary.
    I would like to know your thoughts on this.
  4. Re:about synchronized(mutex)[ Go to top ]

    Hi,
    Is it a stateless or stateful session bean ?
    In your first message I see it mentioned as stateful session bean.
    Any way there is no need for using synchronized(mutex).
    Reason.
    EJB goes not allow concurrent access, so method getNextID()
    will never be accessed by two different threads simultaneously(situation like one thread in waiting state and other accessing the same code with same values will not occur).
  5. Synchronized EJB code[ Go to top ]

    I'd put it more strongly than this - an EJB must *not* attempt to manage its own threading. Attempting to do so can sabotage the container's ability to manage the bean. It is potentially harmful as well as just being unnecessary, and furthermore the container's confusion may not be apparent during tests.