You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user-java@ibatis.apache.org by "Albert L. Sapp" <as...@uiuc.edu> on 2006/02/10 17:26:49 UTC

Combined DAO manager with a SqlMap client. Wrong?

Ok, we think we have found why our application transaction handling is 
not working right, but want to verify it.

We downloaded and setup JPetStore to run against our Oracle database.  
No changes where made to the configuration of the database.  We modified 
the order placing function to force it to violate a primary key 
constraint on one (create order) of the multiple sql commands it does 
within the transaction.  This caused all the commands to rollback as we 
would expect.  No update of the quantity on hand of the item occured.

In our application we define a DaoManager, but never reference the 
SqlMapDaoTemplate.  Instead, in our persistance layer, we define using 
the SqlMapClientBuilder a SqlMapClient.  All operations use this 
SqlMapClient (sqlmapclient.queryForList...).  Calls to start a 
transaction execute daomgr.startTransaction.  Extra layers of 
inheritance where implemented in the application by the then project 
head.  Don't ask me why.  Anyway, when we do a transaction all the sql 
commands up to the command that fails commit, when they should all 
rollback.  Same database with same configuration on it.

It appears that JPetStore uses the DaoManager to execute the 
queryForList and such with no actual build of a SqlMapClient.  Am I 
correct?  Is that why our transactions don't rollback correctly?  
Otherwise, I am at a loss for why JPetStore rolls back correctly and our 
application does not.  We are having to use stored procedures right now 
to get the proper rollback, but one of the requirements is that the 
application not be database dependant.  In other words, no having to 
convert stored procedures on one database to another.

Any help or comments would be greatly appreciated.

Al


Re: Combined DAO manager with a SqlMap client. Wrong?

Posted by "Albert L. Sapp" <as...@uiuc.edu>.
Brandon Goodin wrote:

>What transaction manager do you have configured in your dao.xml? If
>you have a SQLMAP it does the job of initializing your SqlMapClient.
>You do not need to use SqlMapClientBuilder.
>
>Further, if you created a SqlMapClient apart from the DaoManager then
>transactions would not work. This is because the DaoManager
>initializes a SqlMapClient and ultimately calls the startTransaction
>on the SqlMapClient it created during it's initialization.
>
>If you aren't using the SqlMapClient created by the DaoManager then
>you are not using the SqlMapClient that the DaoManager is starting a
>transaction on. You literally have 2 instances of SqlMapClient. The
>SqlMapClient that you manually created is starting and committing
>transactions on each of the calls you make to the database.
>
>If you called the daoManager.getTransaction(Dao dao).getSqlMap(), then
>you would get back the sqlMapClient that you want. It would also be
>within the transaction that was started with the DaoManager. You could
>then use it to execute your sql (queryFor..., insert, update, etc...)
>within the same transaction as other calls that land in between your
>startTransaction and commitTransaction/endTransaction.
>
>But, this too would be a waste of good effort because the
>SqlMapDaoTemplate already does this and saves you the work of doing
>it. I would have to say that you are doing the correct thing by
>modeling your application after the example set forth by JPetStore.
>
>Brandon
>
>On 2/11/06, Albert L. Sapp <as...@uiuc.edu> wrote:
>  
>
>>Brandon Goodin wrote:
>>
>>    
>>
>>>"In JPetStore, if I remember right, commands are executed through a
>>>daomanager.update() versus a sqlmap.update().  Am I correct? "
>>>
>>>This is not correct. The DaoManager is used to retrieve an instance of
>>>the Dao. One of the fuctions of the DaoManager is to be a Dao Factory.
>>>In the dao.xml DAO interfaces are mapped to DAO implementations. The
>>>DaoManager passes back the implementation of the DAO interface.
>>>
>>>Another function of the DaoManager is transaciton management. When
>>>using the DaoManager in conjunction with SqlMaps it retrieves an
>>>intance of the Dao and also passes itself into the Dao implemenations
>>>constructor. That is why classes that use the DaoManager in
>>>conjunction with SqlMaps extend the SqlMapDaoTemplate.
>>>
>>>In a standard web architecture you may see something like:
>>>
>>>Application --> Service --> Data Access
>>>
>>>Application is where Struts/JSP or whatever lives.
>>>Service is where the Dao Manager exists.
>>>The Data Access layer is where the SqlMaps exists.
>>>
>>>The service layer is where you would make more course grained calls
>>>that are made up of fine grained calls to the Data Access layer. Since
>>>the service layer is responsible for grouping together calls to the
>>>Data Access layer (or DAO classes) you would want to manage
>>>transactions on the service layer. If you have mulitple calls to
>>>multiple DAO classes in a method on your service class you would want
>>>to wrap them in a transaction in the service class method. You would
>>>do this with daoManager.startTransaction() etc...
>>>
>>>In your Dao that extends SqlMapDaoTemplate you would simple calls the
>>>queryFor.., insert,update, delete methods. These methods are calling
>>>the SqlMapClient/SqlMapClientImpl as you normally would if you never
>>>used the DaoManager. The only difference is that the calls are being
>>>passed through the SqlMapDaoTemplate class and the transactions are
>>>being managed by the DaoManager.
>>>
>>>Hope that helps,
>>>Brandon
>>>
>>>On 2/10/06, Albert L. Sapp <as...@uiuc.edu> wrote:
>>>
>>>
>>>      
>>>
>>>>Brandon Goodin wrote:
>>>>
>>>>
>>>>
>>>>        
>>>>
>>>>>Actually JPetstore does use the SqlMapDaoTemplate. All of the DAO
>>>>>class extend BaseSqlMapDao which extends SqlMapDaoTemplate.
>>>>>
>>>>>In your case I am not completely clear on what you are doing. Perhaps
>>>>>you can provide code from your application that shows us how you are
>>>>>using iBatis. Code coupled with you explanation can go a long way.
>>>>>
>>>>>Brandon
>>>>>
>>>>>public class BaseSqlMapDao extends SqlMapDaoTemplate {
>>>>>
>>>>>On 2/10/06, Albert L. Sapp <as...@uiuc.edu> wrote:
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>          
>>>>>
>>>>>>Ok, we think we have found why our application transaction handling is
>>>>>>not working right, but want to verify it.
>>>>>>
>>>>>>We downloaded and setup JPetStore to run against our Oracle database.
>>>>>>No changes where made to the configuration of the database.  We modified
>>>>>>the order placing function to force it to violate a primary key
>>>>>>constraint on one (create order) of the multiple sql commands it does
>>>>>>within the transaction.  This caused all the commands to rollback as we
>>>>>>would expect.  No update of the quantity on hand of the item occured.
>>>>>>
>>>>>>In our application we define a DaoManager, but never reference the
>>>>>>SqlMapDaoTemplate.  Instead, in our persistance layer, we define using
>>>>>>the SqlMapClientBuilder a SqlMapClient.  All operations use this
>>>>>>SqlMapClient (sqlmapclient.queryForList...).  Calls to start a
>>>>>>transaction execute daomgr.startTransaction.  Extra layers of
>>>>>>inheritance where implemented in the application by the then project
>>>>>>head.  Don't ask me why.  Anyway, when we do a transaction all the sql
>>>>>>commands up to the command that fails commit, when they should all
>>>>>>rollback.  Same database with same configuration on it.
>>>>>>
>>>>>>It appears that JPetStore uses the DaoManager to execute the
>>>>>>queryForList and such with no actual build of a SqlMapClient.  Am I
>>>>>>correct?  Is that why our transactions don't rollback correctly?
>>>>>>Otherwise, I am at a loss for why JPetStore rolls back correctly and our
>>>>>>application does not.  We are having to use stored procedures right now
>>>>>>to get the proper rollback, but one of the requirements is that the
>>>>>>application not be database dependant.  In other words, no having to
>>>>>>convert stored procedures on one database to another.
>>>>>>
>>>>>>Any help or comments would be greatly appreciated.
>>>>>>
>>>>>>Al
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>            
>>>>>>
>>>>>
>>>>>          
>>>>>
>>>>Brandon,
>>>>
>>>>I will try this again and leave out as much of the exception handling as
>>>>I can.  I will try to trace through what I think is happening though I
>>>>have never fully understood the explaination I was given.
>>>>
>>>>1.  Say we want to create a inventory item.  We have collected all the
>>>>information in our web page and created a transfer object bean in our
>>>>action.  The action calls the appropriate manager.  In this case, it
>>>>calls the StoreroomManager, which is implemented in the
>>>>StoreroomManagerImpl and extends the BaseManager.
>>>>
>>>>2.  We execute "startTransaction();", which executes
>>>>"daoManager.startTransaction();" in the BaseManager.  BaseManager is
>>>>where the DaoManager is defined and configured.
>>>>
>>>>3.  Then, we execute "inventoryItemDAO.create(newInventoryItem);".
>>>>inventoryItemDAO was defined "inventoryItemDAO =
>>>>(InventoryItemDAO)getDao(InventoryItemDAO.class);" using the getDao
>>>>defined in BaseManager.
>>>>
>>>>4.  We go to SqlMapInventoryItemDAO which extends BaseDAO.
>>>>
>>>>5.  The BaseDAO executes these commands:
>>>>
>>>>   a,  "reader = Resources.getResourceAsReader(sqlMapConf);"
>>>>   b.  "sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);"
>>>>   c.  create() contains "executeUpdate(getEntityName() + "Insert",to""
>>>>which translates as "executeUpdate("InventoryItemInsert", inventoryItem)"
>>>>   d.  executeUpdate contains "return
>>>>sqlMap.update(InventoryItemInsert, inventoryItem);"
>>>>
>>>>6.  This executes the statement in the inventoryItem.xml file called
>>>>"InventoryItemInsert".
>>>>
>>>>7.  If no exceptions are thrown, we execute "commitTransaction();",
>>>>which executes "daoManager.commitTransaction();" in the BaseManager.
>>>>
>>>>I can send you the files themselves if you need to see them.  For single
>>>>sql commands in a transaction, it either commits or rollback as we would
>>>>expect.  With something like:
>>>>
>>>>startTransaction();
>>>>invoiceDAO.createInvoice(new Invoice);
>>>>for (int i = 0; i < invoiceItem.size(); i++)
>>>>{
>>>>   invoiceItem = (InvoiceItem) invoiceItems.get(i);
>>>>   invoiceItemDAO.createInvoiceItem(invoiceItem);
>>>>}
>>>>inventoryItem.updateInventoryItem(inventoryItem);
>>>>for (int z = 0; z < transactions.size(); z++)
>>>>{
>>>>   transaction = (Transaction) transactions.get(z);
>>>>   transactionDAO.createTransaction(transaction);
>>>>}
>>>>stopTransaction();
>>>>
>>>>Everything is commited prior to an exception being encountered with only
>>>>the current sql command, that caused the exception, being rolled back.
>>>>Since this is contained in try blocks to trap exceptions, we always call
>>>>endTransaction().
>>>>
>>>>In JPetStore, if I remember right, commands are executed through a
>>>>daomanager.update() versus a sqlmap.update().  Am I correct?  Am I miss
>>>>reading JPetStore code execution?  By executing the SqlMapClientBuilder
>>>>instead of letting the daomanager use the SqlMapDaoTemplate taking
>>>>control away from the daomanager transaction control?
>>>>
>>>>If you need the files, let me know.  In the meantime, I have begun
>>>>rewriting the application in the pattern that JPetstore uses, since I
>>>>know that it does the rollback correctly.
>>>>
>>>>Thanks,
>>>>
>>>>Al
>>>>
>>>>
>>>>
>>>>
>>>>        
>>>>
>>>
>>>      
>>>
>>Brandon,
>>
>>I think I am close to understanding this now.  What if the
>>SqlMapDaoTemplate is never reference within the application and never
>>extended?  We import these com.ibatis.dao.client.DaoManagerBuilder ,
>>com.ibatis.dao.client.Dao, com.ibatis.sqlmap.client.SqlMapClient and
>>com.ibatis.sqlmap.client.SqlMapClientBuilder.  We extend
>>com.ibatis.dao.client.Dao in our base interfaceDao and then implement
>>that in our baseDao, which all other Dao interfaces/implementations
>>extend.  Is this the same as extending the SqlMapDaoTemplate or have we
>>broken the DaoManager control by NOT extending, implementing and using
>>the SqlMapDaoTemplate?
>>
>>Sorry about taking so much time, but I have never worked with a
>>programming language other than Cobol.  Also, never worked with anything
>>beyond key-indexed files.  This project has been more a "jump in the
>>deep-end" experience to me.
>>
>>Thanks for trying to explain all this to me,
>>
>>Al
>>
>>
>>    
>>
>
>  
>
BINGO!!!!!  Thanks, Brandon.  I beleive that is exactly what we are 
doing, because that is the behavior we are seeing.  No where do I see us 
working within the DaoManager to get our SqlMapClient.  I am in the 
process of converting a small application that is similar to our large 
application, but modeling it after the JPetStore example.  If it works 
as I think it will, we can apply the same techniques to the main 
application.  I am going to copy my co-developer on this and he may be 
able to find where in our current application structure to make the 
changes needed.  In the meantime, I can proceed with what I am doing.

If this all works, I will let you know.  I really appreciate the time 
you spent on this.

Al


Re: Combined DAO manager with a SqlMap client. Wrong?

Posted by Brandon Goodin <br...@gmail.com>.
What transaction manager do you have configured in your dao.xml? If
you have a SQLMAP it does the job of initializing your SqlMapClient.
You do not need to use SqlMapClientBuilder.

Further, if you created a SqlMapClient apart from the DaoManager then
transactions would not work. This is because the DaoManager
initializes a SqlMapClient and ultimately calls the startTransaction
on the SqlMapClient it created during it's initialization.

If you aren't using the SqlMapClient created by the DaoManager then
you are not using the SqlMapClient that the DaoManager is starting a
transaction on. You literally have 2 instances of SqlMapClient. The
SqlMapClient that you manually created is starting and committing
transactions on each of the calls you make to the database.

If you called the daoManager.getTransaction(Dao dao).getSqlMap(), then
you would get back the sqlMapClient that you want. It would also be
within the transaction that was started with the DaoManager. You could
then use it to execute your sql (queryFor..., insert, update, etc...)
within the same transaction as other calls that land in between your
startTransaction and commitTransaction/endTransaction.

But, this too would be a waste of good effort because the
SqlMapDaoTemplate already does this and saves you the work of doing
it. I would have to say that you are doing the correct thing by
modeling your application after the example set forth by JPetStore.

Brandon

On 2/11/06, Albert L. Sapp <as...@uiuc.edu> wrote:
> Brandon Goodin wrote:
>
> >"In JPetStore, if I remember right, commands are executed through a
> >daomanager.update() versus a sqlmap.update().  Am I correct? "
> >
> >This is not correct. The DaoManager is used to retrieve an instance of
> >the Dao. One of the fuctions of the DaoManager is to be a Dao Factory.
> >In the dao.xml DAO interfaces are mapped to DAO implementations. The
> >DaoManager passes back the implementation of the DAO interface.
> >
> >Another function of the DaoManager is transaciton management. When
> >using the DaoManager in conjunction with SqlMaps it retrieves an
> >intance of the Dao and also passes itself into the Dao implemenations
> >constructor. That is why classes that use the DaoManager in
> >conjunction with SqlMaps extend the SqlMapDaoTemplate.
> >
> >In a standard web architecture you may see something like:
> >
> >Application --> Service --> Data Access
> >
> >Application is where Struts/JSP or whatever lives.
> >Service is where the Dao Manager exists.
> >The Data Access layer is where the SqlMaps exists.
> >
> >The service layer is where you would make more course grained calls
> >that are made up of fine grained calls to the Data Access layer. Since
> >the service layer is responsible for grouping together calls to the
> >Data Access layer (or DAO classes) you would want to manage
> >transactions on the service layer. If you have mulitple calls to
> >multiple DAO classes in a method on your service class you would want
> >to wrap them in a transaction in the service class method. You would
> >do this with daoManager.startTransaction() etc...
> >
> >In your Dao that extends SqlMapDaoTemplate you would simple calls the
> >queryFor.., insert,update, delete methods. These methods are calling
> >the SqlMapClient/SqlMapClientImpl as you normally would if you never
> >used the DaoManager. The only difference is that the calls are being
> >passed through the SqlMapDaoTemplate class and the transactions are
> >being managed by the DaoManager.
> >
> >Hope that helps,
> >Brandon
> >
> >On 2/10/06, Albert L. Sapp <as...@uiuc.edu> wrote:
> >
> >
> >>Brandon Goodin wrote:
> >>
> >>
> >>
> >>>Actually JPetstore does use the SqlMapDaoTemplate. All of the DAO
> >>>class extend BaseSqlMapDao which extends SqlMapDaoTemplate.
> >>>
> >>>In your case I am not completely clear on what you are doing. Perhaps
> >>>you can provide code from your application that shows us how you are
> >>>using iBatis. Code coupled with you explanation can go a long way.
> >>>
> >>>Brandon
> >>>
> >>>public class BaseSqlMapDao extends SqlMapDaoTemplate {
> >>>
> >>>On 2/10/06, Albert L. Sapp <as...@uiuc.edu> wrote:
> >>>
> >>>
> >>>
> >>>
> >>>>Ok, we think we have found why our application transaction handling is
> >>>>not working right, but want to verify it.
> >>>>
> >>>>We downloaded and setup JPetStore to run against our Oracle database.
> >>>>No changes where made to the configuration of the database.  We modified
> >>>>the order placing function to force it to violate a primary key
> >>>>constraint on one (create order) of the multiple sql commands it does
> >>>>within the transaction.  This caused all the commands to rollback as we
> >>>>would expect.  No update of the quantity on hand of the item occured.
> >>>>
> >>>>In our application we define a DaoManager, but never reference the
> >>>>SqlMapDaoTemplate.  Instead, in our persistance layer, we define using
> >>>>the SqlMapClientBuilder a SqlMapClient.  All operations use this
> >>>>SqlMapClient (sqlmapclient.queryForList...).  Calls to start a
> >>>>transaction execute daomgr.startTransaction.  Extra layers of
> >>>>inheritance where implemented in the application by the then project
> >>>>head.  Don't ask me why.  Anyway, when we do a transaction all the sql
> >>>>commands up to the command that fails commit, when they should all
> >>>>rollback.  Same database with same configuration on it.
> >>>>
> >>>>It appears that JPetStore uses the DaoManager to execute the
> >>>>queryForList and such with no actual build of a SqlMapClient.  Am I
> >>>>correct?  Is that why our transactions don't rollback correctly?
> >>>>Otherwise, I am at a loss for why JPetStore rolls back correctly and our
> >>>>application does not.  We are having to use stored procedures right now
> >>>>to get the proper rollback, but one of the requirements is that the
> >>>>application not be database dependant.  In other words, no having to
> >>>>convert stored procedures on one database to another.
> >>>>
> >>>>Any help or comments would be greatly appreciated.
> >>>>
> >>>>Al
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>
> >>>
> >>>
> >>Brandon,
> >>
> >>I will try this again and leave out as much of the exception handling as
> >>I can.  I will try to trace through what I think is happening though I
> >>have never fully understood the explaination I was given.
> >>
> >>1.  Say we want to create a inventory item.  We have collected all the
> >>information in our web page and created a transfer object bean in our
> >>action.  The action calls the appropriate manager.  In this case, it
> >>calls the StoreroomManager, which is implemented in the
> >>StoreroomManagerImpl and extends the BaseManager.
> >>
> >>2.  We execute "startTransaction();", which executes
> >>"daoManager.startTransaction();" in the BaseManager.  BaseManager is
> >>where the DaoManager is defined and configured.
> >>
> >>3.  Then, we execute "inventoryItemDAO.create(newInventoryItem);".
> >>inventoryItemDAO was defined "inventoryItemDAO =
> >>(InventoryItemDAO)getDao(InventoryItemDAO.class);" using the getDao
> >>defined in BaseManager.
> >>
> >>4.  We go to SqlMapInventoryItemDAO which extends BaseDAO.
> >>
> >>5.  The BaseDAO executes these commands:
> >>
> >>    a,  "reader = Resources.getResourceAsReader(sqlMapConf);"
> >>    b.  "sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);"
> >>    c.  create() contains "executeUpdate(getEntityName() + "Insert",to""
> >>which translates as "executeUpdate("InventoryItemInsert", inventoryItem)"
> >>    d.  executeUpdate contains "return
> >>sqlMap.update(InventoryItemInsert, inventoryItem);"
> >>
> >>6.  This executes the statement in the inventoryItem.xml file called
> >>"InventoryItemInsert".
> >>
> >>7.  If no exceptions are thrown, we execute "commitTransaction();",
> >>which executes "daoManager.commitTransaction();" in the BaseManager.
> >>
> >>I can send you the files themselves if you need to see them.  For single
> >>sql commands in a transaction, it either commits or rollback as we would
> >>expect.  With something like:
> >>
> >>startTransaction();
> >>invoiceDAO.createInvoice(new Invoice);
> >>for (int i = 0; i < invoiceItem.size(); i++)
> >>{
> >>    invoiceItem = (InvoiceItem) invoiceItems.get(i);
> >>    invoiceItemDAO.createInvoiceItem(invoiceItem);
> >>}
> >>inventoryItem.updateInventoryItem(inventoryItem);
> >>for (int z = 0; z < transactions.size(); z++)
> >>{
> >>    transaction = (Transaction) transactions.get(z);
> >>    transactionDAO.createTransaction(transaction);
> >>}
> >>stopTransaction();
> >>
> >>Everything is commited prior to an exception being encountered with only
> >>the current sql command, that caused the exception, being rolled back.
> >>Since this is contained in try blocks to trap exceptions, we always call
> >>endTransaction().
> >>
> >>In JPetStore, if I remember right, commands are executed through a
> >>daomanager.update() versus a sqlmap.update().  Am I correct?  Am I miss
> >>reading JPetStore code execution?  By executing the SqlMapClientBuilder
> >>instead of letting the daomanager use the SqlMapDaoTemplate taking
> >>control away from the daomanager transaction control?
> >>
> >>If you need the files, let me know.  In the meantime, I have begun
> >>rewriting the application in the pattern that JPetstore uses, since I
> >>know that it does the rollback correctly.
> >>
> >>Thanks,
> >>
> >>Al
> >>
> >>
> >>
> >>
> >
> >
> >
> Brandon,
>
> I think I am close to understanding this now.  What if the
> SqlMapDaoTemplate is never reference within the application and never
> extended?  We import these com.ibatis.dao.client.DaoManagerBuilder ,
> com.ibatis.dao.client.Dao, com.ibatis.sqlmap.client.SqlMapClient and
> com.ibatis.sqlmap.client.SqlMapClientBuilder.  We extend
> com.ibatis.dao.client.Dao in our base interfaceDao and then implement
> that in our baseDao, which all other Dao interfaces/implementations
> extend.  Is this the same as extending the SqlMapDaoTemplate or have we
> broken the DaoManager control by NOT extending, implementing and using
> the SqlMapDaoTemplate?
>
> Sorry about taking so much time, but I have never worked with a
> programming language other than Cobol.  Also, never worked with anything
> beyond key-indexed files.  This project has been more a "jump in the
> deep-end" experience to me.
>
> Thanks for trying to explain all this to me,
>
> Al
>
>

Re: Combined DAO manager with a SqlMap client. Wrong?

Posted by "Albert L. Sapp" <as...@uiuc.edu>.
Brandon Goodin wrote:

>"In JPetStore, if I remember right, commands are executed through a
>daomanager.update() versus a sqlmap.update().  Am I correct? "
>
>This is not correct. The DaoManager is used to retrieve an instance of
>the Dao. One of the fuctions of the DaoManager is to be a Dao Factory.
>In the dao.xml DAO interfaces are mapped to DAO implementations. The
>DaoManager passes back the implementation of the DAO interface.
>
>Another function of the DaoManager is transaciton management. When
>using the DaoManager in conjunction with SqlMaps it retrieves an
>intance of the Dao and also passes itself into the Dao implemenations
>constructor. That is why classes that use the DaoManager in
>conjunction with SqlMaps extend the SqlMapDaoTemplate.
>
>In a standard web architecture you may see something like:
>
>Application --> Service --> Data Access
>
>Application is where Struts/JSP or whatever lives.
>Service is where the Dao Manager exists.
>The Data Access layer is where the SqlMaps exists.
>
>The service layer is where you would make more course grained calls
>that are made up of fine grained calls to the Data Access layer. Since
>the service layer is responsible for grouping together calls to the
>Data Access layer (or DAO classes) you would want to manage
>transactions on the service layer. If you have mulitple calls to
>multiple DAO classes in a method on your service class you would want
>to wrap them in a transaction in the service class method. You would
>do this with daoManager.startTransaction() etc...
>
>In your Dao that extends SqlMapDaoTemplate you would simple calls the
>queryFor.., insert,update, delete methods. These methods are calling
>the SqlMapClient/SqlMapClientImpl as you normally would if you never
>used the DaoManager. The only difference is that the calls are being
>passed through the SqlMapDaoTemplate class and the transactions are
>being managed by the DaoManager.
>
>Hope that helps,
>Brandon
>
>On 2/10/06, Albert L. Sapp <as...@uiuc.edu> wrote:
>  
>
>>Brandon Goodin wrote:
>>
>>    
>>
>>>Actually JPetstore does use the SqlMapDaoTemplate. All of the DAO
>>>class extend BaseSqlMapDao which extends SqlMapDaoTemplate.
>>>
>>>In your case I am not completely clear on what you are doing. Perhaps
>>>you can provide code from your application that shows us how you are
>>>using iBatis. Code coupled with you explanation can go a long way.
>>>
>>>Brandon
>>>
>>>public class BaseSqlMapDao extends SqlMapDaoTemplate {
>>>
>>>On 2/10/06, Albert L. Sapp <as...@uiuc.edu> wrote:
>>>
>>>
>>>      
>>>
>>>>Ok, we think we have found why our application transaction handling is
>>>>not working right, but want to verify it.
>>>>
>>>>We downloaded and setup JPetStore to run against our Oracle database.
>>>>No changes where made to the configuration of the database.  We modified
>>>>the order placing function to force it to violate a primary key
>>>>constraint on one (create order) of the multiple sql commands it does
>>>>within the transaction.  This caused all the commands to rollback as we
>>>>would expect.  No update of the quantity on hand of the item occured.
>>>>
>>>>In our application we define a DaoManager, but never reference the
>>>>SqlMapDaoTemplate.  Instead, in our persistance layer, we define using
>>>>the SqlMapClientBuilder a SqlMapClient.  All operations use this
>>>>SqlMapClient (sqlmapclient.queryForList...).  Calls to start a
>>>>transaction execute daomgr.startTransaction.  Extra layers of
>>>>inheritance where implemented in the application by the then project
>>>>head.  Don't ask me why.  Anyway, when we do a transaction all the sql
>>>>commands up to the command that fails commit, when they should all
>>>>rollback.  Same database with same configuration on it.
>>>>
>>>>It appears that JPetStore uses the DaoManager to execute the
>>>>queryForList and such with no actual build of a SqlMapClient.  Am I
>>>>correct?  Is that why our transactions don't rollback correctly?
>>>>Otherwise, I am at a loss for why JPetStore rolls back correctly and our
>>>>application does not.  We are having to use stored procedures right now
>>>>to get the proper rollback, but one of the requirements is that the
>>>>application not be database dependant.  In other words, no having to
>>>>convert stored procedures on one database to another.
>>>>
>>>>Any help or comments would be greatly appreciated.
>>>>
>>>>Al
>>>>
>>>>
>>>>
>>>>
>>>>        
>>>>
>>>
>>>      
>>>
>>Brandon,
>>
>>I will try this again and leave out as much of the exception handling as
>>I can.  I will try to trace through what I think is happening though I
>>have never fully understood the explaination I was given.
>>
>>1.  Say we want to create a inventory item.  We have collected all the
>>information in our web page and created a transfer object bean in our
>>action.  The action calls the appropriate manager.  In this case, it
>>calls the StoreroomManager, which is implemented in the
>>StoreroomManagerImpl and extends the BaseManager.
>>
>>2.  We execute "startTransaction();", which executes
>>"daoManager.startTransaction();" in the BaseManager.  BaseManager is
>>where the DaoManager is defined and configured.
>>
>>3.  Then, we execute "inventoryItemDAO.create(newInventoryItem);".
>>inventoryItemDAO was defined "inventoryItemDAO =
>>(InventoryItemDAO)getDao(InventoryItemDAO.class);" using the getDao
>>defined in BaseManager.
>>
>>4.  We go to SqlMapInventoryItemDAO which extends BaseDAO.
>>
>>5.  The BaseDAO executes these commands:
>>
>>    a,  "reader = Resources.getResourceAsReader(sqlMapConf);"
>>    b.  "sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);"
>>    c.  create() contains "executeUpdate(getEntityName() + "Insert",to""
>>which translates as "executeUpdate("InventoryItemInsert", inventoryItem)"
>>    d.  executeUpdate contains "return
>>sqlMap.update(InventoryItemInsert, inventoryItem);"
>>
>>6.  This executes the statement in the inventoryItem.xml file called
>>"InventoryItemInsert".
>>
>>7.  If no exceptions are thrown, we execute "commitTransaction();",
>>which executes "daoManager.commitTransaction();" in the BaseManager.
>>
>>I can send you the files themselves if you need to see them.  For single
>>sql commands in a transaction, it either commits or rollback as we would
>>expect.  With something like:
>>
>>startTransaction();
>>invoiceDAO.createInvoice(new Invoice);
>>for (int i = 0; i < invoiceItem.size(); i++)
>>{
>>    invoiceItem = (InvoiceItem) invoiceItems.get(i);
>>    invoiceItemDAO.createInvoiceItem(invoiceItem);
>>}
>>inventoryItem.updateInventoryItem(inventoryItem);
>>for (int z = 0; z < transactions.size(); z++)
>>{
>>    transaction = (Transaction) transactions.get(z);
>>    transactionDAO.createTransaction(transaction);
>>}
>>stopTransaction();
>>
>>Everything is commited prior to an exception being encountered with only
>>the current sql command, that caused the exception, being rolled back.
>>Since this is contained in try blocks to trap exceptions, we always call
>>endTransaction().
>>
>>In JPetStore, if I remember right, commands are executed through a
>>daomanager.update() versus a sqlmap.update().  Am I correct?  Am I miss
>>reading JPetStore code execution?  By executing the SqlMapClientBuilder
>>instead of letting the daomanager use the SqlMapDaoTemplate taking
>>control away from the daomanager transaction control?
>>
>>If you need the files, let me know.  In the meantime, I have begun
>>rewriting the application in the pattern that JPetstore uses, since I
>>know that it does the rollback correctly.
>>
>>Thanks,
>>
>>Al
>>
>>
>>    
>>
>
>  
>
Brandon,

I think I am close to understanding this now.  What if the 
SqlMapDaoTemplate is never reference within the application and never 
extended?  We import these com.ibatis.dao.client.DaoManagerBuilder , 
com.ibatis.dao.client.Dao, com.ibatis.sqlmap.client.SqlMapClient and 
com.ibatis.sqlmap.client.SqlMapClientBuilder.  We extend 
com.ibatis.dao.client.Dao in our base interfaceDao and then implement 
that in our baseDao, which all other Dao interfaces/implementations 
extend.  Is this the same as extending the SqlMapDaoTemplate or have we 
broken the DaoManager control by NOT extending, implementing and using 
the SqlMapDaoTemplate?

Sorry about taking so much time, but I have never worked with a 
programming language other than Cobol.  Also, never worked with anything 
beyond key-indexed files.  This project has been more a "jump in the 
deep-end" experience to me.

Thanks for trying to explain all this to me,

Al


Re: Combined DAO manager with a SqlMap client. Wrong?

Posted by Brandon Goodin <br...@gmail.com>.
"In JPetStore, if I remember right, commands are executed through a
daomanager.update() versus a sqlmap.update().  Am I correct? "

This is not correct. The DaoManager is used to retrieve an instance of
the Dao. One of the fuctions of the DaoManager is to be a Dao Factory.
In the dao.xml DAO interfaces are mapped to DAO implementations. The
DaoManager passes back the implementation of the DAO interface.

Another function of the DaoManager is transaciton management. When
using the DaoManager in conjunction with SqlMaps it retrieves an
intance of the Dao and also passes itself into the Dao implemenations
constructor. That is why classes that use the DaoManager in
conjunction with SqlMaps extend the SqlMapDaoTemplate.

In a standard web architecture you may see something like:

Application --> Service --> Data Access

Application is where Struts/JSP or whatever lives.
Service is where the Dao Manager exists.
The Data Access layer is where the SqlMaps exists.

The service layer is where you would make more course grained calls
that are made up of fine grained calls to the Data Access layer. Since
the service layer is responsible for grouping together calls to the
Data Access layer (or DAO classes) you would want to manage
transactions on the service layer. If you have mulitple calls to
multiple DAO classes in a method on your service class you would want
to wrap them in a transaction in the service class method. You would
do this with daoManager.startTransaction() etc...

In your Dao that extends SqlMapDaoTemplate you would simple calls the
queryFor.., insert,update, delete methods. These methods are calling
the SqlMapClient/SqlMapClientImpl as you normally would if you never
used the DaoManager. The only difference is that the calls are being
passed through the SqlMapDaoTemplate class and the transactions are
being managed by the DaoManager.

Hope that helps,
Brandon

On 2/10/06, Albert L. Sapp <as...@uiuc.edu> wrote:
> Brandon Goodin wrote:
>
> >Actually JPetstore does use the SqlMapDaoTemplate. All of the DAO
> >class extend BaseSqlMapDao which extends SqlMapDaoTemplate.
> >
> >In your case I am not completely clear on what you are doing. Perhaps
> >you can provide code from your application that shows us how you are
> >using iBatis. Code coupled with you explanation can go a long way.
> >
> >Brandon
> >
> >public class BaseSqlMapDao extends SqlMapDaoTemplate {
> >
> >On 2/10/06, Albert L. Sapp <as...@uiuc.edu> wrote:
> >
> >
> >>Ok, we think we have found why our application transaction handling is
> >>not working right, but want to verify it.
> >>
> >>We downloaded and setup JPetStore to run against our Oracle database.
> >>No changes where made to the configuration of the database.  We modified
> >>the order placing function to force it to violate a primary key
> >>constraint on one (create order) of the multiple sql commands it does
> >>within the transaction.  This caused all the commands to rollback as we
> >>would expect.  No update of the quantity on hand of the item occured.
> >>
> >>In our application we define a DaoManager, but never reference the
> >>SqlMapDaoTemplate.  Instead, in our persistance layer, we define using
> >>the SqlMapClientBuilder a SqlMapClient.  All operations use this
> >>SqlMapClient (sqlmapclient.queryForList...).  Calls to start a
> >>transaction execute daomgr.startTransaction.  Extra layers of
> >>inheritance where implemented in the application by the then project
> >>head.  Don't ask me why.  Anyway, when we do a transaction all the sql
> >>commands up to the command that fails commit, when they should all
> >>rollback.  Same database with same configuration on it.
> >>
> >>It appears that JPetStore uses the DaoManager to execute the
> >>queryForList and such with no actual build of a SqlMapClient.  Am I
> >>correct?  Is that why our transactions don't rollback correctly?
> >>Otherwise, I am at a loss for why JPetStore rolls back correctly and our
> >>application does not.  We are having to use stored procedures right now
> >>to get the proper rollback, but one of the requirements is that the
> >>application not be database dependant.  In other words, no having to
> >>convert stored procedures on one database to another.
> >>
> >>Any help or comments would be greatly appreciated.
> >>
> >>Al
> >>
> >>
> >>
> >>
> >
> >
> >
> Brandon,
>
> I will try this again and leave out as much of the exception handling as
> I can.  I will try to trace through what I think is happening though I
> have never fully understood the explaination I was given.
>
> 1.  Say we want to create a inventory item.  We have collected all the
> information in our web page and created a transfer object bean in our
> action.  The action calls the appropriate manager.  In this case, it
> calls the StoreroomManager, which is implemented in the
> StoreroomManagerImpl and extends the BaseManager.
>
> 2.  We execute "startTransaction();", which executes
> "daoManager.startTransaction();" in the BaseManager.  BaseManager is
> where the DaoManager is defined and configured.
>
> 3.  Then, we execute "inventoryItemDAO.create(newInventoryItem);".
> inventoryItemDAO was defined "inventoryItemDAO =
> (InventoryItemDAO)getDao(InventoryItemDAO.class);" using the getDao
> defined in BaseManager.
>
> 4.  We go to SqlMapInventoryItemDAO which extends BaseDAO.
>
> 5.  The BaseDAO executes these commands:
>
>     a,  "reader = Resources.getResourceAsReader(sqlMapConf);"
>     b.  "sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);"
>     c.  create() contains "executeUpdate(getEntityName() + "Insert",to""
> which translates as "executeUpdate("InventoryItemInsert", inventoryItem)"
>     d.  executeUpdate contains "return
> sqlMap.update(InventoryItemInsert, inventoryItem);"
>
> 6.  This executes the statement in the inventoryItem.xml file called
> "InventoryItemInsert".
>
> 7.  If no exceptions are thrown, we execute "commitTransaction();",
> which executes "daoManager.commitTransaction();" in the BaseManager.
>
> I can send you the files themselves if you need to see them.  For single
> sql commands in a transaction, it either commits or rollback as we would
> expect.  With something like:
>
> startTransaction();
> invoiceDAO.createInvoice(new Invoice);
> for (int i = 0; i < invoiceItem.size(); i++)
> {
>     invoiceItem = (InvoiceItem) invoiceItems.get(i);
>     invoiceItemDAO.createInvoiceItem(invoiceItem);
> }
> inventoryItem.updateInventoryItem(inventoryItem);
> for (int z = 0; z < transactions.size(); z++)
> {
>     transaction = (Transaction) transactions.get(z);
>     transactionDAO.createTransaction(transaction);
> }
> stopTransaction();
>
> Everything is commited prior to an exception being encountered with only
> the current sql command, that caused the exception, being rolled back.
> Since this is contained in try blocks to trap exceptions, we always call
> endTransaction().
>
> In JPetStore, if I remember right, commands are executed through a
> daomanager.update() versus a sqlmap.update().  Am I correct?  Am I miss
> reading JPetStore code execution?  By executing the SqlMapClientBuilder
> instead of letting the daomanager use the SqlMapDaoTemplate taking
> control away from the daomanager transaction control?
>
> If you need the files, let me know.  In the meantime, I have begun
> rewriting the application in the pattern that JPetstore uses, since I
> know that it does the rollback correctly.
>
> Thanks,
>
> Al
>
>

Re: Combined DAO manager with a SqlMap client. Wrong?

Posted by "Albert L. Sapp" <as...@uiuc.edu>.
Brandon Goodin wrote:

>Actually JPetstore does use the SqlMapDaoTemplate. All of the DAO
>class extend BaseSqlMapDao which extends SqlMapDaoTemplate.
>
>In your case I am not completely clear on what you are doing. Perhaps
>you can provide code from your application that shows us how you are
>using iBatis. Code coupled with you explanation can go a long way.
>
>Brandon
>
>public class BaseSqlMapDao extends SqlMapDaoTemplate {
>
>On 2/10/06, Albert L. Sapp <as...@uiuc.edu> wrote:
>  
>
>>Ok, we think we have found why our application transaction handling is
>>not working right, but want to verify it.
>>
>>We downloaded and setup JPetStore to run against our Oracle database.
>>No changes where made to the configuration of the database.  We modified
>>the order placing function to force it to violate a primary key
>>constraint on one (create order) of the multiple sql commands it does
>>within the transaction.  This caused all the commands to rollback as we
>>would expect.  No update of the quantity on hand of the item occured.
>>
>>In our application we define a DaoManager, but never reference the
>>SqlMapDaoTemplate.  Instead, in our persistance layer, we define using
>>the SqlMapClientBuilder a SqlMapClient.  All operations use this
>>SqlMapClient (sqlmapclient.queryForList...).  Calls to start a
>>transaction execute daomgr.startTransaction.  Extra layers of
>>inheritance where implemented in the application by the then project
>>head.  Don't ask me why.  Anyway, when we do a transaction all the sql
>>commands up to the command that fails commit, when they should all
>>rollback.  Same database with same configuration on it.
>>
>>It appears that JPetStore uses the DaoManager to execute the
>>queryForList and such with no actual build of a SqlMapClient.  Am I
>>correct?  Is that why our transactions don't rollback correctly?
>>Otherwise, I am at a loss for why JPetStore rolls back correctly and our
>>application does not.  We are having to use stored procedures right now
>>to get the proper rollback, but one of the requirements is that the
>>application not be database dependant.  In other words, no having to
>>convert stored procedures on one database to another.
>>
>>Any help or comments would be greatly appreciated.
>>
>>Al
>>
>>
>>    
>>
>
>  
>
Brandon,

I will try this again and leave out as much of the exception handling as 
I can.  I will try to trace through what I think is happening though I 
have never fully understood the explaination I was given.

1.  Say we want to create a inventory item.  We have collected all the 
information in our web page and created a transfer object bean in our 
action.  The action calls the appropriate manager.  In this case, it 
calls the StoreroomManager, which is implemented in the 
StoreroomManagerImpl and extends the BaseManager.

2.  We execute "startTransaction();", which executes 
"daoManager.startTransaction();" in the BaseManager.  BaseManager is 
where the DaoManager is defined and configured.

3.  Then, we execute "inventoryItemDAO.create(newInventoryItem);".  
inventoryItemDAO was defined "inventoryItemDAO = 
(InventoryItemDAO)getDao(InventoryItemDAO.class);" using the getDao 
defined in BaseManager.

4.  We go to SqlMapInventoryItemDAO which extends BaseDAO.

5.  The BaseDAO executes these commands:

    a,  "reader = Resources.getResourceAsReader(sqlMapConf);"
    b.  "sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);"
    c.  create() contains "executeUpdate(getEntityName() + "Insert",to"" 
which translates as "executeUpdate("InventoryItemInsert", inventoryItem)"
    d.  executeUpdate contains "return 
sqlMap.update(InventoryItemInsert, inventoryItem);"

6.  This executes the statement in the inventoryItem.xml file called 
"InventoryItemInsert".

7.  If no exceptions are thrown, we execute "commitTransaction();", 
which executes "daoManager.commitTransaction();" in the BaseManager.

I can send you the files themselves if you need to see them.  For single 
sql commands in a transaction, it either commits or rollback as we would 
expect.  With something like:

startTransaction();
invoiceDAO.createInvoice(new Invoice);
for (int i = 0; i < invoiceItem.size(); i++)
{
    invoiceItem = (InvoiceItem) invoiceItems.get(i);
    invoiceItemDAO.createInvoiceItem(invoiceItem);
}
inventoryItem.updateInventoryItem(inventoryItem);
for (int z = 0; z < transactions.size(); z++)
{
    transaction = (Transaction) transactions.get(z);
    transactionDAO.createTransaction(transaction);
}
stopTransaction();

Everything is commited prior to an exception being encountered with only 
the current sql command, that caused the exception, being rolled back.  
Since this is contained in try blocks to trap exceptions, we always call 
endTransaction().

In JPetStore, if I remember right, commands are executed through a 
daomanager.update() versus a sqlmap.update().  Am I correct?  Am I miss 
reading JPetStore code execution?  By executing the SqlMapClientBuilder 
instead of letting the daomanager use the SqlMapDaoTemplate taking 
control away from the daomanager transaction control?

If you need the files, let me know.  In the meantime, I have begun 
rewriting the application in the pattern that JPetstore uses, since I 
know that it does the rollback correctly.

Thanks,

Al


Re: Combined DAO manager with a SqlMap client. Wrong?

Posted by Brandon Goodin <br...@gmail.com>.
Actually JPetstore does use the SqlMapDaoTemplate. All of the DAO
class extend BaseSqlMapDao which extends SqlMapDaoTemplate.

In your case I am not completely clear on what you are doing. Perhaps
you can provide code from your application that shows us how you are
using iBatis. Code coupled with you explanation can go a long way.

Brandon

public class BaseSqlMapDao extends SqlMapDaoTemplate {

On 2/10/06, Albert L. Sapp <as...@uiuc.edu> wrote:
> Ok, we think we have found why our application transaction handling is
> not working right, but want to verify it.
>
> We downloaded and setup JPetStore to run against our Oracle database.
> No changes where made to the configuration of the database.  We modified
> the order placing function to force it to violate a primary key
> constraint on one (create order) of the multiple sql commands it does
> within the transaction.  This caused all the commands to rollback as we
> would expect.  No update of the quantity on hand of the item occured.
>
> In our application we define a DaoManager, but never reference the
> SqlMapDaoTemplate.  Instead, in our persistance layer, we define using
> the SqlMapClientBuilder a SqlMapClient.  All operations use this
> SqlMapClient (sqlmapclient.queryForList...).  Calls to start a
> transaction execute daomgr.startTransaction.  Extra layers of
> inheritance where implemented in the application by the then project
> head.  Don't ask me why.  Anyway, when we do a transaction all the sql
> commands up to the command that fails commit, when they should all
> rollback.  Same database with same configuration on it.
>
> It appears that JPetStore uses the DaoManager to execute the
> queryForList and such with no actual build of a SqlMapClient.  Am I
> correct?  Is that why our transactions don't rollback correctly?
> Otherwise, I am at a loss for why JPetStore rolls back correctly and our
> application does not.  We are having to use stored procedures right now
> to get the proper rollback, but one of the requirements is that the
> application not be database dependant.  In other words, no having to
> convert stored procedures on one database to another.
>
> Any help or comments would be greatly appreciated.
>
> Al
>
>