The "ObjectRelationalImpedanceMismatch" is label for a set of problems encountered when using a relational database to store (the state of) objects from software written in an object-oriented programming language. Some feel that the ObjectRelationalImpedanceMismatchDoesNotExist on grounds that the problems are imaginary or inconsequential, or that they are problems with particular implementations rather than with mixing object and relational paradigms in general. But most agree that the consituent problems, real or imaginary, inconsequential or grave, are the following:
Contributors: CostinCozianu, RichardHenderson, RandyStafford
This might be considered a corollary of the dissonance between logical and physical models. -- MartinSpamer
This a thing very hard to define in one sentence, many people sustain that it exists, others think it does not, see also ObjectRelationalImpedanceMismatchDoesNotExist.
So. Let's try to define what exactly are the problems that lead us to believe we really deal with such a thing:
Let's try the following...
Added the often missed but IMHO significant issue of handling of null (but only as an empty page) -- AlanKnight
I'm in the middle of refactoring this page, but my limited time. my rather poor typing skills, and the fact that I often have to check my English spelling against a dictionary get in my way. I'll kindly ask a WikiGnome to please help me. Please leave the 'discussions about the discussion' as they are for now.
As I moved the discussion into separate pages, I tried to remove my forward-looking assertions.
ThankYou for all your input and I'll ask more for your patience, since it is no easy task to prove that ObjectRelationalImpedanceMismatch does not exist. I'll first ask for your permission into restructuring this page. Unless any contributor has objections I'll try to create several pages, each defining a single problem that is thought to belong to ObjectRelationalImpedanceMismatch.
For example RelationalDoesnotSupportInheritance? might be such a thing. Another could deal with performance of persisting an object oriented model in a relational database, I need to find a good title for that. Other will probably be dedicated to "empirical", practical evidence that relational and objectual don't match. And I bet we might gather at least 10 distinct problems.
Somebody already created a RelationalHostLanguageImpedanceMismatch, and a big ThankYou for him from my part.
It will help us a lot to do that, and I'd be grateful if you can help me do it. Unless I receive any objection I'll start doing it today.
I'll probably move into separate pages what I received on ObjectRelationalImpedanceMismatchDoesNotExist.
Sounds like a good idea. Please feel free to refactor. -- JeffGrigg
See WhyRandyStaffordThinksTheObjectRelationalImpedanceMismatchExists?
I look forward to your efforts in this regard. Of course, I have no idea what your proof strategy is, but if it involves showing a mechanical mapping exists between an object model and a relational model, then I think we need to better define the term support rather than impedance.
I realize that I need to disclose at least the general outline of what I intend to do. In general terms, I will argue that by their nature, the relational model and ObjectOrientedProgramming address very distinct domains, or in other words we need to have a SeparationOfConcerns.
Second, many of the problems purported to belong to the impedance mismatch are due to a lack of understanding of exactly what the relational model is, and how it is intended to work. Equally valid, many database researchers and even real life DBAs don't seem to worry too much about the daily problem outside data modeling, and most seem to reject the idea of object modeling. I find there is more of a PeopleImpedanceMismatch? between database people and OO people instead of having a true impedance mismatch. It is very often that the two sides of this artificial debate don't communicate and don't understand each other.
Third, I'll try to demonstrate problem by problem that fundamentally the relational model does not stay in the path of any OO programming effort.
Of course, there are people who've already approached this subject, from one side or another. I'll give them due credit and soon I'll post an ObjectRelationalImpedanceMismatchLinks.
I need to try it again is because I feel that I belong to both sides of the story, having programmed in OO languages for a number of years (that's my daily job), while I continuously pursued my intellectual interests in exploring database theories - I even have an "XXX certified DBA". So, I hope that being close to both sides I'll be able to break this kind of dialogue of the deafs.
ScottAmbler (http://www.ambysoft.com) is representative of ObjectPurism.
I'm all for real arguments, Costin. Please provide yours as to why the ObjectRelationalImpedanceMismatchDoesNotExist. I argue that it does exist, because I have experienced it, as documented above. Best regards, -- RandyStafford
Please help me in doing that. I have a daily job and WikiWritersDontGetPaid. You can start by refining your arguments. I can assert that what you've experienced can be as easily a combination of psychological impedance mismatch, bad design, violating relational principles. I don't have enough input from you to be sure about that.
As you were the one who made the assertion, Costin, I believe the burden of proof is on you to refine and substantiate your arguments. I can assure you that our design is not "bad" or "violating relational principles". Our schema is driven from a DomainModel that exhibits OnceAndOnlyOnce, and is therefore in ThirdNormalForm. We're using TopLink, which is widely acknowledged as the market-leading ObjectRelationalMapping layer, and which embodies many more man-years of expertise in that problem domain than you and I have together. We're on opposite sides of the issue. I'm not going to help you provide arguments as to why the ObjectRelationalImpedanceMismatchDoesNotExist, because I believe it does. Every time I have tried to use relational persistence to store a DomainModel, it has been a painful experience. And it has nothing to do with psychology; it has to do with empirical observations accumulated over many years and many projects. -- RandyStafford
I'll tackle each and every problem, including empirical practical evidence. Please let me know if there are more problems that you see when playing with relational databases, but I don't have enough time to do it all at once. We have to be careful in constructing our arguments, otherwise it would be a terrible waste of effort. Therefore the initial step is identifying all the problems.
Randy, again we're falling into a non-argument. I believe TopLink has no authority in this discussion, unless somebody from TopLink comes here with real arguments. As a matter of fact, some people on Wiki believe TopLink is not that good. If you really want to have a match of authorities, I can invoke database theorists and object oriented theorists that have years of activities extending to the very birth of the relational model and Object Orientation. This is NOT a way to go.
If you believe your design was right, and you can blame it on the relational model, please define each concrete problem you stumbled upon. Please also note that the third normal form is hardly enough, and is not automatically achieved by a DomainModel whatever that may be, unless you prove that you follow a specific method that demonstrably leads to third normal form. See for example SemanticBinaryModel which demonstrably leads to the fifth normal form. Please do identify each individual problem.
You believe that the ObjectRelationalImpedanceMismatchDoesNotExist, and yet you don't know what a DomainModel is. Answer me this question, Costin: why do you believe that the ObjectRelationalImpedanceMismatchDoesNotExist?
ObjectRelationalImpedanceMismatch does not exist per se, it is not an Entity if you like, or it is not a DomainObject. It is an association/collection/aggregation, you name it, of several distinct problems. At least on this assertion we'd have to agree, because it is self-evident.
You reiterate that it does not exist, and yet you define it as a collection of several distinct problems. With that I can agree. The ObjectRelationalImpedanceMismatch is (exists as a label for) a collection of problems that you encounter when using a relational database to store (the state of) objects in a program written with an ObjectOrientedProgrammingLanguage. -- RandyStafford
Well, do you see any other particular problem than the things I listed above? If only those are the problems that stay in an OO developer happiness, rest assured I can easily refute those. Otherwise stop bogging me, please, or do something constructive.
OK. I'll go off and constructively build systems with GemStone while awaiting your real arguments as to why the ObjectRelationalImpedanceMismatchDoesNotExist. I have no interest in WastingPeople, nor should you. Best regards, -- RandyStafford
Well, have it your way. Thanks for the input so far, but if you are able to identify any further individual problems please do so. I won't touch any argument until I'm pretty sure I've enumerated here all the complaints against the relational model and relational databases. I'm sorry if I'll make you wait. I don't think WastingPeople applies here; these are problems worth being debated, and usually there's very little tolerance for the opposite side's arguments on both sides of the dispute.
Aha! I've worked it out. The key difficulty is that Costin is saying that The ImpedanceMismatch need not exist. It can be designed out, and generally the relational model is pretty good at storing, querying and retrieving data. So wrap your objects around the thing that works. EJB's try to do this but they have an impedance mismatch in that they perform quite poorly under pressure. No wonder when you see how badly they map to the architecture of the underlying database. One response is to move the problem onto the database, thus the OODB. An equally valid alternative is to move the other way. Work with the grain, not against it, and the ObjectRelationalImpedanceMismatch need not exist. But it does :). -- RichardHenderson
Well, because you always draw conclusions, and guess what I am thinking, I'll clarify this for you. This mismatch exists only as a result of bad designs, and because of OO people ignoring most fundamental database principles, and on a higher level because of a psychological impedance mismatch. See WhyJavaIsntSmalltalk, for an example of this psychological barrier. Basically it says, the way I'm thinking is the right way, there are no alternatives way, and the way I'm thinking must apply to all the problems in the world, because it works for my small universe, so why wouldn't it work for the whole world?.
The fathers and grand fathers (KristenNygaard, BjarneStroustrup) of OO didn't invent OO languages in order to deal with large shared databanks, and basically OO technology successfully handles a whole domain outside what databases deal with. But when you want to force ALL OO concerns into the domain that is addressed by databases, you already make a big mistake, and you can't assert that it will work because OO is generally good.
Once you break this psychological barrier, you may buy a book on databases, study it carefully, consider the problem itself from many more angles, and choose the best solution. In particular, the relational model has no problems in dealing with many of the OO concerns like inheritance and polymorphism (once we defined the polymorphism). On the contrary, problems like RelationalHasNoObjectIdentity stem from people prejudices (they can't let go of the stupid identity) and/or from design errors, hence you can't assert an impedance mismatch. -- CostinCozianu
That would be a 'yes' then :). Are we matching impedances yet? -- RIH
Basically you can say that, yes. It need not exist, that means that whatever exists is not the result of the two models per se being somehow incompatible, but because of many people's misunderstanding of the issues involved. From a theoretical standpoint, it means the impedance does not exist; from a practical standpoint, you can affirm it exists in many cases.
Costin, I detect a trend of aggressive commentary. Anyways, not getting into too much but consider this: if removing the interfacing problem requires you to change your design and modeling on the OO side, then that is exactly equivalent to building in a transformer, in the impedance analogue. Just because you can design a circuit to interface with a particular impedance, doesn't mean that this isn't a constraint! So the impedance mismatch still exists, it has just been hidden. Note, it may be that this is the *best* approach, but pretending a problem doesn't exist because you designed around it is not intellectually honest.
No; if you do a good sound design in the first place, you'll have no problem using it with relational databases, including not modifying your object model in any way. In particular, if your design is not based on the object identity principle (which by the way is a good principle, but for another class of problems) and your design will be based on logical identity of objects (values equality), you'll have no problem at all.
The problem is not to be worked around, but to be addressed correctly, and I'm not talking about the object/relational problem, I'm talking about each specific domain problem that an application is trying to address (providing that the problem involves large shared data banks so that we are in database domain). -- CostinCozianu
I noticed three things about working with objects and relational DBs.
Most of the argument I have seen on these pages is about which is better. But that is not what the page title is about, and what I am commenting on.
Anytime you have two languages that facilitate different forms of expression, there will be an impedance mismatch between them. Which is "better" for any purpose does not remove the mismatch.
Our project was basic business invoicing/advertising system in Smalltalk with relational DB. Our persistence guys made a really nice mapper layer. The OO person and the DB person sat together and decided how to cross the technology-expression bridge: how to map each many-to-many and each inheritance. It was all done with tables, and autogenerated cute and efficient queries and all kinds of cool things.
At the end of that project, I concluded that I didn't care about the mismatch very much, because it can be reduced to a harmless form of technology-expression matching. It seems our mapper designers were better than most, because I rarely meet anyone who had such an easy mapping as we did.
This is a very good point. Having solved this issue for several projects, I don't have the concern that others seem to have about this issue. It seems that a key success factor in solving this problem is to have very experienced relational database people working together with very experienced OO people. Let each person do what they do best. I consider myself very experienced in relational database but only somewhat experienced in OO. I found the problem to be much less difficult than people I've talked to who are more OO experienced than database experienced. I would never say there isn't an issue, only that the cost can be minimized with the right people. -- MikeCorum
I thought I knew something about this problem (see http://members.aol.com/acockburn/papers/newooers.htm and http://members.aol.com/acockburn/papers/endgame/endgame.htm for two articles I wrote about it). Then Randy came along and gave his examples in ObjectRelationalMappingCostsTimeAndMoney, which changed my views somewhat :-(. His involved deep inheritance hierarchies, which we didn't have. After reading his stories, I conceded that sometimes the technology-expression mismatch will be much harder to conceal - occasionally to the point of becoming a real problem. -- AlistairCockburn
Hi Alistair, thanks for jumping in. Actually, my experience has been that the primary characteristic of a domain model which makes it painful to O/R map is not so much the depth of the inheritance hierarchies (although that does have an effect), but the depth of the aggregation hierarchies in the instantiated domain model. The pain comes from having to O/R map a big structure of thousands of related objects into memory all at once in order to operate on it (display it in a diagram editor, reason over it to answer an availability query, etc.). The alternative is to not map it, and move the operation's logic into PL/SQL (if possible). But in so doing you give up the advantages of an object-oriented programming language for coding the logic of the operation. -- RandyStafford
Thanks for an observation that was new to me (the aggregation problem). It makes sense (in hindsight). -- AlistairCockburn
Randy, such a deep agregation hierarchy or inheritance hierarchy is usually not the domain of large shared data banks that is, the domain of relational databases. It typically suggest a CAD/CAM application. Did you meet a situation where you had a large shared databank, that is huge amounts of data, and high concurrency and transactional requirements. Even if I can see some cases where in an OLTP type of application you have chained relations that may involve thousands of entities departing from a root entity (let's say a customer entity), I have a hard time figuring out how all of these are involved in a single transactional use-case. And how that use case can be a significant part of the OLTP workload (as opposed to more sophisticated processes that are sometimes run in batch modes). -- CostinCozianu
Well, the Ascent Logic software was kind of an interesting mix. On the one hand, it was definitely like CAD/CAM - it was an upper-CASE tool generally falling into the "design automation" industry. It was a meta-modeling application used to hold and relate the kind of information you deal with on BIG system development projects (not just software systems) - like source textual requirements information, functional and behavioral information, architecture and design information, etc. It had a big meta-model (information schema) which was the domain model, lots of browsers and inspectors, lots of diagram editors, a simulator, a report generator, etc. It was written in Smalltalk. But on the other hand, it did IMHO deal with "large shared data banks". It was used on VERY big projects - e.g., Space Station Freedom, Strategic Defense Initiative, the FAA's Air Traffic Control Modernization project, Motorola's Iridium project, etc. These projects typically had development organizations of hundreds of engineers of different disciplines, from several different geographically-distributed companies, many of whom needed to interact with the requirements and design database. These databases could easily grow to contain hundreds of thousands of objects or more. It was typically the case that aggregation structures of thousands of these objects at a time needed to be in memory to edit a diagram, run a simulation, generate a report, etc.
The SynXis? hotel reservation system was more of a traditional OLTP application. It definitely had high concurrency and transactional characteristics. And it did deal with reasonably large databanks - multiple hotel chains with multiple hotels each, where each hotel has hundreds of rooms and thousands of reservations, not to mention guest profiles, etc. The thing that caused deep aggregation hierarchies in that application was the way we were describing hotel room "inventory" - by attributes instead of by "type code". As a result of that approach, we had to reason over large aggregation structures to answer availability queries or book reservations. Think about what is involved in answering the following availability query: "is there any luxury accommodation available for any week in the month of March, in or near Puerto Vallarta, Mexico, that has an ocean view, two bedrooms and a kitchen, and is not on the first floor, for less than $300 per night?" Keep in mind that hotels have very complex pricing policies, and we could't hard-code the attribute descriptors because each hotel wanted to define its own.
Randy, the term "large shared data banks" refers to Edgar F. Codd's seminal work on relational databases called "A relational model of data for large shared data banks" [Communications of the ACM 13 (6), 377-387]. It refers specifically to storage of data, not diagrams. So the determination of whether data storage constitutes a "large shared data bank" is based not on size or the fact it is shared - it has to store data and be large in size and shared. A database that stores diagrams would not be a large share data bank in the EF Codd sense.
See http://www.acm.org/classics/nov95/s1p1.html "This paper is concerned with the application of elementary relation theory to systems which provide shared access to large banks of formatted data." -- C. Barton
But "Data" does not preclude images or vector info. During Dr. Codd's paper's time the issue of multimedia was less of a concern anyhow because it was usually too expensive to put on hard-drives.
Again, relational theory was focused on "large banks of formatted data" - i.e. textual data. So yes, Data in the EF Codd sense does preclude images and vector info. Relational database theory was developed to handle large banks of formatted data. This is what Costin Cozianu is talking about when he states "such a deep agregation hierarchy or inheritance hierarchy is usually not the domain of large shared data banks that is, the domain of relational databases." If you are trying to store something other than formatted data in a relational database, then perhaps the problem is not the "object-relational impedence mismatch" but rather the fact that the wrong data storage technology was selected in the first place.
Perhaps we should explore specific examples. Further, I am not sure of your definition of "formatted". See MultiParadigmDatabase for a relational-influenced DB suggestion with a dynamic twist to handle "variable" records, and even be entity-less if wanted. We have dynamic languages, so why not dynamic relational also? If you find Java's static typing too rigid then switch to Python. Same with DB's. Just the small issue of implementation is left in the way. :-)
There is a common example of large shared data banks with wicked aggregation hierarchies: Case Management Systems such as are used for taxation, law enforcement, and client relationship management. These systems involve intricate relationships (the E-R diagrams show just about every entity related to just about every other entity). The subject matter also cries out for objects.
A common characteristic of these things is that they are usually a beast to modify or extend. The one exception I know of is CPIC, the Canadian Police Information Center system. Still in operation today, it was designed thirty years ago and implemented with Cobol and assembler on an ISAM file system, but the design is recognizably OO software on an OO database - done the hard way. They built the solution to fit the problem.
On the other hand, Revenue Canada's case management system, built on a SQL database, is so intractable that, other than adding to a code table, it takes an act of Parliament to make the least change. They built the solution to fit some other problem that was more familiar to them.
Case management has a few fun bits: Anything can have one or more attachments and one or more comments. The attachments can be interesting; the attachments can have attachments; in a border-crossing system, keeping track of people's passports means keeping track of each new passport a person gets, new content whenever they cross the border, inserted forms, and related travel documents. What drives DBAs crazy is the variability - something new every time some country decides to add to the stuff a traveller carries. We invented MIME types to handle the same problem for stuff travelling across the internet, but there's no SQL equivalent to MIME.
It is possible to recruit a SQL database for the task of supporting case management in a flexible, maintainable way - but you have to design the database last, after the OO software is designed, and use some non-traditional structures. I've never been able to convince a development team to do it that way.
-- MarcThibault
The above is rather more slogans than analysis. It is premised on the assertion that OO handles "intricate relationships" better than relational databases. This is in fact one of the elements of ObjectRelationalPsychologicalMismatch, and if this was true I'd have received better solutions sooner to the ManyToManyChallenge. What do you think relational stands for?
Not my premise. Maybe somebody else's. Where I stand is that both are equally capable - they just handle data differently in the process of turning it into information. The designers are the problem. The examples were meant to point out that it isn't the technology that gets in your way.
I haven't responded to the ManyToManyChallenge - didn't know it was there - I will. Step one is recognizing that Many-to-Many isn't a design parameter - it's a convenient shortcut. The real world works with one-to-many: bags, boxes, railcars, shopping lists, etc. Keeping track of a company's shareholders is a separate concern from keeping track of which companies' shares an individual holds. If the application calls for both, many-to-many is the game in SQL. In OO, each company has a list of shareholders and, if called for, each shareholder has a list of companies. These are separate lists.
Most people who claim they see such a case cannot abstract it into a problem form that can be communicated and shared for peer review. So in the end, it can never rule out that such anecdotes relate inability of some engineers (DBA included) to effectively model and operate within the relational model. -- CostinCozianu
I didn't say they couldn't - only that they don't want to. There is an elegant object-oriented approach to persistence that makes it easy to use the full power of a SQL database. Persistent collections with no iterators is one way - there are probably others. -- mt
If they don't want to, maybe they are right. The account you give about the said "OO" approach sounds like marketing brochure - you could start a web page and describe the design pattern. I cannot make anything of "persistent collection with no iterators" and I know quite a few O/R frameworks. And I can assure you that it is absolutely impossible for any O/R approach to use the "full power", any OO API is just not as expressive in some areas. Maybe when C# 3 will have LINQ (language integrated queries) it'll be time to reconsider. -- Costin
An iterator over the members of a class is just a cursor, a very low-level service that reduces the class to the status of a DBAM (or EJB). Well-designed objects provide complete services and eliminate the "this object here fiddling with the data in that object there". Iterator-free Persistent Collections are classes whose instances are selected collections of persistent objects (not even a little bit like an EJB). Collection methods provide set-at-a-time services. Because the collection has a high-level interface, it knows more about what's going on and can more easily optimize DB accesses. Also, the DB design can be tuned specifically to the needs of the collection class instead of an imagined worst-case ad-hoc reporting requirement. Optimized OO access to an optimized SQL DB - who could ask for more?
Stealing from APL, make the collection class a subclass of the item class (Mice subclass of Mouse). That way, a collection can be returned from an item method (Composite pattern). Collection methods override item methods by doing the item method to each member of the collection and returning the result as a collection. -- mt
"We explained the impedance mismatch problem, and claimed that the solution to that problem was not to bring the database language down to the record-at-a-time level, but rather to raise the programming language to the set-at-a-time level. Indeed, the fact that OO languages are so procedural is a severe disadvantage of those languages; in particular, it seriously undermines optimizability."
From C. J. Date, "An Introduction to Database Systems, 6th Ed.", page 681
Set-at-a-time is a Persistent Collection with no iterators. -- mt
I have read quite a bit about this issue, and have been on the look out for solutions/ideas on how to best deal with the issue at hand. Saddly, I find that his page has evolved into a theoretical/no-facts **fight** rather than a clear definition on the problem (or perceived problem) and ideas of how to cope/solve it.
The issues that I have heard (read, argued, etc.) called 'impedance mismatch' don't have much to do with whether the OR database was designed well or not. There is no questioning that some designs accentuate the issue a bit more than others. The basic issue remains:
Company (cX) has a database (DB). cX decides that it needs to have software! DB is quite complicated. It has LOTS of tables, which are all related in one way or another. JOINs abound!
Developers of X (dX) are given the task to write a large piece of software that uses DB. They usually take one or a combination of the following approaches:
1. From the 'CODE' itself they create SQL queries and use them. They are also capable of calling Stored procedures for some business logic, while other business logic is done in the 'CODE'.
2. dX decide to create objects/libraries that map 1-1 to a table. Here it doesn't matter if they are using an OO language or a purely procedural language; this seems to be an approach taken by many (probably) less enlightened dX.
3. dX become really dreamy and code up a frame work that allows them to create Business Objects. Since the data for this objects does not all reside in ONE table, the objects have the duty of joining the data. This implies that the model of the data is many times duplicated (ack!! bad!! DoNotRepeatYourself?) once in the database, and once in the mapping framework.
Developers then find themselves realizing that data is a nasty little bugger. You need it sometimes in datasets, while other times it just makes more sense to get it in logical units (Business Objects). You seem to pay a penalty any time you decide to build your framework to work one way or the other. The frameworks soon became beasts (mosters, if you will) of their own, that required more time to maintain than the DB or the 'CODE' itself.
This is, in the simplest terms, impedance mismatch. Database design hasn't enter the picture, neither has [my-favorite] programming language either. Client code needs to access data. Table is 'split' up in multiple tables.
I'm more than willing to learn what I must. I believe me there is a WHOLE lot to learn. I hope we can start to bring this conversation a bit closer to the trenches, instead of the you-are-and-idiot, phylosophy-A-beats-phylo-B talk. These are real issues that developers face every day, and it is sad to say that most don't use (many times because they don't have a clue about) best practices. How could they? Look at ADO.NET (what managers would love us using) and tell me if that is a best-practice approach to using data.
I've said enough, hope to elicit some useful thoughts from the gurus. -- DanTart?
I am not sure if anything new is introduced here, to be frank. The "translation layer" becomes large and messy because two very different philosophies are being forced to work togeter. I doubt the philosophies are reconcilable. It would be easier to get Lisp fans to use Java. My recommended solution is to dump OO where it appears to conflict with relational, but others really like OO for reasons that escape me. -- top
So, uh, are there any good books on this (these?) topic(s)? (My particular interest is that of the O-O (Java) developer who wants to learn more about the d/b side of things.) -- JohnLusk, 15 Nov 2004
Learn about relational theory first. Unfortunately, I cannot recommend any books that are relatively easy-to-digest. The writers of existing text have been in academia for too long. And, know SQL.
[The problem isn't that the writers of existing texts have been in "academia" too long, it's that readers of existing texts are often unwilling to learn the theoretical foundations that are needed for an accurate and complete understanding of relational theory. The difference between a database practitioner who understands the theory vs one who does not is like the difference between having your car repaired by an educated mechanical engineer vs a shade-tree hack. Both can perform simple tasks like changing tires or spark plugs, but the former has a distinct advantage when confronted with challenging problems.]
See Also: CategoryDatabase (discussion), RelationalObjectIdentity, ObjectRelationalPsychologicalMismatch, TablesAndObjectsAreTooDifferent, RelationalOoImpedanceMismatchIsCausedByClasses, RelationalWithSideEffects