views:

58

answers:

2

We have a J2EE app built on Struts2+spring+iBatis; not all DAO's use iBatis...some code still uses the old JDBC approach of interacting with Database. All our DAO's call Stored Procedures, we do not have any inline SQL. Since Oracle Stored Procedures return cursors, we have to drastically change our code.

It is fairly easy for us to convert current iBatis mappings (in sql) to oracle (used a groovy script to do this) also it is easy to convert Java code that was calling old mappings that were in sql.

Our problem is to convert the old DAO's that still use JDBC approach. Since we will have to modify them anyways (because we are now using oracle) we are thinking about converting them to iBatis mappings. is this a good approach? This will be a huge effort from our side...

what do you think will be the best approach to tackle this huge effort?

  • should we just get to work and start converting each method in every DAO
  • should we try to make some small script that looks at each method, parses out relevant information and makes iBatis mappings from that.
  • for maintenance and seperation purpose should we have 1 iBatis mapping for each DAO

I appologize if the question is vague but am just looking for someone who has gone through this type of thing before and has some pointers or 'lessons learned'.

+1  A: 

The first thing you should do is cover your DAO layer in tests. This way you'll know if you broke something during the conversion. If you are moving a stored procedure from one DBMS to Oracle, you should also write tests for that using a framework like DbUnit.

You should have a TEST DB instance populated with sample data that doesn't change. You should be able to refresh this DB with the same set of sample data after your are done running your tests. This will ensure your TEST DB is in a known state. You will then have your input parameters paired with some expected (correct) result. Your test will read in these pairs and execute them against the test DB instance and confirm the expected result is returned. Assuming your tests mutate the DB, you'll want to refresh the DB between runs of your test suite.

Second, if you're already going in and changing some data access implementations for Oracle, why not use this as an opportunity to move some of that business logic out of the DB and into Java? There are many well-documented problems with maintaining large codebases in a DBMS.

should we try to make some small script that looks at each method, parses out relevant information and makes iBatis mappings from that.

I don't recommend this. The time you'd spend tweaking the script for each special case, plus hunting down all the bugs it would introduce would be better spent doing the conversion by a thinking human.

for maintenance and seperation purpose should we have 1 iBatis mapping for each DAO

That's a fine idea. You can then combine them in your sqlMapConfig with

<sqlMap resource="sqlMaps/XXX.xml" />

This will keep your mappings more manageable. Just make sure to specify the namespace attribute in each sqlMap like:

<sqlMap namespace="User">

So that you can reuse mappings between the sqlMaps for instantiating object graphs (example: when loading a User and his Permissions, the User.xml sqlMap calls the Permission.xml mapping).

rcampbell
"....The first thing you should do is cover your DAO layer in tests..." - spot on with this.
duffymo
when you mention tests...do you mean unit tests? my question about that is....will these tests be run automatically? meaning will I have to go to each jsp page..click on something that triggers the DAO method or test. OR will these test be run all at once. If all at once then will the parameters to the Stored procedures be hardcoded into the test?
Omnipresent
@Omni: There are various mechanisms in Junit and TestNG to set up test suites. You would run these automatically and ideally after every change you make to the code. These would be more properly called integration tests, because you wouldn't just be executing the DAO impl in isolation, but together with a DB instance.
rcampbell
I recommend you set up a Maven goal, Ant task, shell script, or some other mechanism where with one click (or even automatically upon SCM checkin) your full suite of tests is run. If that is too slow, try looking at moving it to a different machine or a different schedule.
rcampbell
Also, you won't want to hardcode the parameters. The goal is you have a set of parameters along with their expected result. You could keep these key/value pairs in an XML and read it in easily with Commons Configuration. You would then have a TEST DB instance, whose data doesn't change. This is important because if you use some live instance, a data change could break your tests incorrectly.
rcampbell
If by unit tests you mean automated, the answer is yes, DbUnit allows to write automated tests. As an aside note, I consider them as integration tests, not unit tests (as they involve several layers).
Pascal Thivent
thanks guys. I'll start looking into Junit and DbUnit. I was also thinking about tests but didnt have any exp with them before. ..now is an ideal time :)
Omnipresent
A: 

All our DAO's call Stored Procedures

I don't see what iBatis is buying you here.

It's also not clear what the migration is. Are you saying that you've decided to move all the code into stored procedures, so there's no more in-line SQL? If that's the case, I'd say don't use iBatis. If you're already using Spring, let it call into Oracle using its StoredProcedure object and map the cursors into objects.

The recommendation to create JUnit or, better yet, TestNG tests is spot on. Do that before changing anything.

duffymo
They're probably using it for automatic object instantiation so they don't have to manually translate the ResultSet into an Object instance.
rcampbell
no we are not moving our code to stored procedure. Basically the backend is changing from SQL to Oracle and our code needs to change along with that. Even before this migration we were using stored procedures. difference now is that SQL stored procedures return result sets where as oracle returns cursors. that is why our code needs to change
Omnipresent