Unknown alias name: 'default'

by Rob Kitson in


I just upgraded RVM to 1.0.13 and suddenly started getting the following error message in my terminal  every time I executed a command.

Unknown alias name: 'default'

Turns out, RVM wants you to set your default version of ruby. Running the following command appears to have fixed the problem for me.

rvm use ruby-1.9.2 --default


Not as lazy as I thought...

by Rob Kitson


I just ran into an unexpected lazy loading issue using NHibernate, so I thought I'd document it here.

Essentially, the domain has a Parent class (called Parent) which has a collection of Child classes (a property named Children which is an IList). The NHibernate mapping is setup as a lazy-loaded collection, which is very performant when the collection of children is small, which you'd typically find when doing unit testing or integration testing. The bottleneck starts showing up as soon as parent.Children.Add(newChild) is called and the number of children is sufficiently large enough to cause a delay while lazily loading the children.

The simple fix is to setup a bi-directional association between the objects and make sure the cascade goes in both directions.  Once that's done, change 'parent.Children.Add(child);' to 'child.Parent = parent;' and flush the changes to the DB. Now, this change will not help very much if you are going to do queries against the Child collection before persisting the changes to the database (since the child won't be in the collection until a query is done to pull the collection out), but it will keep you from pulling all the Children from the database and into memory in order to simply add a new item to the collection. The next time the parent is loaded and the 'Children' property is referenced it will lazily load all the children, including the new record.

To sum it up: If you have a collection that's lazily loaded, and the 'Child' has a reference to the 'Parent', you're better of setting the 'Parent' of the 'Child' than adding the 'Child' to a collection in the 'Parent' since NHibernate is going to load the other 'Child' objects of the 'Parent' before it performs the Add().


Learning the conventions

by Rob Kitson


In effort to sharpen the saw a bit I started playing around with Ruby on Rails last week.  I quickly realized a couple things about Convention over Configuration:

  1. How much busy work is avoided by using Conventions, which is probably why certain projects in the .Net and .Net OSS communities are rushing to add Conventions.
  2. One should probably know what the Conventions are before diving into a project that uses them.

So I did a quick google to get a list of the Conventions and found this post on Ruby on Rails Naming Conventions.

Here's the summary of the post, just in case it ever get's taken down.

Model Naming Convention

Table: orders
Class: Order
File: /app/models/order.rb
Primary Key: id
Foreign Key: customer_id
Link Tables: items_orders

Controller Naming Convention

Class: OrdersController
File: /app/controllers/orders_controller.rb
Layout: /app/layouts/orders.html.erb

View Naming Convention

Helper: /app/helpers/orders_helper.rb
Helper Module: OrdersHelper
Views: /app/views/orders/… (list.html.erb for example)

Tests Naming Convention

Unit: /test/unit/order_test.rb
Functional: /test/functional/orders_controller_test.rb
Fixtures: /test/fixtures/orders.yml




Where'd my email go?

by Rob Kitson


I've been a big fan of Google Apps since I setup my first domain (this one), almost 2 years ago. It's dead simple to setup, you get most of the features of a GMail account with the benefit of having your own domain name, they recently added Microsoft Exchange compatibility, and it's free (if you can squeeze all your emails in ~7GB).

We recently migrated one of our domains from Exchange to Google Apps and encountered an unexpected problem.  When forwarding email from an account on one Google App domain (the secondary account) to an account on another (the primary account) the emails would automatically get marked as read and then skip the inbox in the primary account, effectively never showing up on my radar. Not very convenient if you're like me and you live in your inbox.

As a last resort I could have setup my primary account to poll the secondary account for new emails via POP3, but I figured I'd try one last thing before implementing that hack.  I logged my secondary account and turned off the forwarding in the "Forwarding and POP/IMAP" tab, then setup a new filter that would forward email that showed up for "*@secondarydomain.com" to "me@primarydomain.com". Problem solved.


Another reason why Flash won't work on the iPhone/iPad

by Rob Kitson


Listening to Monday's SDR episode, there was a segment about an experienced Flash developer who recently posted a few reason as to why Flash doesn't belong on a touch-based device.  The article mentions the 'hover issue' and the 'right-click issue' but I think it missed another valid issue; scrolling the page vs. being able to drag elements around.  The problem is that the browser's default behavior for 'touch and drag' is scrolling, not dragging.

This problem is not isolated to Flash apps. I tried to use a web app yesterday which uses jQuery to power the user experience. It allows users to drag DOM elements around the page and it simply didn't work; Every time I tried to drag an element the whole browser would scroll in the direction I was dragging.


Using FluentNHibernate and Rhino-Commons – Part 2

by Rob Kitson


In Using FluentNHibernate and Rhino-Commons – Part 1 I shared how to leverage INHibernateInitializationAware in order to get your FluentNHibernate configuration into the SessionFactory in your UnitOfWork.  In part 2 I’m going to show you how to do the same thing using the latest changes (r328) to FNH.

I was looking at the new FluentNHibernate site earlier and noticed (in the Wiki) that they added a new class called ‘Fluently’ to help assemble the NHibernate configuration.  The first thing that I noticed is that I needed to find a way to get the mappings into the Configuration that I am passing into the FluentNHibernateInitializationAwareConfigurator that I’ve been using.

public class FluentNHibernateInitializationAwareConfigurator : INHibernateInitializationAware  
{  
    public void BeforeInitialization(){}  
    public void Configured(Configuration cfg)  
    {
        Fluently.Configure().Mappings(m =>
        {
            m.FluentMappings.AddFromAssemblyOf()
                .AlterConventions(convention =>
                    {
                        convention.GetForeignKeyName = (prop => prop.Name + "Id");
                        convention.GetForeignKeyNameOfParent = (prop => prop.Name + "Id");
                    }
                );
            m.Apply(cfg);
        });
    }  
    public void Initialized(Configuration cfg, ISessionFactory sessionFactory){}
}

This is actually a simplified version of what I am using, which is actually currently leveraging the AutoMapping features against entities in two different assemblies (although the example above is using FluentMapping).  I will probably create my own FluentMappings once the domain gels a bit more so that I can have more granular control over the database structure. 

However I decide to create my mappings (Fluent, Auto, classic HBM files, or a combination) I’ll still be able to use the Fluently class to apply them to the configuration as long as I remember to call Apply() and pass in the NHibernate Configuration that is passed into the Configured() method in my FluentNHibernateInitializationAwareConfigurator.

 


Using FluentNHibernate and Rhino-Commons

by Rob Kitson


Since it's inception, I have been a big fan of FluentNHibernate.  I am also a big fan of Ayende's Rhino-Tools.
A project that I've been working on recently has given me the opportunity to trying to leverage both.  I wanted to use DatabaseTextFixtureBase from Rhino.Commons.ForTesting with FluentNHibernate to work on my integration tests.  The problem that I kept coming up against was the fact that FluentNHibernate works it's magic on the NHibernate configuration in the PersistenceModel class, and getting your hands on the NHibernate configuration once you call DatabaseTestFixtureBase.InitializeNHibernateAndIoC() Rhino.Commons works it's magic privately and you no longer have access to the NHibernate config (or not in a way that I could see).


As it turns out, my last assumption was wrong.  I asked the Rhino-TOols list how I might go about accomplishing this integration and in as simple a response as I could have hoped, I got a 1-word word response from Ayende, "INHibernateInitializationAware" (and honestly, I'm glad that that was all the help that I got.)  It was a simple hint but it made me go back and look at everything all over again and I saw a bunch of stuff that I hadn't looked at before. And now I'm chuckling a bit over his post from this morning about Static vs. Dynamic Dependencies because when I was looking at the implementations of INHibernateInitializationAware that are in Rhino.Commons I didn't find one that helped me understand what it's purpose was (in his words about another class, "there's not a lot happening there").


As it turns out If you register an INHibernateInitializationAware service with the container, it will be picked up by the NHibernateUnitOfWorkTestContext when it calls CreatConfigs().  So that's what I did.

public class FluentNHibernateInitializationAwareConfigurator : INHibernateInitializationAware
{
    public void BeforeInitialization(){}

    public void Configured(Configuration cfg)
    {
        var persistenceModel = new PersistenceModel
                                   {
                                       Conventions =
                                       {
                                           GetForeignKeyName = (prop => prop.Name + "Id"),
                                           GetForeignKeyNameOfParent = (prop => prop.Name + "Id")
                                       }
                                   };
        persistenceModel.addMappingsFromAssembly(typeof(ClickMap).Assembly);
        persistenceModel.Configure(cfg);
    }

    public void Initialized(Configuration cfg, ISessionFactory sessionFactory){}
}