I really like the look of your IdeaBlade. It really reminds me of a Java based development platform that I have used in the past called Jade (www.discoverjade.com), which made building OO
systems so damned easy. Once I get the chance, I intend to give the lite version a test, but I'd also like to know how I go about making a full purchase. I can't see anything on your site that gives me information about sales or purchases. What would I need
to do?
Who wouldn't like a post like S. Roughley's? "I really like the look of your IdeaBlade...I'd also like to know how I go about making a full purchase."
Anyway, I don't go near pricing. Anyone who's interested should email
info@ideablade.com. Here I'm going to try to stick with the technology. Thanks though!
Re: Identity Columns, Frans understood me perfectly. The issue was not gaps in the Id series. It was the matter of rolling back the Id assignments to foreign keys - the assignments we made as we linked Order A to its child order items, A1,
A2, etc. as we saved and just before the transaction failed (for unrelated reasons). Frans' versioning / rollback approach would do the trick.
I am impressed that Frans dares to go farther and take on graph versioning. I assume, Frans, that you're only proposing to offer a multi-level undo within the bounds of a single user's (or session's) fetch and save. It's not clear to me what is the correct
behavior if I could roll back across my own save transactions. What might someone ELSE have done with the objects I saved and am now rolling back. Writing my novel on a word processor, I don't worry about the effects of my forward and backward motion on either
readers or other writers ... not until I publish. What if my main character gets on a plane and I write that the plane crashed. I publish. My co-author picks up the thread and starts a romance between the widow and his best friend. Meanwhile I decide he didn't
get on the plane but took the bus. I merge/publish. Looks bad for the friend, wife, and kids. Anyway, best of luck Frans.
Re: ID visibility to end-users. Thona, I absolutely agree that user's shouldn't see these IDs. IDs should have no business value baked into them. We'd all be better off if we could tolerate Guids. I just wish my customers felt the same way.
I usually don't have the luxury of designing my database; I have to make do with the database(s) I'm given, along with the constraints and expectations of the legacy applications that use them. Let me say again, it is not that I care about gaps in the ID sequence.
I am concerned about ensuring that all IDs and foreign keys referencing them have valid values. I also can't wish away the fact that others before me have conditioned the end user to view these IDs and actually reference them in their non-system communications.
So I have to be prepared to display them in some form both before inserting them into the database and after. Our need to operate disconnected from the database for long periods just makes the problem harder. Fortunately, we now have it covered.
Re: Discarding the objects if the transaction fails
Thona, do I understand this to be your meaning when you write "Transaction 101 and Windows standard approaches (COM+) demand that transactions having an exception are not resubmitted but thrown away, which means - the issue is a non issue again"? Again
you are technically correct. But it is the transaction which is thrown away, not the objects or their values. Of course the objects are now suspect. But it's really a business-cum-end-user decision as to what to do with them. And that makes it a REAL issue,
not a "non issue". Nothing is more discouraging than filling out a long form and having the entire thing thrown away for no apparent reason. The user didn't do anything wrong. Why should he pay because the transaction failed? Therefore, many apps will provide
mechanisms to salvage what they can, reconcile what they can, and offer the user a chance to "fix" and resubmit - as a new transaction.
I might add that I've worked for a number of large institutions that use last-one-wins concurrency (that is, no concurrency checking at all). Absolutely wrong of course. But the sky does not fall. The users are happy (or complaining about everything else BUT
this). I'm sure there are consequences. And yet sometimes you just have to let it go. Because in the business users' mind - discarding their work is WORSE than the (usually remote) dangers of data integrity problems. I can disagree (and the orphans records
and impossibly out-of-sync values help make my case). But they write the check and if it's not a big problem to them ... it's not a big problem.
Our job is to provide concurrency checking and transactional integrity AND provide the means for a satisfactory user experience.
I KNOW you know this. Therefore, I must have missed your point and am sure you will help me see it.
Re: Inheritance
Thona - Thanks for the reference to Ambler. You are justly proud of your CMS application. I can see that the way I put the question "What's your use case for inheritance?" might be read as a statement that I thought there was no case for inheritance among persistent
objects. Of course there is a case and I regret seeming to say otherwise by highlighting the (all to familiar) mistake of creating a subtype for what is, in everyday language, merely a role or facet.
[To recap: Someone wondering if 'A' can be a subtype (derived class, ...) of 'B' should ask "Can an object of type 'A' ever lose it's 'A'-ness and become something else?" Thus, if an employee can become a part-time worker, then a full-time worker, then a
part-time worker again, defining a "PartTimeWorker" class is not a good idea. As Frans observes, this is all so obvious with Employees but not so evident in other cases where instances have a way of looking a lot like types.]
You are surely right to observe that there are many clear cut cases of 'A' staying 'A'. A newspaper does not magically become a photograph even though both are documents. Their records are not just tagged with a four character field (your example); they are
tattooed with it. It follows that they can, as classes, descend from (say) "Document" even as they reside in the same database table.
I am pleased to report that IdeaBlade joins the other fine tools mentioned here in supporting the developer's decision to create Newspaper and Photograph types. They can be rooted in a common table AND have different graphs (related object branches, "per-type
relations") as befits their distinctive types. It is possible (I would say easy) to have them descend from Document and inherit or override its behaviors. It is also easy to inject a delegate or object adhering to an interface or do any of the other object
oriented gymnastics that we know about.
[Aside: I used auditing as an example. I do not agree that the mere presence of course grained life-cycle events - object changed, etc. - solves all auditing needs. True, an external audit system could listen in. But that could mean a giant case statement within
that "system" as it did some kinds of auditing for one class, a different kind for the next class, and so on. My preference would be to delegate the responsibility back to the classes themselves. In any case, it was only an example.]
I haven't thought much about AOP (spring.net) in this context; that's got possibilities and I can't think off hand why some AOP could not fit well with IdeaBlade business object classes.
Which leaves me where I started, wondering what Fregas wanted to do in the way of inheritance that he couldn't do in IdeaBlade. I have some guesses because we do impose some restrictions that others may not. But I'm wondering whether he might have been able
to finesse the problems he faced without doing violence to the integrity of his design. In other words, I'm curious about the practical consequences of the limitations of our approach.
Meanwhile, thanks to Frans and Thona for your willingness to take on these issues. I can only hope that readers of the thread will come to appreciate that we makers of Object-Relational Persistence layers are working diligently to provide them with solid, reliable,
performing and capable data access in an object-oriented manner. They should rely on one of us to carry this burden and focus their energies on building the rest of their applications. And THAT is my commercial for the day.
And if you will implement it your self you will get at the end DataSet.
Interesting enough - you do NOT get the DataSet at the end. You get leightweight object containers that are way more efficient than a dataset and have these capabilities.
I really don't have a lot of experience with anything but LLBLGEN Pro, but the bug you're talking about sounds odd, and in 2 years of using LLBLGen, I've never run into it.
All I can say is that I've really never encountered anything that I needed done that LLBLGen didn't do, and I'm working in a 300 table framework with over a million lines of code. I've never had a performance issue or found a bug in Frans' framework. I have
tables with millions of rows, hundreds of user controls, etc... and I simply couldn't be happier with it. The documentation is good, the support is even better, and it's completely OO from the top down.
Anyway, I'm sure WORM is good, as well as XPO, Versant and the like, but I just had to throw in my $.02.
I really don't have a lot of experience with anything but LLBLGEN Pro, but the bug you're talking about sounds odd, and in 2 years of using LLBLGen, I've never run into it.
All I can say is that I've really never encountered anything that I needed done that LLBLGen didn't do, and I'm working in a 300 table framework with over a million lines of code. I've never had a performance issue or found a bug in Frans' framework. I have
tables with millions of rows, hundreds of user controls, etc... and I simply couldn't be happier with it. The documentation is good, the support is even better, and it's completely OO from the top down.
Anyway, I'm sure WORM is good, as well as XPO, Versant and the like, but I just had to throw in my $.02.
Cheers,
-A
Yes, me and Frans went round for round on that bug, and you're right its pretty old. I haven't looked at the newest version so maybe you can tell me if it has improved in these areas:
- Its pretty complex. The objects inherit from some "uber object" in his framework and often have hundreds of members to sift thru. Many methods/properties it creates for you have default names like __GetSomething(). Not sure why, that might be something weird
with our crappy database.
- Its not "completely OO from the top down" since every
table becomes an object . You can't map multiple tables to the same class or to an enum. It also doesn't support inheritance, although Frans says he's working on it. Its more like an API into your particular database, which isn't necessarily bad, but not
good OO design.
Again, these were all problems with my particular version which is at least one year old.
I really don't have a lot of experience with anything but LLBLGEN Pro, but the bug you're talking about sounds odd, and in 2 years of using LLBLGen, I've never run into it.
All I can say is that I've really never encountered anything that I needed done that LLBLGen didn't do, and I'm working in a 300 table framework with over a million lines of code. I've never had a performance issue or found a bug in Frans' framework. I have
tables with millions of rows, hundreds of user controls, etc... and I simply couldn't be happier with it. The documentation is good, the support is even better, and it's completely OO from the top down.
Yes, me and Frans went round for round on that bug, and you're right its pretty old. I haven't looked at the newest version so maybe you can tell me if it has improved in these areas:
- Its pretty complex. The objects inherit from some "uber object" in his framework and often have hundreds of members to sift thru. Many methods/properties it creates for you have default names like __GetSomething(). Not sure why, that might be something weird
with our crappy database.
If you have hundreds of relations and fields in an entity, yes, you get hunderds of members, though you can hide relations if you don't want them/need them. And complex? Doing advanced stuff is complex when you want full power over what you want to do, simply
because all the options are offered to you. If you don't want that, you can use the simplified way of doing things, like Customer.Orders or what have you. Or generate your own wrapper methods, after all it contains a code generator engine.
- Its not "completely OO from the top down" since every
table becomes an object . You can't map multiple tables to the same class or to an enum. It also doesn't support inheritance, although Frans says he's working on it. Its more like an API into your particular database, which isn't necessarily bad, but not
good OO design.
Full inheritance, multi-entity same table, partly map target, polymorphic queries, new query system, etc. it's now in beta. Take a look, you're a licensee after all.
Oh, and I DO get tired about people calling my framework not 'good OO design'. First show me the criteria what's 'GOOD' OO design and second where my framework isn't using OO-style design. I mean it's full of patterns (have you spot them all, Fregas?), if that's
not OO design, I don't know what is, but I'm sure you can tell me right away.
You really confuse entity in a relational model (abstract) with a class. If you don't think like that about a database, perfectly fine by me, but don't claim it's not 'good design'. It's 'different', it uses a different approach, more Chen-Yourdon-Halpin, less
Fowler-Evans. Because there are different ways of doing data-access, and they are that much different from each other, based on what their core idea is, that you won't LIKE them all, but that doesn't mean the ones you don't LIKE are bad. Because that suggests
a list of criteria which can be used to check if something is GOOD. If you think such a list exists, that's fine, but I'm sure you also read this:
http://weblogs.asp.net/fbouma/archive/2004/10/09/240225.aspx
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
sroughley
Participant
1404 Points
381 Posts
Re: WORM, NHibernate and reviews of any other ORMappers
Aug 17, 2005 08:59 AM|LINK
WardB
Member
16 Points
3 Posts
Re: WORM, NHibernate and reviews of any other ORMappers
Aug 18, 2005 03:51 AM|LINK
Who wouldn't like a post like S. Roughley's? "I really like the look of your IdeaBlade...I'd also like to know how I go about making a full purchase."
Anyway, I don't go near pricing. Anyone who's interested should email info@ideablade.com. Here I'm going to try to stick with the technology. Thanks though!
WardB
Member
16 Points
3 Posts
Re: WORM, NHibernate and reviews of any other ORMappers
Aug 18, 2005 06:22 AM|LINK
Re: Identity Columns, Frans understood me perfectly. The issue was not gaps in the Id series. It was the matter of rolling back the Id assignments to foreign keys - the assignments we made as we linked Order A to its child order items, A1, A2, etc. as we saved and just before the transaction failed (for unrelated reasons). Frans' versioning / rollback approach would do the trick.
I am impressed that Frans dares to go farther and take on graph versioning. I assume, Frans, that you're only proposing to offer a multi-level undo within the bounds of a single user's (or session's) fetch and save. It's not clear to me what is the correct behavior if I could roll back across my own save transactions. What might someone ELSE have done with the objects I saved and am now rolling back. Writing my novel on a word processor, I don't worry about the effects of my forward and backward motion on either readers or other writers ... not until I publish. What if my main character gets on a plane and I write that the plane crashed. I publish. My co-author picks up the thread and starts a romance between the widow and his best friend. Meanwhile I decide he didn't get on the plane but took the bus. I merge/publish. Looks bad for the friend, wife, and kids. Anyway, best of luck Frans.
Re: ID visibility to end-users. Thona, I absolutely agree that user's shouldn't see these IDs. IDs should have no business value baked into them. We'd all be better off if we could tolerate Guids. I just wish my customers felt the same way. I usually don't have the luxury of designing my database; I have to make do with the database(s) I'm given, along with the constraints and expectations of the legacy applications that use them. Let me say again, it is not that I care about gaps in the ID sequence. I am concerned about ensuring that all IDs and foreign keys referencing them have valid values. I also can't wish away the fact that others before me have conditioned the end user to view these IDs and actually reference them in their non-system communications. So I have to be prepared to display them in some form both before inserting them into the database and after. Our need to operate disconnected from the database for long periods just makes the problem harder. Fortunately, we now have it covered.
Re: Discarding the objects if the transaction fails
Thona, do I understand this to be your meaning when you write "Transaction 101 and Windows standard approaches (COM+) demand that transactions having an exception are not resubmitted but thrown away, which means - the issue is a non issue again"? Again you are technically correct. But it is the transaction which is thrown away, not the objects or their values. Of course the objects are now suspect. But it's really a business-cum-end-user decision as to what to do with them. And that makes it a REAL issue, not a "non issue". Nothing is more discouraging than filling out a long form and having the entire thing thrown away for no apparent reason. The user didn't do anything wrong. Why should he pay because the transaction failed? Therefore, many apps will provide mechanisms to salvage what they can, reconcile what they can, and offer the user a chance to "fix" and resubmit - as a new transaction.
I might add that I've worked for a number of large institutions that use last-one-wins concurrency (that is, no concurrency checking at all). Absolutely wrong of course. But the sky does not fall. The users are happy (or complaining about everything else BUT this). I'm sure there are consequences. And yet sometimes you just have to let it go. Because in the business users' mind - discarding their work is WORSE than the (usually remote) dangers of data integrity problems. I can disagree (and the orphans records and impossibly out-of-sync values help make my case). But they write the check and if it's not a big problem to them ... it's not a big problem.
Our job is to provide concurrency checking and transactional integrity AND provide the means for a satisfactory user experience.
I KNOW you know this. Therefore, I must have missed your point and am sure you will help me see it.
Re: Inheritance
Thona - Thanks for the reference to Ambler. You are justly proud of your CMS application. I can see that the way I put the question "What's your use case for inheritance?" might be read as a statement that I thought there was no case for inheritance among persistent objects. Of course there is a case and I regret seeming to say otherwise by highlighting the (all to familiar) mistake of creating a subtype for what is, in everyday language, merely a role or facet.
[To recap: Someone wondering if 'A' can be a subtype (derived class, ...) of 'B' should ask "Can an object of type 'A' ever lose it's 'A'-ness and become something else?" Thus, if an employee can become a part-time worker, then a full-time worker, then a part-time worker again, defining a "PartTimeWorker" class is not a good idea. As Frans observes, this is all so obvious with Employees but not so evident in other cases where instances have a way of looking a lot like types.]
You are surely right to observe that there are many clear cut cases of 'A' staying 'A'. A newspaper does not magically become a photograph even though both are documents. Their records are not just tagged with a four character field (your example); they are tattooed with it. It follows that they can, as classes, descend from (say) "Document" even as they reside in the same database table.
I am pleased to report that IdeaBlade joins the other fine tools mentioned here in supporting the developer's decision to create Newspaper and Photograph types. They can be rooted in a common table AND have different graphs (related object branches, "per-type relations") as befits their distinctive types. It is possible (I would say easy) to have them descend from Document and inherit or override its behaviors. It is also easy to inject a delegate or object adhering to an interface or do any of the other object oriented gymnastics that we know about.
[Aside: I used auditing as an example. I do not agree that the mere presence of course grained life-cycle events - object changed, etc. - solves all auditing needs. True, an external audit system could listen in. But that could mean a giant case statement within that "system" as it did some kinds of auditing for one class, a different kind for the next class, and so on. My preference would be to delegate the responsibility back to the classes themselves. In any case, it was only an example.]
I haven't thought much about AOP (spring.net) in this context; that's got possibilities and I can't think off hand why some AOP could not fit well with IdeaBlade business object classes.
Which leaves me where I started, wondering what Fregas wanted to do in the way of inheritance that he couldn't do in IdeaBlade. I have some guesses because we do impose some restrictions that others may not. But I'm wondering whether he might have been able to finesse the problems he faced without doing violence to the integrity of his design. In other words, I'm curious about the practical consequences of the limitations of our approach.
Meanwhile, thanks to Frans and Thona for your willingness to take on these issues. I can only hope that readers of the thread will come to appreciate that we makers of Object-Relational Persistence layers are working diligently to provide them with solid, reliable, performing and capable data access in an object-oriented manner. They should rely on one of us to carry this burden and focus their energies on building the rest of their applications. And THAT is my commercial for the day.
tsv
Member
5 Points
1 Post
Re: WORM, NHibernate and reviews of any other ORMappers
Sep 17, 2005 07:28 PM|LINK
If for .NET 2.0. What about this one: www.lastcomponent.com?
Best!
JasonBunting
Member
525 Points
105 Posts
Re: WORM, NHibernate and reviews of any other ORMappers
Sep 19, 2005 12:53 AM|LINK
If it is using DataSets or DataRows, it cannot be "best." In fact, it makes me want to avoid it altogether.
lastcomponen...
Member
25 Points
5 Posts
Re: WORM, NHibernate and reviews of any other ORMappers
Sep 19, 2005 04:31 AM|LINK
Do you prefere to implement all logic provided by DataSets yourself?
I don't beleave that serrios application does not need it. And if you will implement it your self you will get at the end DataSet. Why not to get it?
Thanks.
thona
Member
20 Points
2923 Posts
Re: WORM, NHibernate and reviews of any other ORMappers
Sep 19, 2005 06:18 AM|LINK
Interesting enough - you do NOT get the DataSet at the end. You get leightweight object containers that are way more efficient than a dataset and have these capabilities.
boyd5
Participant
1033 Points
226 Posts
Re: WORM, NHibernate and reviews of any other ORMappers
Sep 19, 2005 08:33 PM|LINK
All I can say is that I've really never encountered anything that I needed done that LLBLGen didn't do, and I'm working in a 300 table framework with over a million lines of code. I've never had a performance issue or found a bug in Frans' framework. I have tables with millions of rows, hundreds of user controls, etc... and I simply couldn't be happier with it. The documentation is good, the support is even better, and it's completely OO from the top down.
Anyway, I'm sure WORM is good, as well as XPO, Versant and the like, but I just had to throw in my $.02.
Cheers,
-A
Systems Architect
fregas
Member
406 Points
96 Posts
Re: WORM, NHibernate and reviews of any other ORMappers
Sep 19, 2005 09:37 PM|LINK
Yes, me and Frans went round for round on that bug, and you're right its pretty old. I haven't looked at the newest version so maybe you can tell me if it has improved in these areas:
- Its pretty complex. The objects inherit from some "uber object" in his framework and often have hundreds of members to sift thru. Many methods/properties it creates for you have default names like __GetSomething(). Not sure why, that might be something weird with our crappy database.
- Its not "completely OO from the top down" since every table becomes an object . You can't map multiple tables to the same class or to an enum. It also doesn't support inheritance, although Frans says he's working on it. Its more like an API into your particular database, which isn't necessarily bad, but not good OO design.
Again, these were all problems with my particular version which is at least one year old.
FransBouma
Participant
1509 Points
312 Posts
Re: WORM, NHibernate and reviews of any other ORMappers
Sep 20, 2005 06:41 AM|LINK
If you have hundreds of relations and fields in an entity, yes, you get hunderds of members, though you can hide relations if you don't want them/need them. And complex? Doing advanced stuff is complex when you want full power over what you want to do, simply because all the options are offered to you. If you don't want that, you can use the simplified way of doing things, like Customer.Orders or what have you. Or generate your own wrapper methods, after all it contains a code generator engine.
Full inheritance, multi-entity same table, partly map target, polymorphic queries, new query system, etc. it's now in beta. Take a look, you're a licensee after all.
Oh, and I DO get tired about people calling my framework not 'good OO design'. First show me the criteria what's 'GOOD' OO design and second where my framework isn't using OO-style design. I mean it's full of patterns (have you spot them all, Fregas?), if that's not OO design, I don't know what is, but I'm sure you can tell me right away.
You really confuse entity in a relational model (abstract) with a class. If you don't think like that about a database, perfectly fine by me, but don't claim it's not 'good design'. It's 'different', it uses a different approach, more Chen-Yourdon-Halpin, less Fowler-Evans. Because there are different ways of doing data-access, and they are that much different from each other, based on what their core idea is, that you won't LIKE them all, but that doesn't mean the ones you don't LIKE are bad. Because that suggests a list of criteria which can be used to check if something is GOOD. If you think such a list exists, that's fine, but I'm sure you also read this: http://weblogs.asp.net/fbouma/archive/2004/10/09/240225.aspx
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)