O/R Mappers: To Attribute or Xml ?

I learned a lot while I was creating my own O/R Mapper, so I thought a few lessons learned would be good to blog. I'll be adding a few of these over the next couple of days, so stay tuned for some other interesting observations.

First, I think Microsoft has made the right decision to use xml mapping files instead of attributes in code. Note that I'm not commenting on the complexity of theirs, although I suppose it may be necessary for performance. What I'm getting at is that attributes just are NOT the best approach for things that are external to the code! Attributes make perfect sense for things like unit tests, design-time only features, and aspects like logging too. But persistence mappings are very external to the code, like table and field names, and they do often change.

Why should I have to recompile my business objects just because someone changed the table or field names again? I can also easily imagine some cases where applications must work with existing databases as well -- then what? And what if I want to support multiple databases but I must make some schema changes for performance reasons? Finally, I've even seen people say they want to change their schemas on the fly -- that's weird, but what if? Only external xml mappings allow you to handle these.

So far I've stayed away from some of the other reasons that attributes are not the best choice for persistence, but why not list them anyhow just to stir up the kettle. My pet peeve -- persistence attributes make my business objects very ugly for no important development reason. Speaking of development, I can imagine that many shops will have different people creating the business objects from the people that will be worried about the mappings. Finally, if you use a GUI helper to create the mappings then it seems obvious they should go in a separate file.

I can't think of even one reason to prefer attributes other than the argument that external files get messed up. I know attributes are cool in .NET, especially since its one thing that Java does not have, but I do not think that they make much sense for object-relational mapping.

What do you think? I chose xml mappings, not attributes.

13 Comments

  • ::persistence attributes make my business

    ::objects very ugly for no important

    ::development reason



    Reality check:



    is this ugly?



    using Builder.Cms.ComponentModel;



    using EntityBroker.Foundation.Nodes;



    namespace Builder.Cms {



    /// <summary>

    /// This subnode of ContentNode represents a simple (not to say stupid) file. File nodes are the

    /// "we dont care" content nodes - whatever is stored there is just forwarded to the database and,

    /// when rendering, just returned to the user. This is necessary because there wil lbe a lot of stuff

    /// just to store in the content node hierarchy (like a file archive).

    /// </summary>

    public class File : Builder.Cms.EntityObjectSet.FileStub {



    protected override void EntityObjectPostCreate() {

    base.EntityObjectPostCreate ();

    Particle p = (Particle) EntityManager.Create (typeof(Particle));

    this.Particle = p;

    }



    }

    }



    You just see a dozen mapped fields, some relations, actually plus a lot of logic in a base class.



    But wait - where are the attributes?



    Oh, see the inherited stub :-) And all generated.



    Again, just a reality check :-)

  • I've been working on a little Attribute based ORM in my spare time - probably not anything I'm going to release to the public, but i've used it in a prototype application, and found it to be quite useful.



    However, your arguments against the attribute based ORMs are quite solid... i may have to reconsider how I go about this... not to mention that mine currently has nothing to do with persistence, but is purely an access layer.

  • My system, like ObjectSpaces, uses an external XML configuration to create the mappings between the fields in the underlying data store and the class fields.

  • While I prefer external XML mapping the advantage I can see with mapping attributes to the class is when you add/remove fields your maintenace occurs in one location instead of two. But of course as the tools mature its GUI will end up managing that for you.

  • I opt for mappings generated in code from a definition. This is far more optimal than xml (objects are constructed directly with the right code/data) and both are generated so it's no loss that the persistence info is inside code, you use the definition to change the mappings anyway.



    So I don't think it matters much what you pick, as long as the format you pick is NOT the source of your mappings: it always should be generated from a definition a user can design in a tool

  • Oh and this: "Why should I have to recompile my business objects just because someone changed the table or field names again?" is not an argument.



    Table names do not change frequently. If they do, go online, go to the first jobsite you can think of, opt for the first job available and leave the project! :)

  • I'm not really up on the O/R stuff, can someone post an enlightening link about how attributes (System.Attribute based?) are used for mapping. A lot of reflection?



    When I think "map" think of a piece of paper, a document that I can use to get from one place to annother.



    I could esily envision using an xml file to generate source code that then must be compiled (being too lazy to write so much similar code, I already do this:).

  • Why should you have to specify the mappings at all? It seems to me you should only have to concern yourself with what should be persisted, not how the O/R mapper does it. I understand this is not always possible though, for example if you have to work with an existing database.

  • I have never seen an instance where tables had to be created at runtime except when I worked on a SQL DMO web app.



    There's no need to create tables at runtime except in those cases where you are actively administering the database.



    Having an app create tables on the fly is:

    1) a security risk

    2) poor database design



    In addition it usually indicates a poor understanding on the part of the developer about the problem domain and the type of information going into the application.

  • ::I just got an email today from someone that

    ::has some of those odd requirements to create

    ::tables at runtime.



    Hm.



    Tell him to get something like "SQL for people who have no clue about how to deal with databases".



    I have not found this requirement in any valid way in the last 10 years. And I am sure I will not find it until I retire.



    Oh, I have seen applications like this.



    But basically thwy were like - well - one example:



    * Invoice management. One table for every invoice, one for every invoice ' InvoiceDetails (makes tables per invoice). Comment: so that the tables do not get too large.



    Well. Some poeple think a db is as stupid as they are in handling data - they can not remember more than 10 invoice details, so the db will surely also have problems.



    Show me a valid example and I will change :-)

  • I totally agree in principle that this type of requirement sounds ludicrous. But that doesn't really change the other arguments that I found. Also, should it really be our business to tell our customers what they can or cannot do, especially when its so easy to change our approach to enable them to do what they want? Here's a reality check -- you enable your customers if you want to sell them something.

  • ::Here's a reality check -- you enable your

    ::customers if you want to sell them something.



    Here is another one: I dont help them raping a database server :-)



    No, not me.

  • I agree poor requests shouldn't dictate my architecture, but when there are two approaches and one satisfies those additional requests (and in my opinion other issues) without sacrificing the real issues . . .

Comments have been disabled for this content.