in

 

Bytes of Wisdom

April 2007 - Posts

  • How to enlist ADO commands into an NHibernate transaction

    Adoption of NHibernate in a legacy environment can be daunting for a number of reasons.  Aside from the overhead of becoming proficient with the framework itself, developers are also faced with thousands of lines of working (it's assumed) code that is already conversing with the system's data store(s).  If complete migration to NHibernate is a prerequisite, then such systems would never make the move.  That being said, NHibernate does afford a way to make calls using the plain old ADO.Net API.  To be more precise, NHibernate allows users to enlist IDbCommands into NHibernate transactions.

    Personally, I've only used this feature to work around limitations of NHibernate (yes, although I believe NHibernate is the best thing since sliced bread, I do acknowledge its limitations...unlike <disparaging remark about other OS/Language/Methodology fanatics here>).  This feature was necessary for bulk delete operations…example follows:

    HQL in NHibernate is handy, but can get you in trouble.  Say you fire off an HQL query something like this:

    DELETE FROM User WHERE User.Clue = null   //not sure offhand of exact HQL syntax

    This would delete pretty much all your users, so if you have a few million clueless users in the system NHibernate will load the Users into the first level cache and then delete them.  I had a similar situation with a gig I was on not too long ago.  Caching the objects before deleting them would not only have taken a long time, it would have brought the server to its knees after the page file was used up.  I couldn’t skip the caching stage using NHibernate directly, but I could do something like this:

    ISession session = sessionFactory.GetSession();

               

    using(ITransaction transaction = session.BeginTransaction())

    {

                ...NHibernate stuff...

     

    IDbCommand command = new SqlCommand();

    command.Connection = session.Connection;

     

    transaction.Enlist(command);

     

    command.CommandText = "delete from User where clue is null";

    command.ExecuteNonQuery();

     

    ...more NHibernate stuff... 

    }

    In the using block I could do all sorts of NHibernate stuff yet still do my bulk delete without the caching overhead.  ADO commands used in this way are safely tucked into your current NHibernate Transaction context.

     This feature can be handy, but keep in mind that NHibernate remains unaware of state changes in the repository.  If I had a User collection in memory, I’d have to ignore the previous state after the delete and recall the collection based on my previous find criteria.  Stored Procedures could also be used this way, but Ayende blogged not to long ago about an alternative approach (I’m not sure off hand of the version of NHibernate that supports this).

     

  • Reflectionesque behavior in JavaScript

     

    Here's a little something in my continued investigation of JavaScript and its many wonders (man, that sounds strange!)...

    Okay, so for today's topic I'll look at some 'reflectionesque' behavior of JavaScript.  As many know, the class Object can be used as an associative array.  For instance:

    var myvar = new Object();
    myvar["value1"] = 42;
    assert(42, myvar["value1"]);  //would be true

    What many may not know is that objects will behave as associative array whether we like it or not.  Properties (fields or functions) that we add to an object's prototype will show up in a foreach construct if we iterate over an object.  This means that we could iterate over an object to see what's supported by its prototype/interface...sort of like reflection in .Net.  This can be helpful if we want to ensure that a property is supported by a given instance.  If it's not supported we can either inject the property/function at runtime so that the object doesn't cause any problems or we could bypass behavior that depends on the property.  Also, we could take disparate classes that support the same "interface" and apply polymorphic ideas.  In the example I show an attempt at getting the value of the 'name' property from three different classes.

    So that joe has something to play with, I've attached a script file called reflectionesque.js (zipped) that illustrates some of this.  I've also attached a screen shot that shows the output:

  • How'd he get that image up there?

    First off, I'm not much of a blogger so I'm not quite up to speed on the tips and trick of blogging.  I saw recently pretty pictures in one of Nellie's blogs and was instanly green with envy.  I wanted pictures too!  I tinkered around with the dashboard and blog editor for a while to no avail and finally out of desparation went back his blog entry.  I noticed WindowsLiveWriter in the URL and gave a quick search.  To say the least, I wish I was aware of the tool in the first place.  It facilitates creating blog entries easily with rich content.  Just as a simple example, I've included and image of one of the more lackluster constellations, Triangulum.........now I can include screen shots in discussions....yiiiihaaa!

    Posted Apr 06 2007, 06:30 PM by jlockwood with 1 comment(s)
    Filed under:
  • Term of the Day: Principle Of Least Surprise - Epilogue

    Okay, this is funny.  Little did I know that while writing “Term of the Day: Principle Of Least Surprise” I was entering the midst of just such a problem.

    The entry was written over a 2-3 hour span during compile waits on various tasks.  The last hour or so required debugging due to some really strange behavior.  I was working at the persistence layer on a data mapper responsible for persisting a complex object, adding support for new composite type that was a few levels down in the object model.  Everything looked right, but for some reason my tests kept failing.   I finally had to debug and intercept the SQL that was generated to see what was going on. 

    In the end I found the problem in a class that I wasn’t using directly that was providing the table name.  This is okay and common in our persistence framework.  What was not okay was that it specified the target database along with the table name, ignoring the connection information that was passed back to the data mapper.  The mapper was saving data to the correct database, but was retrieving it from another database.  I took out notwhatiwant.dbo from the const defining the table name and ran my tests again…some other tests on code that I wasn’t working on started to fail.  It didn’t take too long to clean everything up after that, but it was annoying.

    …lol, told you it wasn’t that uncommon

    P.S.  This is also a great argument for automated unit tests.  Resolving this was only quick because of over 5,000 automated unit tests that cover our code.  The tests that broke relate to the code base from a separate subsystem that I wasn’t even working on.  The need that prompted the addition of the database name to the tableName constant was addressed implicitly and in such a way that limited reuse.  Without the tests I probably would have ended up deploying a new bug.  We have great tests…that’s why we rock.

  • Term of the Day: Principle Of Least Surprise

    The principle of least surprise (AKA POLS) simply dictates that the interface to any given entity (method, for instance) should exhibit the bevahior that is least suprising to the user/programmer when there are conflicts or ambiguities between members of said interface.

    Example:  

    Let's say that the following are true...

    The following classes exist: Person, Address, People

    Person has the following attributes: SSN, Name, Address

    Person.SSN is used to identify Person instances

    People is a service that manages a set of Person objects

    People has to following methods: Add(Person):void, Get(SSN):Person

     

    Now let's say Joe programmer is using People to describe his blooming social life...

    Joe says:

    myFriend = new Person()

    myFriend.Name = "John"

    myFriend.SSN = 9999999999

    myFriend.Street = 10101 Victory Lane

    myFriend.City = San Mango

    myFriend.Address.State = Texas

    myFriend.Address.Zip = 93940

     

    Then he says:

    friends = new People() 

    friends.Add(myFriend)

    ...Now Joe's friends include a reference to John...

     

    Later Joe wants to write a letter to his friend, so he says:

    myFriend = friends.Get(999999999)

     

    If the People class adheres to the POLS, the address of myFriend should be that same as it was when he added it to friends. 

     

    Now here's a scenario that we see on occasion that will give Joe a nasty surprise.  The author of People decided that states are implied by zip codes.  Instead of bothering with the State value that's passed into People, it just stores the Zip code and gets the appropriate state based on the Zip repository that People's author went through so much trouble to create.  Unfortunately for Joe, when Joe entered the data he had been reminiscing on his own address in central California and he accidentally entered his own Zip.  Now Joe's lost contact with his only friend (poor Joe).

     

    As a result, myFriend looks like this:

    myFriend = new Person()

    myFriend.Name = "John"

    myFriend.SSN = 9999999999

    myFriend.Street = 10101 Victory Lane

    myFriend.City = San Mango

    myFriend.Address.State = California

    myFriend.Address.Zip = 93940

     

    Person's Add() looks like a setter and the Get() looks like a getter.  The interface does nothing to communicate that somewhere in between there is an implied mutation based on Zip.  This behavior would therefore violate the POLS.

     

    The example may seem a bit silly, but I'm sure we've all run into similar scenarios more than we'd like to admit.  This concept isn't new, just often ignored.

     

  • Another great JavaScript article

    Sorry all, I'll probably be over this JavaScript tear soon enough, but now that I've given the language another glance it has really caught my eye this time.  I can only explain my recent engagement with the language as a total re-discovery.  I've done some js OO before in the past, but looking at the language completely outside of a web development context has really helped my make a paradigm shift.  It's been kind of like when I was scripting in sed then discovered perl.

    Here's a really good js article: http://simon.incutio.com/slides/2006/etech/javascript/js-reintroduction-notes.html

     I couldn't agree more with the author, Simon Willison, when he says "...JavaScript has a reasonable claim to being the world's most misunderstood programming language." 

    Again, the author focuses on js from a web developer viewpoint, but I really think its potential is undervalued when it comes to using the language as a tool for system tools.  I just have to find a better way of managing script libraries...

  • C# -> JavaScript

    Joe had asked me recently if I thought I might want to make a tool that compiles C# into JavaScript.  I might want to futs with something like that, but fortunately I don't have to any time soon.  There's already a tool called script# that does just that.  This is a pet project of Nikhil Kothari and is definitely a must see.  I plan on messing with this in the near future with the goal of covering client code with nunit testing and rendering the business rules related client side scripts during the build.

     Here's a link to the project: http://projects.nikhilk.net/Projects/ScriptSharp.aspx

Copyright Los Techies 2007. All rights reserved.
Powered by Community Server (Commercial Edition), by Telligent Systems