Database Independence - IBatis - Nhibernate

Database Independence - IBatis - Nhibernate

Old forum URL: forums.lhotka.net/forums/t/4283.aspx


davido posted on Monday, February 04, 2008

Hi,

I would like to achieve databae independence for my CSLA projects.

The two main options (AFAIK) appear to be IBatis and NHibernate.

I am not intrested in using Direct/Dynamic SQL - this is simply not an option in most of our projects. A stored procedure only approach is required.

In some cases we may not be able to change/add stored procedures i.e. we must make use of existing CSLA CRUD procedures.

NHibernate seems to be a non runner because:

a) it always requires rows to be returned (AFAIK).

b) identities need to be the last parameter passed to a stored proc (AFAIK).

Having said that, NHibernate appears to have more momentum behind it than IBatis.

I would like to get some feedback on any previosus experiences from the group.

Most importantly we don't want to implement anything that will not be compatible with future versions of CSLA. In fact if there are any plans for CSLA to make use of any technology to implement database independence we'd really like to hear about it now if possible.

Any feedback appreciated.

Thanks.

jtradke replied on Monday, February 04, 2008

Hi Davido -

Sorry, don't have any answers to your questions, but I'm in a similar boat, trying to foster the unholy marriage of CSLA and IBatis.  It seems at this point that the best option is to circumvent the DataPortal in favor of my own .  Main reason is that the DataPortal_Fetch method is instance level and is called *after* the object is already instantiated (as I understand it).  However, calls to IBatis return a complete object (not just a DataSet), so the _Fetch method would consist of calling QueryForObject(), and then copying each of the fetched object's values over to the current instance, which seems a bit ridiculous, since you already have a complete instance of the object.

So my solution has been to avoid the DataPortal_* methods altogether, and create my own static Repository class, which is then called wherever any DataPortal calls would normally be made.  Downside is that this involves duplicating some of the CSLA base class logic (mostly checking the IsSavable, IsDirty, IsNew flags).

So for my own knowledge, and hopefully David's, does this sound reasonable?

Thanks,
John

ajj3085 replied on Monday, February 04, 2008

That doesn't sound like a good idea to me.  If IBatis is like NHibernate, it should be used in the DataPortal methods, but should not BE a business object.  The IBatis object should have its values copied to the BO's fields.

I'd be very careful moving forward, especially if you do need to go 3-tier.

jtradke replied on Monday, February 04, 2008

But the IBatis object *IS* the BO.  If your Fetch method is just mapping one BO to another BO of the same type, that's a maintenance problem because adding a property to the BO means adding it to the IBatis SqlMap *and* to the _Fetch method.  My idea would be to let IBatis do its job in giving me an object which I can immediately use as provided.

I'm confused by your statement: "it should be used in the DataPortal methods, but should not BE a business object".  Are you talking about the Repository object I mentioned?  This would not be a business object - it would be a separate helper class sitting in my DataAccess project along with all the IBatis config hooey.  It's de-coupled from the Business objects as much as possible.

Re: 3-tier, there's no plans for moving to a 3-tier setup, and historically at my company it hasn't really been utilized (as far as I'm aware), so I don't wish to have that nebulous possibility complicate my architecture decisions.  I mean, hopefully this doesn't get me razzed around here, but I'd rather cross *that* bridge when it becomes necessary, and no sooner.

ajj3085 replied on Monday, February 04, 2008

jtradke:
But the IBatis object *IS* the BO.


That's exactly what is a bad idea.  Your BO is there to fulfill a use case, not to store data.  It shouldn't be modeled on the structure of the data, yet that sounds exactly like what you're doing. 

jtradke:
If your Fetch method is just mapping one BO to another BO of the same type, that's a maintenance problem because adding a property to the BO means adding it to the IBatis SqlMap *and* to the _Fetch method.  My idea would be to let IBatis do its job in giving me an object which I can immediately use as provided.


The solution to that is code generation, NOT building BOs which are doubling as DTOs.

jtradke:
Re: 3-tier, there's no plans for moving to a 3-tier setup, and historically at my company it hasn't really been utilized (as far as I'm aware), so I don't wish to have that nebulous possibility complicate my architecture decisions.  I mean, hopefully this doesn't get me razzed around here, but I'd rather cross *that* bridge when it becomes necessary, and no sooner.


All it takes is having to support users at two locations with a single database.  Suddenly 3-tier helps quite a bit, because talking to a database is a chatty proposition.  I didn't think I'd use it either, but here I am. 

There's other risks as well; each time you change a table, you'll need to change your BO, even when the change should not affect the BO at all, because the data is not necessary to fulfill the use case.  Your application can break and become harder to maintain because your BO is re-used multiple times when it should not be.

Finally, upgrading Csla becomes more difficult, because you're having to duplicate logic that is already provided by the framework itself.  You've said you're already doing this, which means it will probably be difficult for you to move to 3.5; that version changes how IsDirty is tracked.  Will it impact you?  I can't say for sure, if if you're duplicating what's already done by the framework, its giong to be increasingly difficult for you to move to newer versions. 

I've been down that road before.. not with Csla, but we did have BOs which were based on data, and it DID become a huge maintence problem.  Weird subclassing, changing one bit of functionality broke other bits that had been working.. its not pretty.

tmg4340 replied on Monday, February 04, 2008

jtradke:
But the IBatis object *IS* the BO.  If your Fetch method is just mapping one BO to another BO of the same type, that's a maintenance problem because adding a property to the BO means adding it to the IBatis SqlMap *and* to the _Fetch method.  My idea would be to let IBatis do its job in giving me an object which I can immediately use as provided.

I'm confused by your statement: "it should be used in the DataPortal methods, but should not BE a business object".  Are you talking about the Repository object I mentioned?  This would not be a business object - it would be a separate helper class sitting in my DataAccess project along with all the IBatis config hooey.  It's de-coupled from the Business objects as much as possible.

Re: 3-tier, there's no plans for moving to a 3-tier setup, and historically at my company it hasn't really been utilized (as far as I'm aware), so I don't wish to have that nebulous possibility complicate my architecture decisions.  I mean, hopefully this doesn't get me razzed around here, but I'd rather cross *that* bridge when it becomes necessary, and no sooner.

Well - I'm not going to razz you, but I do have to agree with the questions raised...

If you are using iBatis to populate your BO's directly (which is the only way I can see using it that would cause you to dump the DataPortal), then you are bypassing a lot of what the DataPortal gives you.  I understand that you don't see a 3-tier environment on your horizon anytime soon, and that's fine.  But the transport- and location-level transparency that the DataPortal gives you is not exclusively useful in a 3-tier environment.  Plus, if the decision comes down that you do have to move to an n-tier environment, your time to complete that project would probably be a heck of a lot less had you used the DP than what you're doing now.  And has been mentioned, if you're not using the n-tier facilities of the DP, your coding style doesn't change, and you don't see any overhead in execution either.

Plus, as you've alaready mentioned, you've had to "duplicate some of the CSLA base class logic".  This would seem to be to be a bigger maintenance problem than having iBatis return some DTO's that you transfer back and forth (a process that can be greatly simplified by using the DataMapper, BTW), since you have to maintain that code base as new versions of CSLA make their way into your applications.  That, I would guess, is a lot more code to manage than some property-mapping code.

I would also like to know why it's a problem for the DP_ methods to be instance-related - after all, you have to have an instance of the object in order to populate it...

- Scott

jtradke replied on Monday, February 04, 2008

Sorry, I think I've lead this discussion off-track.  I'll start a new thread regarding my own personal DataPortal concerns.

Back to David's original question (using NHibernate or IBatis with CSLA), I have obviously demonstrated that I don't have that experience.  I do, however, have lots of experience with IBatis to tell you that it's pretty well-designed and robust.  We've got a couple of apps in production that use it.  The main reason we chose it was because it helps mitigate issues with legacy database problems.  With NHibernate, you only get to define the mappings between a table's column and an object's field, and it writes the queries automagically.  With IBatis, though, you have full control over the query.

The way I look at it is that NHibernate maps a table/view/proc to an object, while IBatis maps a QUERY to an object.  At least I *think* this is the case, as I have not used NHibernate at all.  Anyway, with IBatis, you could have an object model that is neatly decoupled from the data model, which is super-cool when you have a nasty legacy data model to deal with.

And for the record, I am quite certain you can use IBatis just fine with the DataPortal; it's just that I'm a stubborn jerkface, and am merely attempting to bend CSLA to my will, which is definitely riskier than just using it as prescribed.

ajj3085 replied on Monday, February 04, 2008

jtradke:
And for the record, I am quite certain you can use IBatis just fine with the DataPortal;


From what is described here, it certainly sounds like that is the case.

jtradke:
it's just that I'm a stubborn jerkface, and am merely attempting to bend CSLA to my will, which is definitely riskier than just using it as prescribed.


Sorry, I didn't intend to make you feel that way, and I hope I haven't.  Perhaps my warning was a bit strong... but I've been bitten like that before.  So I hope I didn't offend you or anything. 

I would definately be careful though; Rocky has posted recently that to successfully use a framework, you need to buy into the philosophy behind the frameworks design.  The philosophy here is that business objects should be designed to fulfill use cases, not around what data the objects hold.

Andy

jtradke replied on Monday, February 04, 2008

Nope, I'm just being self-deprecating.  The exact problem is that I don't buy into the framework, so I'm trying to work around it.  But I'm trying to have a sense of humor about it so I don't get all pissed off when it doesn't work out the way I want.

And regardless, I think there's a misunderstanding that I aiming for data-driven design - that's not true.  IBatis does not tie you to the data model.  With IBatis, *you* write the database queries, just like you would with ADO, so there's nothing to say you can't have a ten-table join for a single BO, or a single table behind ten different BOs.

ajj3085 replied on Tuesday, February 05, 2008

jtradke:
The exact problem is that I don't buy into the framework, so I'm trying to work around it.  But I'm trying to have a sense of humor about it so I don't get all pissed off when it doesn't work out the way I want.


Hmm... well an interesting approach.  Smile [:)]

jtradke:
And regardless, I think there's a misunderstanding that I aiming for data-driven design - that's not true.  IBatis does not tie you to the data model.  With IBatis, *you* write the database queries, just like you would with ADO, so there's nothing to say you can't have a ten-table join for a single BO, or a single table behind ten different BOs.


Ahh, yes that is a mis-understanding, which comes about from me not knowing enough about IBatis.  Certainly sounds interesting, its a shame you need to ditch the dataportal concept to use it.

SomeGuy replied on Tuesday, February 05, 2008

"so there's nothing to say you can't have a ten-table join for a single BO, or a single table behind ten different BOs."

Well, that is true of CSLA and the DataPortal also.

E

jtradke replied on Tuesday, February 05, 2008

SomeGuy:

Well, that is true of CSLA and the DataPortal also.

Yes, of course.  I never meant to imply it wasn't.

Copyright (c) Marimer LLC