You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Bill Lear <ra...@zopyra.com> on 2003/10/03 13:51:56 UTC

[HiveMind] Question about DAO creation

I've been using hivemind to build a DAO factory.  I think I may be
using this in a rather crude way that undoes some of the good hivemind
has done, so I thought I'd ask for some advice.  I have a second question
regarding JDBC connections.

First, in Tapestry, I store my DAO object in the Global class, but
I seem to have reverted to the singleton pattern instead of
doing things the hivemind way:

public class Global {
    private static DAO dao;

    private static Object daoMutex = new Object();

    public DAO getDAO() throws DAOException {
        synchronized (daoMutex) {
            if (dao == null) {
                dao = createDAO();
            }
        }
        return dao;
    }

    private DAO createDAO() throws DAOException {
        DAOFactory f = (DAOFactory) Services.getService(DAOFactory.class);
        return f.createDAO();
    }
}

Services is a wrapper around Hivemind that gets a service based on a
class name:

public class Services {
    public static Object getService(Class theClass) {
        ClassResolver resolver = new DefaultClassResolver();
        RegistryBuilder builder = new RegistryBuilder();

        builder.processModules(resolver);

        Registry registry = builder.constructRegistry(Locale.getDefault());

        return registry.getService(theClass.getName(), theClass);
    }
}

My hivemodule looks like this:

<module id="com.foobar.eci.dao" version="1.0.0">
    <service-point id="DAOFactory"
                   interface="com.foobar.eci.dao.DAOFactory">
        <invoke-factory service-id="hivemind.BuilderFactory">
            <construct
	        class="com.foobar.eci.dao.mysql.MySQLDAOFactory">
                <set property="name" value="eci"/>
                <set property="protocol" value="mysql"/>
                <set property="driver"
		     value="org.gjt.mm.mysql.Driver"/>
                <set property="host" value="localhost"/>
                <set property="port" value="3906"/>
                <set property="user" value="bogon"/>
                <set property="password" value="foobar"/>
            </construct>
        </invoke-factory>
    </service-point>
</module>

I'm not quite sure how to have hivemind construct both the Global
object and DAO object, and set the DAO object in the Global object.


Second question: I use a command pattern to separate the implementation of
different methods in the DAO class.  So, if I have a DAO that looks like
this:

public interface DAO {
    Employee getEmployee(Integer employeeID) throws DAOException;

    Employee[] getEmployees(String sortColumn) throws DAOException;

    void insertEmployee(Employee employee) throws DAOException;
}

I implement this with a class to expose this interface, and three
classes to implement each of the commands.  Notice the MySQLDAO
class stores the JDBC connection object and passes it to each
of the command classes it constructs:

public class MySQLDAO implements DAO {
    void init(Connection connection) throws DAOException {
        try {
            getEmployee = new GetEmployee(connection);
            getEmployees = new GetEmployees(connection);
            insertEmployee = new InsertEmployee(connection);
        } catch (SQLException sex) {
            LOG.error(sex.toString());
            throw new DAOException(sex.toString());
        }
    }

    private GetEmployee getEmployee;

    public Employee getEmployee(Integer employeeID) throws DAOException {
        return getEmployee.execute(employeeID);
    }

    private GetEmployees getEmployees;

    public Employee[] getEmployees(String sortColumn) throws DAOException {
        return getEmployees.execute(sortColumn);
    }

    private InsertEmployee insertEmployee;

    public void insertEmployee(Employee employee) throws DAOException {
        insertEmployee.execute(employee);
    }
}

The factory is what I have Hivemind creating:

public class MySQLDAOFactory implements DAOFactory {
    private String name;
    private String protocol;
    private String driver;
    private String host;
    private String port;
    private String user;
    private String password;

    public DAO createDAO() throws DAOException {
        MySQLDAO dao = new MySQLDAO();

        try {
            String connURL = "jdbc:" + protocol + "://";

            if (host.length() == 0) {
                connURL += name;
            } else {
                connURL += host + ":" + port + "/" + name;
            }

            // This ensures no timeouts for MySQL after default idle period
            connURL += "?autoReconnect=true";

            Class.forName(driver);
            dao.init(DriverManager.getConnection(connURL, user, password));
        } catch (SQLException sex) {
            throw new DAOException(sex);
        } catch (ClassNotFoundException ex) {
            throw new DAOException(ex);
        }

        return dao;
    }

    // Get-Set methods for private variables elided ...
}

So, what I'm wondering is: I have embedded a JDBC connection object in
the each of the three command objects.  This seems too direct and
inflexible, but I don't know what other alternatives to use.  Also, I
would like to be able to unit-test each of the three command classes,
but I would prefer to be able to use hivemind to construct the JDBC
connection for me, in which case, I might re-factor things in the
MySQLDAO class itself to also take advantage of hivemind to get the
connection object (but then, what about pooling?  Can hivemind create
a JDBC connection?  Is this desirable?).

Finally, when testing the DAO, I need to be able to clear the database
before each test case method is run.  I would prefer to use the same
connection that the DAO has, but exposing that in the DAO interface
seems a bit lame (Connection getConnection()) and too concrete.

In any case, if anyone has comments or suggestions to share on managing
JDBC connections, I'd appreciate it.


Bill

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [HiveMind] Question about DAO creation

Posted by Harish Krishnaswamy <hk...@comcast.net>.
Sorry, I did not mean your response was not good, I just thought 
reinventing the wheel would be a waste of time and energy.

Cool, peace,
Harish
:-)

Christian Essl wrote:

> Yes that's better at least I always said your answer is better.
> On Fri, 03 Oct 2003 11:23:07 -0400, Harish Krishnaswamy 
> <hk...@comcast.net> wrote:
>
>> Why not use an off-the-shelf pooling library like DBCP or CP03(?) or 
>> something?
>>
>> -Harish
>>
>> Bill Lear wrote:
>>
>>> On Friday, October 3, 2003 at 16:33:58 (+0200) Christian Essl writes:
>>>
>>>
>>>> ...
>>>> Than I would give out the DOA directly as a service. Than as you 
>>>> also said (for your second question) I would implement a 
>>>> ConnectionPool service interface and a (or more) implementation(s) 
>>>> (one which just holds one connection - for your testing). Than I 
>>>> would change the DAO- implementation to take a ConnectionPool 
>>>> service as parameter and get the connection from there.
>>>>
>>>> interface ConnectionPool {
>>>> public Connection getConnection();
>>>> public void returnConnection(Connection connection);
>>>> }
>>>>
>>>>
>>>
>>> Hmm, I'm starting to like this.
>>>
>>>
>>>
>>>> <module...>
>>>>
>>>> <service-point id="DAO"
>>>> ...
>>>> </service>
>>>>
>>>> <service-point id="ConnectionPool"
>>>> ...
>>>> </service>
>>>>
>>>>
>>>
>>> Ok, I think I'm getting the point...
>>>
>>>
>>>
>>>> Now you saved the factory and you have access to the single 
>>>> connection in your test-code. In running code you can still change 
>>>> to a real connection pool. With this suggestion you still have to 
>>>> change both the DAO service-definition and the ConnectionPool 
>>>> definition if you want to change the DAO implementation. However 
>>>> this can be cleaned up, see the Overriding-Services tutorial at the 
>>>> hivemind page.
>>>>
>>>> Finally: I think (like you) you should if you are going to use a 
>>>> 'real' connection-pool take the connection out of the commands. I 
>>>> would give the commands the connection as a parameter each time 
>>>> they are called. The caller would get it from the ConnectionPool 
>>>> call the command with it and return it straight to the pool.
>>>>
>>>>
>>>
>>> This is something I've been considering, and I think I'm convinced that
>>> this is a better way to do things.
>>>
>>> Thanks for the feedback.
>>>
>>>
>>> Bill
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
>>> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>>>
>>>
>>>
>>>
>>
>
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [HiveMind] Question about DAO creation

Posted by Christian Essl <ch...@yahoo.de>.
Yes that's better at least I always said your answer is better.
On Fri, 03 Oct 2003 11:23:07 -0400, Harish Krishnaswamy 
<hk...@comcast.net> wrote:

> Why not use an off-the-shelf pooling library like DBCP or CP03(?) or 
> something?
>
> -Harish
>
> Bill Lear wrote:
>
>> On Friday, October 3, 2003 at 16:33:58 (+0200) Christian Essl writes:
>>
>>
>>> ...
>>> Than I would give out the DOA directly as a service. Than as you also 
>>> said (for your second question) I would implement a ConnectionPool 
>>> service interface and a (or more) implementation(s) (one which just 
>>> holds one connection - for your testing). Than I would change the DAO- 
>>> implementation to take a ConnectionPool service as parameter and get 
>>> the connection from there.
>>>
>>> interface ConnectionPool {
>>> public Connection getConnection();
>>> public void returnConnection(Connection connection);
>>> }
>>>
>>>
>>
>> Hmm, I'm starting to like this.
>>
>>
>>
>>> <module...>
>>>
>>> <service-point id="DAO"
>>> ...
>>> </service>
>>>
>>> <service-point id="ConnectionPool"
>>> ...
>>> </service>
>>>
>>>
>>
>> Ok, I think I'm getting the point...
>>
>>
>>
>>> Now you saved the factory and you have access to the single connection 
>>> in your test-code. In running code you can still change to a real 
>>> connection pool. With this suggestion you still have to change both the 
>>> DAO service-definition and the ConnectionPool definition if you want to 
>>> change the DAO implementation. However this can be cleaned up, see the 
>>> Overriding-Services tutorial at the hivemind page.
>>>
>>> Finally: I think (like you) you should if you are going to use a 'real' 
>>> connection-pool take the connection out of the commands. I would give 
>>> the commands the connection as a parameter each time they are called. 
>>> The caller would get it from the ConnectionPool call the command with 
>>> it and return it straight to the pool.
>>>
>>>
>>
>> This is something I've been considering, and I think I'm convinced that
>> this is a better way to do things.
>>
>> Thanks for the feedback.
>>
>>
>> Bill
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>>
>>
>>
>>
>



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [HiveMind] Question about DAO creation

Posted by Harish Krishnaswamy <hk...@comcast.net>.
Why not use an off-the-shelf pooling library like DBCP or CP03(?) or 
something?

-Harish

Bill Lear wrote:

>On Friday, October 3, 2003 at 16:33:58 (+0200) Christian Essl writes:
>  
>
>>...
>>Than I would give out the DOA directly as a service. Than as you also said 
>>(for your second question) I would implement a ConnectionPool service 
>>interface and a (or more) implementation(s) (one which just holds one 
>>connection - for your testing). Than I would change the DAO-implementation 
>>to take a ConnectionPool service as parameter and get the connection from 
>>there.
>>
>>interface ConnectionPool {
>> public Connection getConnection();
>> public void returnConnection(Connection connection);
>>}
>>    
>>
>
>Hmm, I'm starting to like this.
>
>  
>
>><module...>
>>
>><service-point id="DAO"
>>...
>></service>
>>
>><service-point id="ConnectionPool"
>>...
>></service>
>>    
>>
>
>Ok, I think I'm getting the point...
>
>  
>
>>Now you saved the factory and you have access to the single connection in 
>>your test-code. In running code you can still change to a real connection 
>>pool. With this suggestion you still have to change both the DAO service- 
>>definition and the ConnectionPool definition if you want to change the DAO 
>>implementation. However this can be cleaned up, see the Overriding-Services 
>>tutorial at the hivemind page.
>>
>>Finally: I think (like you) you should if you are going to use a 'real' 
>>connection-pool take the connection out of the commands. I would give the 
>>commands the connection as a parameter each time they are called. The 
>>caller would get it from the ConnectionPool call the command with it and 
>>return it straight to the pool.
>>    
>>
>
>This is something I've been considering, and I think I'm convinced that
>this is a better way to do things.
>
>Thanks for the feedback.
>
>
>Bill
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
>
>  
>

Re: [HiveMind] Question about DAO creation

Posted by Bill Lear <ra...@zopyra.com>.
On Friday, October 3, 2003 at 16:33:58 (+0200) Christian Essl writes:
>...
>Than I would give out the DOA directly as a service. Than as you also said 
>(for your second question) I would implement a ConnectionPool service 
>interface and a (or more) implementation(s) (one which just holds one 
>connection - for your testing). Than I would change the DAO-implementation 
>to take a ConnectionPool service as parameter and get the connection from 
>there.
>
>interface ConnectionPool {
>  public Connection getConnection();
>  public void returnConnection(Connection connection);
>}

Hmm, I'm starting to like this.

><module...>
>
><service-point id="DAO"
>...
></service>
>
><service-point id="ConnectionPool"
>...
></service>

Ok, I think I'm getting the point...

>Now you saved the factory and you have access to the single connection in 
>your test-code. In running code you can still change to a real connection 
>pool. With this suggestion you still have to change both the DAO service- 
>definition and the ConnectionPool definition if you want to change the DAO 
>implementation. However this can be cleaned up, see the Overriding-Services 
>tutorial at the hivemind page.
>
>Finally: I think (like you) you should if you are going to use a 'real' 
>connection-pool take the connection out of the commands. I would give the 
>commands the connection as a parameter each time they are called. The 
>caller would get it from the ConnectionPool call the command with it and 
>return it straight to the pool.

This is something I've been considering, and I think I'm convinced that
this is a better way to do things.

Thanks for the feedback.


Bill

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [HiveMind] Question about DAO creation

Posted by Christian Essl <ch...@yahoo.de>.
Your DAO is quite evolved, and I don't realy know Tapestry, but let me 
still try to say how I would do it:

First I would directly expose the Registry in the Global and the 
application gets the DAO directly from the Registry. The Registry should 
not be build up too often it's just too time-consuming (and you should call 
shut-down on the reigstry before you release it).

public Global{
  private Registry registry;
  public Global(){
   //build up the registry here
   //because I certainly need
   //and don't need synchronize later
  }

  public Registry getHiveMindRegistry(){
    return registry;
  }

  public void shutdownHiveMindRegistry() {
    registry.shutdown();
  }
}

Than I would give out the DOA directly as a service. Than as you also said 
(for your second question) I would implement a ConnectionPool service 
interface and a (or more) implementation(s) (one which just holds one 
connection - for your testing). Than I would change the DAO-implementation 
to take a ConnectionPool service as parameter and get the connection from 
there.

interface ConnectionPool {
  public Connection getConnection();
  public void returnConnection(Connection connection);
}

<module...>

<service-point id="DAO"
   interface="com.foobar.eci.dao.DAOFactory">
   <invoke-factory service-id="hivemind.BuilderFactory">
	<construct class="com.foobar.eci.dao.mysql.MySQLDAOFactory">
	<set-service id="MySqlConnectionPool" property".."/>
      </contruct>
   </invoke-factory>
</service>

<service-point id="ConnectionPool"
   interface="com.foobar.eci.dao.ConnectionPool">
   <invoke-factory service-id="hivemind.BuilderFactory">
	<construct class="com.foobar.eci.dao.mysql.MySQLSingelConnectionPool">
	<set ... the Connection properties/>
      (etc..)
      </construct>
   </invoke-factory>
</service>

Now you saved the factory and you have access to the single connection in 
your test-code. In running code you can still change to a real connection 
pool. With this suggestion you still have to change both the DAO service- 
definition and the ConnectionPool definition if you want to change the DAO 
implementation. However this can be cleaned up, see the Overriding-Services 
tutorial at the hivemind page.

Finally: I think (like you) you should if you are going to use a 'real' 
connection-pool take the connection out of the commands. I would give the 
commands the connection as a parameter each time they are called. The 
caller would get it from the ConnectionPool call the command with it and 
return it straight to the pool.



> <invoke-factory service-id="hivemind.BuilderFactory">
> <construct
> 	        class="com.foobar.eci.dao.mysql.MySQLDAOFactory">
> <set property="name" value="eci"/>
> <set property="protocol" value="mysql"/>
> <set property="driver"
> 		     value="org.gjt.mm.mysql.Driver"/>
> <set property="host" value="localhost"/>
> <set property="port" value="3906"/>
> <set property="user" value="bogon"/>
> <set property="password" value="foobar"/>
> </construct>
> </invoke-factory>
> </service-point>
> </module>
On Fri, 3 Oct 2003 06:51:56 -0500, Bill Lear <ra...@zopyra.com> wrote:

> I've been using hivemind to build a DAO factory.  I think I may be
> using this in a rather crude way that undoes some of the good hivemind
> has done, so I thought I'd ask for some advice.  I have a second question
> regarding JDBC connections.
>
> First, in Tapestry, I store my DAO object in the Global class, but
> I seem to have reverted to the singleton pattern instead of
> doing things the hivemind way:
>
> public class Global {
> private static DAO dao;
>
> private static Object daoMutex = new Object();
>
> public DAO getDAO() throws DAOException {
> synchronized (daoMutex) {
> if (dao == null) {
> dao = createDAO();
> }
> }
> return dao;
> }
>
> private DAO createDAO() throws DAOException {
> DAOFactory f = (DAOFactory) Services.getService(DAOFactory.class);
> return f.createDAO();
> }
> }
>
> Services is a wrapper around Hivemind that gets a service based on a
> class name:
>
> public class Services {
> public static Object getService(Class theClass) {
> ClassResolver resolver = new DefaultClassResolver();
> RegistryBuilder builder = new RegistryBuilder();
>
> builder.processModules(resolver);
>
> Registry registry = builder.constructRegistry(Locale.getDefault());
>
> return registry.getService(theClass.getName(), theClass);
> }
> }
>
> My hivemodule looks like this:
>
> <module id="com.foobar.eci.dao" version="1.0.0">
> <service-point id="DAOFactory"
> interface="com.foobar.eci.dao.DAOFactory">
> <invoke-factory service-id="hivemind.BuilderFactory">
> <construct
> 	        class="com.foobar.eci.dao.mysql.MySQLDAOFactory">
> <set property="name" value="eci"/>
> <set property="protocol" value="mysql"/>
> <set property="driver"
> 		     value="org.gjt.mm.mysql.Driver"/>
> <set property="host" value="localhost"/>
> <set property="port" value="3906"/>
> <set property="user" value="bogon"/>
> <set property="password" value="foobar"/>
> </construct>
> </invoke-factory>
> </service-point>
> </module>
>
> I'm not quite sure how to have hivemind construct both the Global
> object and DAO object, and set the DAO object in the Global object.
>
>
> Second question: I use a command pattern to separate the implementation 
> of
> different methods in the DAO class.  So, if I have a DAO that looks like
> this:
>
> public interface DAO {
> Employee getEmployee(Integer employeeID) throws DAOException;
>
> Employee[] getEmployees(String sortColumn) throws DAOException;
>
> void insertEmployee(Employee employee) throws DAOException;
> }
>
> I implement this with a class to expose this interface, and three
> classes to implement each of the commands.  Notice the MySQLDAO
> class stores the JDBC connection object and passes it to each
> of the command classes it constructs:
>
> public class MySQLDAO implements DAO {
> void init(Connection connection) throws DAOException {
> try {
> getEmployee = new GetEmployee(connection);
> getEmployees = new GetEmployees(connection);
> insertEmployee = new InsertEmployee(connection);
> } catch (SQLException sex) {
> LOG.error(sex.toString());
> throw new DAOException(sex.toString());
> }
> }
>
> private GetEmployee getEmployee;
>
> public Employee getEmployee(Integer employeeID) throws DAOException {
> return getEmployee.execute(employeeID);
> }
>
> private GetEmployees getEmployees;
>
> public Employee[] getEmployees(String sortColumn) throws DAOException {
> return getEmployees.execute(sortColumn);
> }
>
> private InsertEmployee insertEmployee;
>
> public void insertEmployee(Employee employee) throws DAOException {
> insertEmployee.execute(employee);
> }
> }
>
> The factory is what I have Hivemind creating:
>
> public class MySQLDAOFactory implements DAOFactory {
> private String name;
> private String protocol;
> private String driver;
> private String host;
> private String port;
> private String user;
> private String password;
>
> public DAO createDAO() throws DAOException {
> MySQLDAO dao = new MySQLDAO();
>
> try {
> String connURL = "jdbc:" + protocol + "://";
>
> if (host.length() == 0) {
> connURL += name;
> } else {
> connURL += host + ":" + port + "/" + name;
> }
>
> // This ensures no timeouts for MySQL after default idle period
> connURL += "?autoReconnect=true";
>
> Class.forName(driver);
> dao.init(DriverManager.getConnection(connURL, user, password));
> } catch (SQLException sex) {
> throw new DAOException(sex);
> } catch (ClassNotFoundException ex) {
> throw new DAOException(ex);
> }
>
> return dao;
> }
>
> // Get-Set methods for private variables elided ...
> }
>
> So, what I'm wondering is: I have embedded a JDBC connection object in
> the each of the three command objects.  This seems too direct and
> inflexible, but I don't know what other alternatives to use.  Also, I
> would like to be able to unit-test each of the three command classes,
> but I would prefer to be able to use hivemind to construct the JDBC
> connection for me, in which case, I might re-factor things in the
> MySQLDAO class itself to also take advantage of hivemind to get the
> connection object (but then, what about pooling?  Can hivemind create
> a JDBC connection?  Is this desirable?).
>
> Finally, when testing the DAO, I need to be able to clear the database
> before each test case method is run.  I would prefer to use the same
> connection that the DAO has, but exposing that in the DAO interface
> seems a bit lame (Connection getConnection()) and too concrete.
>
> In any case, if anyone has comments or suggestions to share on managing
> JDBC connections, I'd appreciate it.
>
>
> Bill
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [HiveMind] Question about DAO creation

Posted by Christian Essl <ch...@yahoo.de>.
The reason is that the connection-pool may to have to be informed when it 
can close its connections. You can do this yourself or let HiveMind do it 
for you. Just a few days ago Howard has commited code so that all service- 
implementations which implement org.hivemind.RegistryShutdownListener are 
informed when the registry ends. This information happens exactly when you 
call Registry.shutdown(). A connection-pool implementation (and other 
services) may relay now on this and therefore you should do it. (Note: the 
registry can not be used anymore after this).

On Fri, 3 Oct 2003 09:53:29 -0500, Bill Lear <ra...@zopyra.com> wrote:

> On Friday, October 3, 2003 at 16:45:42 (+0200) Christian Essl writes:
>> Sorry I wrote my answer send it and than just saw that Harish was faster 
>> (and better). Maybe the only thing you should keep from my anser that 
>> you should shutdown the registry (the pool may need it, because HiveMind 
>> now supports a shut-down event).
>
> No reason to apologize --- very helpful stuff, except I'm not sure
> I understand the need to shut down the registry.
>
> I've refactored a bit, now my Global is simpler:
>
> public class Global {
> private DAO dao;
>
> public Global() throws DAOException {
> Services services = new Services();
> DAOFactory factory =
> (DAOFactory) services.getService(DAOFactory.class);
> dao = factory.createDAO();
> }
>
> public DAO getDAO() {
> return dao;
> }
> }
>
> as is my Services class:
>
> public class Services {
> private Registry registry;
>
> public Services() {
> ClassResolver resolver = new DefaultClassResolver();
> RegistryBuilder builder = new RegistryBuilder();
>
> builder.processModules(resolver);
>
> Registry registry = builder.constructRegistry(Locale.getDefault());
> }
>
> public Object getService(Class theClass) {
> return registry.getService(theClass.getName(), theClass);
> }
> }
>
> Now I need to see about incorporating the other ideas about
> connections, shutting down the registry (again, is this really
> needed?)  etc.
>
>
> Bill
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [HiveMind] Question about DAO creation

Posted by Bill Lear <ra...@zopyra.com>.
On Friday, October 3, 2003 at 16:45:42 (+0200) Christian Essl writes:
>Sorry I wrote my answer send it and than just saw that Harish was faster 
>(and better). Maybe the only thing you should keep from my anser that you 
>should shutdown the registry (the pool may need it, because HiveMind now 
>supports a shut-down event).

No reason to apologize --- very helpful stuff, except I'm not sure
I understand the need to shut down the registry.

I've refactored a bit, now my Global is simpler:

public class Global {
    private DAO dao;

    public Global() throws DAOException {
        Services services = new Services();
        DAOFactory factory =
            (DAOFactory) services.getService(DAOFactory.class);
        dao = factory.createDAO();
    }

    public DAO getDAO() {
        return dao;
    }
}

as is my Services class:

public class Services {
    private Registry registry;

    public Services() {
        ClassResolver resolver = new DefaultClassResolver();
        RegistryBuilder builder = new RegistryBuilder();

        builder.processModules(resolver);

        Registry registry = builder.constructRegistry(Locale.getDefault());
    }

    public Object getService(Class theClass) {
        return registry.getService(theClass.getName(), theClass);
    }
}

Now I need to see about incorporating the other ideas about
connections, shutting down the registry (again, is this really
needed?)  etc.


Bill

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [HiveMind] Question about DAO creation

Posted by Christian Essl <ch...@yahoo.de>.
Sorry I wrote my answer send it and than just saw that Harish was faster 
(and better). Maybe the only thing you should keep from my anser that you 
should shutdown the registry (the pool may need it, because HiveMind now 
supports a shut-down event).

On Fri, 03 Oct 2003 10:12:37 -0400, Harish Krishnaswamy 
<hk...@comcast.net> wrote:

> Here's what I have done in my project, I am using iBatisDB and I love it, 
> I suppose you can do the same with JDBC too.
>
> I have a super DataAccessService...
>
> public class DataAccessServiceImpl implements DataAccessService, 
> Initializable
> {
> // This will be a configuration provided in the module descriptor
> // In JDBC, this will probably be the JNDI path to the DataSource
> public void setResourcePath(String path)
> {
> _resourcePath = path;
> }
>
> // This is used to build the SqlMap, kind of registry for all sql 
> statements.
> // In a plain JDBC env, this is probably where I would get the DataSource 
> (from JNDI typically) and store it locally.
> public void initializeService(Object service)
> {
> try
> {
> Reader reader = Resources.getResourceAsReader(_resourcePath);
> _sqlMap = XmlSqlMapBuilder.buildSqlMap(reader);
> reader.close();
> }
> catch (Exception ex)
> {
> throw new ApplicationRuntimeException("Error Initializing DAS :" + ex);
> }
> }
>
> // Generic statement executions
> public List getList(String statementName, Object parameterObject) throws 
> DaoException
> {
> // executeQuery()
> }
>
> public Object getObject(String statementName, Object parameterObject) 
> throws DaoException
> {
> // executeQuery()
> }
>
> public int update(String statementName, Object parameterObject) throws 
> DaoException
> {
> // executeUpdate()
> }
> }
>
> And I have other DataAccess services compose the super DataAccessService 
> which will be provided by HiveMind as specified in the module descriptor.
>
> For example...
>
> public class ClientDASImpl implements ClientDAS
> {
> private DataAccessService _das;
> public void setDataAccessService(DataAccessService das)
> {
> _das = das;
> }
> public List getClients()
> {
> List list = null;
> try
> {
> list = _das.getList("getClients", new Client());
> }
> catch (DaoException e)
> {
> throw new ApplicationRuntimeException(e);
> }
> return list;
> }
> }
>
> And what I store in the Global is just the registry. That's one thing I 
> noticed in your code, you seem to be building the registry eveytime a 
> service is requested. Here my Global...
>
> public class Global
> {
> private Registry _registry;
>
> public Global()
> {
> ClassResolver resolver = new DefaultClassResolver();
> RegistryBuilder builder = new RegistryBuilder();
>
> builder.processModules(resolver);
>
> _registry = builder.constructRegistry(Locale.getDefault());
> }
>
> public LookupService getLookupService()
> {
> return (LookupService) _registry.getService(ServiceTokens.LOOKUP, 
> LookupService.class);
> }
> ...
> }
>
> I use DBCP for DB connection pooling, that way you externalize all the 
> connection stuff out of the service.
>
> I hope this will be helpful. If you need more info, I will be glad to 
> provide what ever I can.
>
> -Harish
>
>
> Bill Lear wrote:
>
>> I've been using hivemind to build a DAO factory.  I think I may be
>> using this in a rather crude way that undoes some of the good hivemind
>> has done, so I thought I'd ask for some advice.  I have a second 
>> question
>> regarding JDBC connections.
>>
>> First, in Tapestry, I store my DAO object in the Global class, but
>> I seem to have reverted to the singleton pattern instead of
>> doing things the hivemind way:
>>
>> public class Global {
>> private static DAO dao;
>>
>> private static Object daoMutex = new Object();
>>
>> public DAO getDAO() throws DAOException {
>> synchronized (daoMutex) {
>> if (dao == null) {
>> dao = createDAO();
>> }
>> }
>> return dao;
>> }
>>
>> private DAO createDAO() throws DAOException {
>> DAOFactory f = (DAOFactory) Services.getService(DAOFactory.class);
>> return f.createDAO();
>> }
>> }
>>
>> Services is a wrapper around Hivemind that gets a service based on a
>> class name:
>>
>> public class Services {
>> public static Object getService(Class theClass) {
>> ClassResolver resolver = new DefaultClassResolver();
>> RegistryBuilder builder = new RegistryBuilder();
>>
>> builder.processModules(resolver);
>>
>> Registry registry = builder.constructRegistry(Locale.getDefault());
>>
>> return registry.getService(theClass.getName(), theClass);
>> }
>> }
>>
>> My hivemodule looks like this:
>>
>> <module id="com.foobar.eci.dao" version="1.0.0">
>> <service-point id="DAOFactory"
>> interface="com.foobar.eci.dao.DAOFactory">
>> <invoke-factory service-id="hivemind.BuilderFactory">
>> <construct
>> 	        class="com.foobar.eci.dao.mysql.MySQLDAOFactory">
>> <set property="name" value="eci"/>
>> <set property="protocol" value="mysql"/>
>> <set property="driver"
>> 		     value="org.gjt.mm.mysql.Driver"/>
>> <set property="host" value="localhost"/>
>> <set property="port" value="3906"/>
>> <set property="user" value="bogon"/>
>> <set property="password" value="foobar"/>
>> </construct>
>> </invoke-factory>
>> </service-point>
>> </module>
>>
>> I'm not quite sure how to have hivemind construct both the Global
>> object and DAO object, and set the DAO object in the Global object.
>>
>>
>> Second question: I use a command pattern to separate the implementation 
>> of
>> different methods in the DAO class.  So, if I have a DAO that looks like
>> this:
>>
>> public interface DAO {
>> Employee getEmployee(Integer employeeID) throws DAOException;
>>
>> Employee[] getEmployees(String sortColumn) throws DAOException;
>>
>> void insertEmployee(Employee employee) throws DAOException;
>> }
>>
>> I implement this with a class to expose this interface, and three
>> classes to implement each of the commands.  Notice the MySQLDAO
>> class stores the JDBC connection object and passes it to each
>> of the command classes it constructs:
>>
>> public class MySQLDAO implements DAO {
>> void init(Connection connection) throws DAOException {
>> try {
>> getEmployee = new GetEmployee(connection);
>> getEmployees = new GetEmployees(connection);
>> insertEmployee = new InsertEmployee(connection);
>> } catch (SQLException sex) {
>> LOG.error(sex.toString());
>> throw new DAOException(sex.toString());
>> }
>> }
>>
>> private GetEmployee getEmployee;
>>
>> public Employee getEmployee(Integer employeeID) throws DAOException {
>> return getEmployee.execute(employeeID);
>> }
>>
>> private GetEmployees getEmployees;
>>
>> public Employee[] getEmployees(String sortColumn) throws DAOException {
>> return getEmployees.execute(sortColumn);
>> }
>>
>> private InsertEmployee insertEmployee;
>>
>> public void insertEmployee(Employee employee) throws DAOException {
>> insertEmployee.execute(employee);
>> }
>> }
>>
>> The factory is what I have Hivemind creating:
>>
>> public class MySQLDAOFactory implements DAOFactory {
>> private String name;
>> private String protocol;
>> private String driver;
>> private String host;
>> private String port;
>> private String user;
>> private String password;
>>
>> public DAO createDAO() throws DAOException {
>> MySQLDAO dao = new MySQLDAO();
>>
>> try {
>> String connURL = "jdbc:" + protocol + "://";
>>
>> if (host.length() == 0) {
>> connURL += name;
>> } else {
>> connURL += host + ":" + port + "/" + name;
>> }
>>
>> // This ensures no timeouts for MySQL after default idle period
>> connURL += "?autoReconnect=true";
>>
>> Class.forName(driver);
>> dao.init(DriverManager.getConnection(connURL, user, password));
>> } catch (SQLException sex) {
>> throw new DAOException(sex);
>> } catch (ClassNotFoundException ex) {
>> throw new DAOException(ex);
>> }
>>
>> return dao;
>> }
>>
>> // Get-Set methods for private variables elided ...
>> }
>>
>> So, what I'm wondering is: I have embedded a JDBC connection object in
>> the each of the three command objects.  This seems too direct and
>> inflexible, but I don't know what other alternatives to use.  Also, I
>> would like to be able to unit-test each of the three command classes,
>> but I would prefer to be able to use hivemind to construct the JDBC
>> connection for me, in which case, I might re-factor things in the
>> MySQLDAO class itself to also take advantage of hivemind to get the
>> connection object (but then, what about pooling?  Can hivemind create
>> a JDBC connection?  Is this desirable?).
>>
>> Finally, when testing the DAO, I need to be able to clear the database
>> before each test case method is run.  I would prefer to use the same
>> connection that the DAO has, but exposing that in the DAO interface
>> seems a bit lame (Connection getConnection()) and too concrete.
>>
>> In any case, if anyone has comments or suggestions to share on managing
>> JDBC connections, I'd appreciate it.
>>
>>
>> Bill
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>>
>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Re: [HiveMind] Question about DAO creation

Posted by Harish Krishnaswamy <hk...@comcast.net>.
Here's what I have done in my project, I am using iBatisDB and I love 
it, I suppose you can do the same with JDBC too.

I have a super DataAccessService...

public class DataAccessServiceImpl implements DataAccessService, 
Initializable
{
    // This will be a configuration provided in the module descriptor
    // In JDBC, this will probably be the JNDI path to the DataSource
    public void setResourcePath(String path)
    {
        _resourcePath = path;
    }

    // This is used to build the SqlMap, kind of registry for all sql 
statements.
    // In a plain JDBC env, this is probably where I would get the 
DataSource (from JNDI typically) and store it locally.
    public void initializeService(Object service)
    {
        try
        {
            Reader reader = Resources.getResourceAsReader(_resourcePath);
            _sqlMap = XmlSqlMapBuilder.buildSqlMap(reader);
            reader.close();
        }
        catch (Exception ex)
        {
            throw new ApplicationRuntimeException("Error Initializing 
DAS :" + ex);
        }
    }

    // Generic statement executions
    public List getList(String statementName, Object parameterObject) 
throws DaoException
    {
       // executeQuery()
    }

    public Object getObject(String statementName, Object 
parameterObject) throws DaoException
    {
       // executeQuery()
    }

    public int update(String statementName, Object parameterObject) 
throws DaoException
    {
       // executeUpdate()
    }
}

And I have other DataAccess services compose the super DataAccessService 
which will be provided by HiveMind as specified in the module descriptor.

For example...

public class ClientDASImpl implements ClientDAS
{
    private DataAccessService _das;
   
    public void setDataAccessService(DataAccessService das)
    {
        _das = das;
    }
   
    public List getClients()
    {
        List list = null;
       
        try
        {
            list = _das.getList("getClients", new Client());
        }
        catch (DaoException e)
        {
            throw new ApplicationRuntimeException(e);
        }
       
        return list;
    }
}

And what I store in the Global is just the registry. That's one thing I 
noticed in your code, you seem to be building the registry eveytime a 
service is requested. Here my Global...

public class Global
{
    private Registry _registry;

    public Global()
    {
        ClassResolver resolver = new DefaultClassResolver();
        RegistryBuilder builder = new RegistryBuilder();

        builder.processModules(resolver);

        _registry = builder.constructRegistry(Locale.getDefault());
    }

    public LookupService getLookupService()
    {
        return (LookupService) 
_registry.getService(ServiceTokens.LOOKUP, LookupService.class);
    }
    ...
}

I use DBCP for DB connection pooling, that way you externalize all the 
connection stuff out of the service.

I hope this will be helpful. If you need more info, I will be glad to 
provide what ever I can.

-Harish


Bill Lear wrote:

>I've been using hivemind to build a DAO factory.  I think I may be
>using this in a rather crude way that undoes some of the good hivemind
>has done, so I thought I'd ask for some advice.  I have a second question
>regarding JDBC connections.
>
>First, in Tapestry, I store my DAO object in the Global class, but
>I seem to have reverted to the singleton pattern instead of
>doing things the hivemind way:
>
>public class Global {
>    private static DAO dao;
>
>    private static Object daoMutex = new Object();
>
>    public DAO getDAO() throws DAOException {
>        synchronized (daoMutex) {
>            if (dao == null) {
>                dao = createDAO();
>            }
>        }
>        return dao;
>    }
>
>    private DAO createDAO() throws DAOException {
>        DAOFactory f = (DAOFactory) Services.getService(DAOFactory.class);
>        return f.createDAO();
>    }
>}
>
>Services is a wrapper around Hivemind that gets a service based on a
>class name:
>
>public class Services {
>    public static Object getService(Class theClass) {
>        ClassResolver resolver = new DefaultClassResolver();
>        RegistryBuilder builder = new RegistryBuilder();
>
>        builder.processModules(resolver);
>
>        Registry registry = builder.constructRegistry(Locale.getDefault());
>
>        return registry.getService(theClass.getName(), theClass);
>    }
>}
>
>My hivemodule looks like this:
>
><module id="com.foobar.eci.dao" version="1.0.0">
>    <service-point id="DAOFactory"
>                   interface="com.foobar.eci.dao.DAOFactory">
>        <invoke-factory service-id="hivemind.BuilderFactory">
>            <construct
>	        class="com.foobar.eci.dao.mysql.MySQLDAOFactory">
>                <set property="name" value="eci"/>
>                <set property="protocol" value="mysql"/>
>                <set property="driver"
>		     value="org.gjt.mm.mysql.Driver"/>
>                <set property="host" value="localhost"/>
>                <set property="port" value="3906"/>
>                <set property="user" value="bogon"/>
>                <set property="password" value="foobar"/>
>            </construct>
>        </invoke-factory>
>    </service-point>
></module>
>
>I'm not quite sure how to have hivemind construct both the Global
>object and DAO object, and set the DAO object in the Global object.
>
>
>Second question: I use a command pattern to separate the implementation of
>different methods in the DAO class.  So, if I have a DAO that looks like
>this:
>
>public interface DAO {
>    Employee getEmployee(Integer employeeID) throws DAOException;
>
>    Employee[] getEmployees(String sortColumn) throws DAOException;
>
>    void insertEmployee(Employee employee) throws DAOException;
>}
>
>I implement this with a class to expose this interface, and three
>classes to implement each of the commands.  Notice the MySQLDAO
>class stores the JDBC connection object and passes it to each
>of the command classes it constructs:
>
>public class MySQLDAO implements DAO {
>    void init(Connection connection) throws DAOException {
>        try {
>            getEmployee = new GetEmployee(connection);
>            getEmployees = new GetEmployees(connection);
>            insertEmployee = new InsertEmployee(connection);
>        } catch (SQLException sex) {
>            LOG.error(sex.toString());
>            throw new DAOException(sex.toString());
>        }
>    }
>
>    private GetEmployee getEmployee;
>
>    public Employee getEmployee(Integer employeeID) throws DAOException {
>        return getEmployee.execute(employeeID);
>    }
>
>    private GetEmployees getEmployees;
>
>    public Employee[] getEmployees(String sortColumn) throws DAOException {
>        return getEmployees.execute(sortColumn);
>    }
>
>    private InsertEmployee insertEmployee;
>
>    public void insertEmployee(Employee employee) throws DAOException {
>        insertEmployee.execute(employee);
>    }
>}
>
>The factory is what I have Hivemind creating:
>
>public class MySQLDAOFactory implements DAOFactory {
>    private String name;
>    private String protocol;
>    private String driver;
>    private String host;
>    private String port;
>    private String user;
>    private String password;
>
>    public DAO createDAO() throws DAOException {
>        MySQLDAO dao = new MySQLDAO();
>
>        try {
>            String connURL = "jdbc:" + protocol + "://";
>
>            if (host.length() == 0) {
>                connURL += name;
>            } else {
>                connURL += host + ":" + port + "/" + name;
>            }
>
>            // This ensures no timeouts for MySQL after default idle period
>            connURL += "?autoReconnect=true";
>
>            Class.forName(driver);
>            dao.init(DriverManager.getConnection(connURL, user, password));
>        } catch (SQLException sex) {
>            throw new DAOException(sex);
>        } catch (ClassNotFoundException ex) {
>            throw new DAOException(ex);
>        }
>
>        return dao;
>    }
>
>    // Get-Set methods for private variables elided ...
>}
>
>So, what I'm wondering is: I have embedded a JDBC connection object in
>the each of the three command objects.  This seems too direct and
>inflexible, but I don't know what other alternatives to use.  Also, I
>would like to be able to unit-test each of the three command classes,
>but I would prefer to be able to use hivemind to construct the JDBC
>connection for me, in which case, I might re-factor things in the
>MySQLDAO class itself to also take advantage of hivemind to get the
>connection object (but then, what about pooling?  Can hivemind create
>a JDBC connection?  Is this desirable?).
>
>Finally, when testing the DAO, I need to be able to clear the database
>before each test case method is run.  I would prefer to use the same
>connection that the DAO has, but exposing that in the DAO interface
>seems a bit lame (Connection getConnection()) and too concrete.
>
>In any case, if anyone has comments or suggestions to share on managing
>JDBC connections, I'd appreciate it.
>
>
>Bill
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
>
>  
>


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org