Value Object Dispatcher Pattern

Discussions

J2EE patterns: Value Object Dispatcher Pattern

  1. Value Object Dispatcher Pattern (9 messages)

    We have 4 main components to this pattern.
    1. Value Objects. The value objects in this system must
    2. Data Access Objects.
    3. Value Object Dispatcher.
    4. Business Objects.

    Here are some code examples.

    The first is the Mutable VO Controller interface. This interface is baseically the CRUD style methods that need to be implemented. The VODispatcher class ant DAO classes will all implement this interface.

    The second is the abstract VODispatcher class. It is abstract so you can implement your own caching methods. It is pretty much fully functional. I used Cacheable Mutable Value Objects in my example. You could implement this in any way that it fits best into your system. It implements the MutableVOController interface as do the DAO's in this sytem. This is for ease of programming and so they implement the same CRUD style methods.

    The third is an example User DAO. This pattern is flexible enough to allow the DAO's and the VODispatcher to be stateless session beans or standalone classes. The examples I am providing are just standalone classes. The dao is basically the controller class/vo assembler for the value object it represents. I generally represent them as a 1...1 with a value object. I used the dao's so that I could abstract the data access layer even more. This way, I can get my data from cmp beans, jdbc, jms, web services, etc and it isn't seen. I can also change the way a dao gets its data for a vo without affecting anything in the system. You'll see that in my example, the DAO implements all the methods from the MutableVOController interface as well as some of its own. These will be accessed through the find method inside the VODispatcher.

    The fourth is an example of the abstract Mutable VO class. All value objects must extend this class. As you can see, this class contains pertinent information regarding the state and controller of the value object.

    The fifth is an example User Value Object. As you can see, the constructor defines its controller. This could be done other ways as well. Properties file, static class, etc. I figures since it shouldn't be changed much, it would be alright inside the constructor. The value object itself also implements an interface User tha defines all the getters and setters you want exposed.

    The sixth example is a business object(session bean). I removed most of the methods and only left enough to give an idea of how it works. We could also implement some sort of command pattern in here for the extra finder methods as you can see by the findUserByStatus business method.

    Anyway, this is a very basic overview. What this allows the programmer to do is abstract the persistence layer from the business layer on the server side. It just saves a lot of time in code writing. Most of the methods used in data access are already implemented and the business objects don't have to know about any of the persistence objects in the server. It also allows us to do data caching and whatever else in a centralized location.

    The only real drawback I have run into with this is that you lose the compile time checking for your DAO's. There may be some performance degredation due to the reflection, but it isn't much.

    I have mixed some cachine/non-caching code in the examples. Just ignore it. I don't have time to go into my caching right now or to build a complete working example. Besides, this is long enough that most of you will be glad I've quit talking, anyway. I'm not the best at explaining my ideas, so I hope some of this makes sense. I'm sure the will be questions, criticisms, and more. If anyone has ideas on how to better this, I will try to be open ;-).

    ****** Mutable VO Controller Interface ****************

    public interface MutableVOController
    {
      public MutableVO insert(MutableVO obj) throws DAOException, DuplicateKeyException;

      public void insertAll(Collection objs) throws DAOException, DuplicateKeyException;

      public int delete(MutableVO obj) throws DAOException, FinderException;

      public int deleteAll(MutableVO obj) throws DAOException;

      public int update(MutableVO obj) throws DAOException, FinderException;

      public java.util.List findAll(MutableVO obj) throws DAOException, FinderException;

      public Object findByPrimaryKey(MutableVO obj) throws DAOException, FinderException;
    }

    ***** Value Object Dispatcher Class ******

    public abstract class VODispatcher implements MutableVOController
    {
    public VODispatcher()
    { }

    public MutableVO insert(MutableVO obj) throws DAOException, DuplicateKeyException
    {
    MutableVO value = null;
    boolean cacheable = false;
    MutableVOController controller = null;

    try
    {
    cacheable = (obj instanceof Cacheable);
    if (obj.getControllerClass() == null)
    throw new DAOException("VODispatcher.insert() : Controller class is null...");
    controller = CachingVOControllerFactory.getController(obj.getControllerClass());

    if (cacheable)
    {
    if (!isCached((CacheableMutableVO)obj))
    {
    value = (MutableVO) controller.insert(obj);
    return cacheObject((CacheableMutableVO)value);
    }
    else
    throw new DuplicateKeyException("Object with same key already cached... : " + obj.getPrimaryKey());
    }
    else
    return (MutableVO) controller.insert(obj);
    }
    catch (NullPointerException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (CachingException ex)
    {
    throw new DAOException(ex.getMessage());
    }
    }

    public void insertAll(Collection objs) throws DAOException, DuplicateKeyException
    {
    MutableVO obj = null;
    boolean cacheable = false;
    MutableVOController controller = null;

    try
    {
    for (Iterator iter = objs.iterator(); iter.hasNext();)
    {
    obj = (MutableVO) iter.next();
    cacheable = (obj instanceof Cacheable);

    if (controller == null)
    {
    if (obj.getControllerClass() == null)
    throw new DAOException("VODispatcher.insertAll() : Controller class is null...");
    controller = CachingVOControllerFactory.getController(obj.getControllerClass());
    }

    if (cacheable)
    {
    if (isCached((CacheableMutableVO)obj))
    removeCachedObject((CacheableMutableVO)obj);
    }
    else
    break;
    }

    if (controller != null)
    controller.insertAll(objs);
    else
    throw new DAOException("Cannon insertAll. Controller is null");
    }
    catch (NullPointerException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (CachingException ex)
    {
    throw new DAOException(ex.getMessage());
    }
    }

    public int delete(MutableVO obj) throws DAOException, FinderException
    {

    int rows = 0;
    boolean cacheable = false;
    MutableVOController controller = null;

    try
    {
    cacheable = (obj instanceof Cacheable);
    if (obj.getControllerClass() == null)
    throw new DAOException("VODispatcher.delete() : Controller class is null...");
    controller = CachingVOControllerFactory.getController(obj.getControllerClass());
    if (cacheable)
    {
    if (isCached((CacheableMutableVO)obj))
    removeCachedObject((CacheableMutableVO)obj);
    }
    return controller.delete(obj);
    }
    catch (NullPointerException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (CachingException ex)
    {
    throw new DAOException(ex.getMessage());
    }
    }

    public int deleteAll(Collection objs) throws DAOException, FinderException
    {
    int rows = 0;

    try
    {
    for (Iterator iter = objs.iterator(); iter.hasNext();)
    rows += delete((MutableVO) iter.next());
    return rows;
    }
    catch (NullPointerException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    }

    public int deleteAll(MutableVO obj) throws DAOException
    {

    int rows = 0;
    boolean cacheable = false;
    MutableVOController controller = null;

    try
    {
    cacheable = (obj instanceof Cacheable);
    if (obj.getControllerClass() == null)
    throw new DAOException("VODispatcher.deleteAll() : Controller class is null...");
    controller = CachingVOControllerFactory.getController(obj.getControllerClass());
    if (cacheable)
    {
    removeCachedObjects(obj.getControllerClass());
    }
    return controller.deleteAll(obj);
    }
    catch (NullPointerException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (CachingException ex)
    {
    throw new DAOException(ex.getMessage());
    }
    }

    public int update(MutableVO obj) throws DAOException, FinderException
    {

    boolean cacheable = false;
    MutableVOController controller = null;

    if (!obj.isDirty())
    return 0;

    try
    {
    cacheable = (obj instanceof Cacheable);
    if (obj.getControllerClass() == null)
    throw new DAOException("VODispatcher.update() : Controller class is null...");
    controller = CachingVOControllerFactory.getController(obj.getControllerClass());
    if (cacheable)
    {
    if (validate((CacheableMutableVO)obj))
    {
    int retval = controller.update((CacheableMutableVO)obj);
    if (retval > 0)
    {
    removeCachedObject((CacheableMutableVO)obj);
    findByPrimaryKey(obj);
    }
    return retval;
    }
    else
    throw new DAOException("VODispatcher.update() : Data is invalid. Record updated from another source.\nPlease re-select your data and start over.");
    }
    else
    return controller.update(obj);
    }
    catch (NullPointerException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (CachingException ex)
    {
    throw new DAOException(ex.getMessage());
    }
    }

    public int updateAll(Collection objs) throws DAOException, FinderException
    {
    if (objs == null || objs.isEmpty())
    throw new DAOException("VODispatcher.updateAll() : MutableVO input parameter cannot be null or empty .....");

    int rows = 0;

    try
    {
    for (Iterator iter = objs.iterator(); iter.hasNext();)
    update((MutableVO) iter.next());
    return rows;
    }
    catch (NullPointerException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    }

    // This method returns object because occasionally we have a call that returns an item other than a value object.
    // Yes, I know this makes this object less pure, but it also allows us to implement other finder methods for value objects
    // here.
    public Object find(MutableVO obj, String method, Object[] args) throws DAOException, FinderException
    {
    Object value = null;
    MutableVOController controller = null;

    try
    {
    if (obj.getControllerClass() == null)
    throw new DAOException("VODispatcher.find() : Controller class is null...");
    controller = CachingVOControllerFactory.getController(obj.getControllerClass());
    return MethodUtils.invokeMethod(controller, method, args);
    }
    catch (NullPointerException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (java.lang.reflect.InvocationTargetException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (java.lang.NoSuchMethodException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (IllegalAccessException ex)
    {

    }
    return null;
    }

    public List findAll(MutableVO obj) throws DAOException, FinderException
    {
    if (obj == null)
    throw new DAOException("VODispatcher.findAll() : MutableVO input parameter cannot be null.....");

    MutableVOController controller = null;

    try
    {
    if (obj.getControllerClass() == null)
    throw new DAOException("VODispatcher.findall() : Controller class is null...");
    controller = CachingVOControllerFactory.getController(obj.getControllerClass());
    return controller.findAll(obj);
    }
    catch (NullPointerException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    }

    public MutableVO findByPrimaryKey(MutableVO obj) throws DAOException, FinderException
    {
    boolean cacheable = false;
    MutableVOController controller = null;

    try
    {
    cacheable = (obj instanceof Cacheable);
    if (obj.getControllerClass() == null)
    throw new DAOException("VODispatcher.findByPrimaryKey() : Controller class is null...");
    controller = CachingVOControllerFactory.getController(obj.getControllerClass());
    if (cacheable)
    {
    if (isCached((CacheableMutableVO)obj))
    {
    return getCachedObject((CacheableMutableVO)obj);
    }
    else
    {
    return processObject((MutableVO) controller.findByPrimaryKey(obj));
    }
    }
    return controller.findByPrimaryKey(obj);
    }
    catch (NullPointerException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (CachingException ex)
    {
    throw new DAOException(ex.getMessage());
    }
    }

    protected abstract boolean isCached(CacheableMutableVO obj) throws CachingException;
    protected abstract void removeCachedObject(CacheableMutableVO obj) throws CachingException;
    public abstract void removeCachedObjects(String key) throws CachingException;
    protected abstract MutableVO cacheObject(CacheableMutableVO obj) throws CachingException;
    protected abstract boolean validate(CacheableMutableVO obj) throws CachingException;
    protected abstract MutableVO getCachedObject(CacheableMutableVO obj) throws CachingException;
    protected abstract long getNextSequence();

    protected MutableVO processObject(MutableVO obj) throws CachingException
    {
    if (obj == null)
    return null;
    boolean cacheable = (obj instanceof Cacheable);

    if (obj.getControllerClass() != null)
    {
    if (cacheable)
    {
    if (isCached((CacheableMutableVO)obj))
    return getCachedObject((CacheableMutableVO)obj);
    else
    return cacheObject((CacheableMutableVO)obj);
    }
    }
    return obj;
    }
    }

    ******************************************************

    *********** User DAO ********************************
    public class UserDAO implements MutableVOController
    {
    static final CoreVOManager voManager = new CoreVOManager();
    private static final String FIND_ALL_QUERY = "SELECT user_id FROM mc_tabos_user order by user_id";
    private static final String FIND_BY_PRIMARY_KEY_QUERY =
    "SELECT user_id, passwd, fullname, status, expire, cust_id FROM mc_tabos_user where user_id = ?";
    private static final String FIND_BY_STATUS_QUERY = "SELECT user_id FROM mc_tabos_user where status = ?";
    private static final String FIND_BY_GROUP_QUERY =
    "SELECT a.user_id FROM mc_tabos_user a, mc_user_groups_ref b where a.user_id = b.user_id and b.group_id = ?";
    private static final String FIND_BY_CUSTOMERID_QUERY =
    "SELECT a.user_id FROM mc_tabos_user a, mc_user_groups_ref b where a.cust_id = ? and a.user_id = b.user_id and b.group_id = 9";

    private static final String UPDATE_QUERY =
    "UPDATE mc_tabos_user SET passwd = ?, fullname = ?, status = ?, expire = ?, cust_id = ? WHERE user_id = ?";

    private static final String INSERT_QUERY =
    "INSERT INTO mc_tabos_user (user_id, passwd, fullname, status, expire, cust_id) values(?, ?, ?, ?, ?, ?)";

    private static final String DELETE_QUERY = "DELETE FROM mc_tabos_user WHERE user_id = ?";
    private static final String DELETE_ALL_QUERY = "DELETE FROM mc_tabos_user";

    public UserDAO()
    {
    }

    /**
    * @see com.tab.server.dao.MutableVOController#insertAll(java.util.Collection)
    */
    public void insertAll(Collection objs) throws DAOException, DuplicateKeyException
    {
    throw new DAOException("public void insert(Collection objs) not implemented...");
    }

    /**
    * @see com.tab.server.dao.MutableVOController#insert(com.tab.server.dao.MutableVO)
    */
    public Object insert(MutableVO obj) throws DAOException, DuplicateKeyException
    {
    User user = (User) obj;
    Connection con = null;
    PreparedStatement pstmt = null;

    try
    {
    con =
    ((DataSource) CoreServiceLocator
    .getInstance()
    .getDataSource(CoreServiceLocator.Services.IFX_DATASOURCE))
    .getConnection();
    pstmt = con.prepareStatement(INSERT_QUERY);
    pstmt.setString(1, user.getUserId());
    pstmt.setString(2, user.getPassword());
    pstmt.setString(3, user.getName());
    pstmt.setString(4, user.getStatus().toString());
    pstmt.setInt(5, DateUtil.getIntegerDate(user.getExpire()));
    Integer custId = user.getCustomerId();
    if (custId == null)
    pstmt.setNull(6, java.sql.Types.NULL);
    else
    pstmt.setInt(6, custId.intValue());
    if (pstmt.executeUpdate() < 1)
    throwInsertException(obj);
    }
    catch (NamingException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (SQLException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    finally
    {
    closeResources(con);
    }
    return user;
    }

    /**
    * @see com.tab.server.dao.MutableVOController#delete(com.tab.server.dao.MutableVO)
    */
    public int delete(MutableVO obj) throws DAOException, FinderException
    {
    User user = (User) obj;
    Connection con = null;
    PreparedStatement pstmt = null;
    int rows = 0;

    try
    {
    con =
    ((DataSource) CoreServiceLocator
    .getInstance()
    .getDataSource(CoreServiceLocator.Services.IFX_DATASOURCE))
    .getConnection();
    pstmt = con.prepareStatement(DELETE_QUERY);
    pstmt.setString(1, user.getUserId());
    rows = pstmt.executeUpdate();
    if (rows < 1)
    throwDeleteException(obj);
    }
    catch (NamingException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (SQLException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    finally
    {
    closeResources(con);
    }
    return rows;
    }

    /**
    * @see com.tab.server.dao.MutableVOController#deleteAll(com.tab.server.dao.MutableVO)
    */
    public int deleteAll(MutableVO obj) throws DAOException
    {
    return -1;
    }

    /**
    * @see com.tab.server.dao.MutableVOController#update(com.tab.server.dao.MutableVO)
    */
    public int update(MutableVO obj) throws DAOException, FinderException
    {
    if (!obj.isDirty())
    return 0;
    User user = (User) obj;
    Connection con = null;
    PreparedStatement pstmt = null;
    int rows = 0;

    try
    {
    con =
    ((DataSource) CoreServiceLocator
    .getInstance()
    .getDataSource(CoreServiceLocator.Services.IFX_DATASOURCE))
    .getConnection();
    pstmt = con.prepareStatement(UPDATE_QUERY);
    pstmt.setString(1, user.getPassword());
    pstmt.setString(2, user.getName());
    pstmt.setString(3, user.getStatus().toString());
    pstmt.setInt(4, DateUtil.getIntegerDate(user.getExpire()));
    Integer custId = user.getCustomerId();
    if (custId == null)
    pstmt.setNull(5, java.sql.Types.NULL);
    else
    {
    System.out.println("Inserting customer Id " + custId);
    pstmt.setInt(5, custId.intValue());
    }
    System.out.println("Executing update........");
    pstmt.setString(6, user.getUserId());
    rows = pstmt.executeUpdate();
    if (rows < 1)
    throwUpdateException(obj);
    }
    catch (NamingException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (SQLException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    finally
    {
    closeResources(con);
    }
    return rows;
    }

    /**
    * @see com.tab.server.dao.MutableVOController#findAll(com.tab.server.dao.MutableVO)
    */
    public java.util.List findAll(MutableVO obj) throws DAOException, FinderException
    {
    Connection con = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    List results = new ArrayList();

    try
    {
    con =
    ((DataSource) CoreServiceLocator
    .getInstance()
    .getDataSource(CoreServiceLocator.Services.IFX_DATASOURCE))
    .getConnection();
    pstmt = con.prepareStatement(FIND_ALL_QUERY);
    rs = pstmt.executeQuery();

    for (; rs != null && rs.next();)
    {
    User tmpUser = (User) voManager.findByPrimaryKey(new UserVO(rs.getString(1)));
    if (!(tmpUser.getUserId().trim().equalsIgnoreCase("sysop")))
    results.add(tmpUser);
    }
    }
    catch (NamingException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (SQLException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    finally
    {
    closeResources(con);
    }
    return results;
    }

    /**
    * @see com.tab.server.dao.MutableVOController#findByPrimaryKey(com.tab.server.dao.MutableVO)
    */
    public Object findByPrimaryKey(MutableVO obj) throws DAOException, FinderException
    {
    User user = null;
    Connection con = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;

    try
    {
    con =
    ((DataSource) CoreServiceLocator
    .getInstance()
    .getDataSource(CoreServiceLocator.Services.IFX_DATASOURCE))
    .getConnection();
    pstmt = con.prepareStatement(FIND_BY_PRIMARY_KEY_QUERY);
    pstmt.setString(1, obj.getPrimaryKey().toString().trim());
    rs = pstmt.executeQuery();
    if (rs == null || !rs.next())
    throwFinderException(obj);
    user = (User) createVO(rs);
    }
    catch (NamingException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (SQLException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    finally
    {
    closeResources(con);
    }
    return (User) user;
    }

    /**
    * Method findByStatus.
    * @param status
    * @return List
    * @throws DAOException
    * @throws FinderException
    */
    public List findByStatus(String status) throws DAOException, FinderException
    {
    UserVO user = null;
    Connection con = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    List results = new ArrayList();

    try
    {
    con =
    ((DataSource) CoreServiceLocator
    .getInstance()
    .getDataSource(CoreServiceLocator.Services.IFX_DATASOURCE))
    .getConnection();
    pstmt = con.prepareStatement(FIND_BY_STATUS_QUERY);
    pstmt.setString(1, status.trim());
    rs = pstmt.executeQuery();
    for (; rs != null && rs.next();)
    results.add((User) voManager.findByPrimaryKey(new UserVO(rs.getString(1))));
    }
    catch (NamingException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (SQLException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    finally
    {
    closeResources(con);
    }
    return results;
    }

    /**
    * Method findByGroup.
    * @param groupId
    * @return List
    * @throws DAOException
    * @throws FinderException
    */
    public List findByGroup(Integer groupId) throws DAOException, FinderException
    {
    UserVO user = null;
    Connection con = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    List results = new ArrayList();

    try
    {
    con =
    ((DataSource) CoreServiceLocator
    .getInstance()
    .getDataSource(CoreServiceLocator.Services.IFX_DATASOURCE))
    .getConnection();
    pstmt = con.prepareStatement(FIND_BY_GROUP_QUERY);
    pstmt.setInt(1, groupId.intValue());
    rs = pstmt.executeQuery();
    for (; rs != null && rs.next();)
    results.add((User) voManager.findByPrimaryKey(new UserVO(rs.getString(1))));
    }
    catch (NamingException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (SQLException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    finally
    {
    closeResources(con);
    }
    return results;
    }

    /**
    * Method findByCustomerId.
    * @param customerId
    * @return List
    * @throws DAOException
    * @throws FinderException
    */
    public List findByCustomerId(Integer customerId) throws DAOException, FinderException
    {
    UserVO user = null;
    Connection con = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    List results = new ArrayList();

    try
    {
    con =
    ((DataSource) CoreServiceLocator
    .getInstance()
    .getDataSource(CoreServiceLocator.Services.IFX_DATASOURCE))
    .getConnection();
    pstmt = con.prepareStatement(FIND_BY_CUSTOMERID_QUERY);
    pstmt.setInt(1, customerId.intValue());
    rs = pstmt.executeQuery();
    for (; rs != null && rs.next();)
    results.add((User) voManager.findByPrimaryKey(new UserVO(rs.getString(1))));
    }
    catch (NamingException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    catch (SQLException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    finally
    {
    closeResources(con);
    }
    return results;
    }

    /**
    * @see com.tab.server.dao.AbstractMutableVOController#createVO(java.sql.ResultSet)
    */
    protected MutableVO createVO(ResultSet rs) throws DAOException, FinderException
    {
    try
    {
    UserVO user = new UserVO(rs.getString(1).trim());
    user.setPassword(rs.getString(2));
    user.setName(rs.getString(3));
    user.setStatus(new Character(rs.getString(4).toString().trim().charAt(0)));
    user.setExpire(DateUtil.getCalendar(rs.getInt(5)));
    int custId = rs.getInt(6);
    user.setCustomerId(custId < 1 ? null : new Integer(custId));
    user.setDirty(false);
    return user;
    }
    catch (SQLException ex)
    {
    throw new DAOException(ExceptionUtil.stackTraceToString(ex));
    }
    }

    }

    *************************************************

    ************ MutableVO **************************
    public class MutableVO implements Serializable
    {
      private String controllerClass = null;
      private Object primaryKey = null;
      private Boolean dirty = null;

      public MutableVO()
      {
        setDirty(false);
      }

      public MutableVO(Object primaryKey)
      {
        this();
        setPrimaryKey(primaryKey);
      }

      public Object getPrimaryKey()
      {
        return primaryKey;
      }

      public void setPrimaryKey(Object primaryKey)
      {
        this.primaryKey = primaryKey;
      }

      public String getControllerClass()
      {
        return controllerClass;
      }

      protected void setControllerClass(String controllerClass)
      {
        this.controllerClass = controllerClass;
      }

      public void setDirty(boolean dirty)
      {
        this.dirty = new Boolean(dirty);
      }

      public boolean isDirty()
      {
        return dirty.booleanValue();
      }
    }

    ****************************************************
    ***************** UserVO **************************
    public class UserVO extends MutableVO implements User, Serializable
    {
    private String userId;
    private String password;
    private String name;
    private Character status;
    private Integer customerId;

    public UserVO()
    {
    super();
    setControllerClass("com.tab.server.dao.UserDAO");
    }

    public UserVO(String primaryKey)
    {
    this();
    setUserId(primaryKey);
    }

    public String getUserId()
    {
    return this.userId;
    }

    public void setUserId(String id)
    {
    this.userId = id;
    setPrimaryKey(id);
    setDirty(true);
    }

    public Integer getCustomerId()
    {
    return customerId;
    }

    public void setCustomerId(Integer id)
    {
    this.customerId = id;
    setDirty(true);
    }

    public String getPassword()
    {
    return this.password;
    }

    public void setPassword(String password)
    {
    this.password = password;
    setDirty(true);
    }

    public String getName()
    {
    return this.name;
    }

    public void setName(String name)
    {
    this.name = name;
    setDirty(true);
    }

    public Character getStatus()
    {
    return status;
    }

    public void setStatus(Character status)
    {
    this.status = status;
    setDirty(true);
    }
    }

    *************************************************

    ********** SessionFacadeBean *******************
    public class SessionFacadeBean
    {
    static final VODispatcher voDispatcher = new VODispatcher();

    public int update(MutableVO valueObject) throws MessageException
    {
    int rowsUpdated = 0;

    try
    {
    rowsUpdated = voManager.update((MutableVO) valueObject);
    return rowsUpdated;
    }
    catch (Exception ex)
    {
    LogUtil.log("Error", LogUtil.ERROR, LOGGER, ex);
    }
    }

    public MutableVO insert(MutableVO valueObject) throws MessageException
    {
    Object returnObject = null;

    try
    {
    returnObject = voManager.insert((MutableVO) valueObject);
    return returnObject;
    }
    catch (Exception ex)
    {
    LogUtil.log("Error", LogUtil.ERROR, LOGGER, ex);
    }
    }

    public void insertAll(List valueObjects) throws MessageException
    {
    try
    {
    voManager.insertAll(valueObjects);
    }
    catch (Exception ex)
    {
    LogUtil.log("Error", LogUtil.ERROR, LOGGER, ex);
    }
    }

    public void delete(MutableVO valueObject) throws MessageException
    {
    try
    {
    voManager.delete(valueObject);
    }
    catch (Exception ex)
    {
    LogUtil.log("Error", LogUtil.ERROR, LOGGER, ex);
    }
    }

    public User getUserByUserId(String id) throws MessageException
    {
    try
    {
    return (User) voManager.findByPrimaryKey(new UserVO(id));
    }
    catch (Exception ex)
    {
    LogUtil.log("Error", LogUtil.ERROR, LOGGER, ex);
    }
    }


    public List findUserByStatus(String status) throws MessageException
    {
    final String METHOD = "findByStatus";
    final MutableVO VALUE_OBJECT = new UserVO();

    Object[] args = { status };

    try
    {
    return (List) voManager.find(VALUE_OBJECT, METHOD, args);
    }
    catch (Exception ex)
    {
    LogUtil.log("Error", LogUtil.ERROR, LOGGER, ex);
    }
    }
    }

    Threaded Messages (9)

  2. Value Object Dispatcher Pattern[ Go to top ]

    Looks like you're trying to implement CMP entity bean...
  3. The nice thing about this is that you can connect to anything through the dao. CMP, flat file, SOAP, etc.
  4. Hard to read![ Go to top ]

    When a pattern is to be presented, UML diagrams is a more professional and more concise way to do it!
  5. Hard to read![ Go to top ]

    When a pattern is to be presented, UML diagrams is a more professional and more concise way to do it!


    I most certainly agree. There is none of standard form of presenting patterns in this article; following this form is part of what makes a Design Pattern. It's a pity, because I actually found this article interesting and useful, but if it'd been presented more formally, it'd certainly have saved me a lot of time (and helt people immediately recognise whether or not the pattern is applicable in their situation).
  6. what is the voManager? maybe it should be voDispatcher.
  7. Thats what it is.[ Go to top ]

    Sorry, I didn't review my presentation/mess very well. I will try and post a more legible document soon.
  8. Sorry. I know its hard to follow[ Go to top ]

    I am working on some uml diagrams and I will try to get them posted soon. I was kind of in a hurry when I posted it. I should have waited until I had more time. I didn't plan on it being so messy. But then again... Who does. lol
  9. Hello every body.I am a chinese with poor english and of course this article is not so clearly to understand(of course this is article is very good and helpful).So I ask for detail code or other helper class code to master and evaluate it.My e-mail is ejbstart at hotmail dot com.
        Thanks a lot in advance.
  10. I started a new thread.[ Go to top ]

    I started a new thread that has a simple uml diagram and is hopefully easier to follow. This thread can be killed as far as I am concerned.

    VO Dispatcher Revised